This guide walks you through deploying the API to Railway and the client to Vercel, with GitHub Actions running CI on every PR and CD on every push to main.
- A Railway account (free tier works)
- A Vercel account (free tier works)
- The Rostid repo pushed to GitHub
- Go to railway.app → New Project → Deploy from GitHub repo
- Select the
rostidrepository - Railway will detect
railway.tomland useserver/Dockerfileautomatically
- In the Railway project dashboard, click + New → Database → Add PostgreSQL
- Railway automatically injects
DATABASE_URLinto your service's environment
In the Railway service settings → Variables, add:
| Variable | Value |
|---|---|
NODE_ENV |
production |
PORT |
4000 |
JWT_ACCESS_SECRET |
Run: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" |
JWT_REFRESH_SECRET |
Run the same command again for a different value |
JWT_ACCESS_EXPIRES_IN |
15m |
JWT_REFRESH_EXPIRES_IN |
7d |
COOKIE_SECRET |
Run: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
CLIENT_URL |
Your Vercel URL (set after step 2, e.g. https://rostid.vercel.app) |
STRIPE_SECRET_KEY |
From Stripe Dashboard |
STRIPE_WEBHOOK_SECRET |
From Stripe → Webhooks (after adding endpoint) |
RESEND_API_KEY |
From Resend Dashboard |
RESEND_FROM_EMAIL |
A verified sender address in Resend |
After the first deploy, open the Railway service's Shell tab and run:
npx prisma migrate deploy
npx prisma db seedIn Stripe Dashboard → Add endpoint:
- Endpoint URL:
https://your-app.railway.app/api/webhooks/stripe - Events to listen:
checkout.session.completed - Copy the Signing secret → paste as
STRIPE_WEBHOOK_SECRETin Railway
- Go to vercel.com → Add New Project → import your
rostidGitHub repo - Vercel detects
vercel.jsonautomatically — no framework override needed
In Vercel project settings → Environment Variables:
| Variable | Value |
|---|---|
VITE_API_URL |
Your Railway API URL (e.g. https://rostid-api.railway.app) |
Click Deploy. Vercel builds client/ and serves the SPA with proper routing.
In Railway → Account Settings → Tokens → create a new token → copy it.
# Install Vercel CLI
npm install -g vercel
# Link to your project (run from repo root)
vercel link
# This creates .vercel/project.json with orgId and projectId
cat .vercel/project.jsonGet your personal token from vercel.com/account/tokens.
Go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
| Secret name | Value |
|---|---|
RAILWAY_TOKEN |
Your Railway token |
VERCEL_TOKEN |
Your Vercel personal token |
VERCEL_ORG_ID |
orgId from .vercel/project.json |
VERCEL_PROJECT_ID |
projectId from .vercel/project.json |
From now on, every push to main triggers an automatic deploy to both Railway and Vercel.
# API health check
curl https://your-api.railway.app/api/health
# Expected: {"status":"ok","timestamp":"..."}
# Client
open https://your-app.vercel.app| Service | Platform | URL pattern |
|---|---|---|
| API | Railway | https://rostid-production.up.railway.app |
| Client | Vercel | https://rostid.vercel.app |
| Database | Railway PostgreSQL | Managed, internal |
| Payments | Stripe | Test/live keys |
| Resend | API key |