Deployment Guide

Vercel, Railway, and VPS with Nginx and SSL

Dev Only
ServiceProviderWhy
Frontend (Next.js)VercelZero-config Next.js hosting. Auto SSL. Deploy on git push.
Backend (Node.js API)Railway or RenderOne-click Node.js deploy. Easy environment variables.
PostgreSQLNeon or SupabaseServerless Postgres. Generous free tier. Auto-backups.
RedisUpstashServerless Redis. Pay-per-request. Free tier available.
ImagesCloudinaryAlready configured in the app. No change needed.
DNS & SSLCloudflareFree SSL certificates. DDoS protection. Easy DNS.

Option A — Deploy Frontend to Vercel

The easiest approach for the Next.js frontend.

1

Create a Vercel account

Go to vercel.com and log in (or create an account).

2

Import your repository

Click Add New Project and import your pos-frontend repository from GitHub.

3

Deploy

Vercel auto-detects Next.js. Click Deploy — it builds and deploys automatically.

4

Set environment variables

After deployment, go to Settings › Environment Variables and add all variables from your .env.local file. Set NEXT_PUBLIC_API_URL to your production backend URL.

5

Redeploy

Click Redeploy to apply the environment changes. Your frontend is live at your-project.vercel.app (or your custom domain).

Option B — Deploy Backend to Railway

1

Create a Railway account

Go to railway.app and create an account.

2

Deploy from GitHub

Click New Project › Deploy from GitHub repo and select pos-backend.

3

Configure variables

In the Variables tab, add every key from your .env file.

4

Set networking

In Settings › Networking, add a custom domain or use the auto-generated railway.app URL.

5

Set build commands

Set the build and start commands:

Option C — Deploy to a VPS

For full control — deploy to an Ubuntu VPS with Nginx and PM2.

1 — Initial Server Setup

bash

2 — Clone, Configure, and Start

bash

3 — Nginx Reverse Proxy

/etc/nginx/sites-available/pos-backend
bash

4 — Free SSL with Certbot

bash

Production .env Checklist

VariableProduction Notes
NODE_ENV RequiredMust be exactly: production
DATABASE_URL RequiredUse production Neon/Supabase URL with ?sslmode=require
REDIS_URL RequiredUse Upstash production URL — starts with rediss://
JWT_ACCESS_SECRET RequiredGenerate a fresh 64-char secret. Never reuse the dev value.
JWT_REFRESH_SECRET RequiredGenerate another fresh 64-char secret. Must differ from access secret.
FRONTEND_URL RequiredYour real frontend URL: https://pos.yourdomain.com
CLOUDINARY_*Same credentials as development — Cloudinary is environment-agnostic.
Warning

Never reuse development JWT secrets in production. Regenerate them with the crypto command from the Backend Configuration section.