1
Create a Railway account and project
- Go to railway.app and sign up
- Click New Project
- Select Empty Project
- Name the project (e.g.,
Acme Production)
2
Add PostgreSQL
- In your project, click New → Database → Add PostgreSQL
- Railway creates a PostgreSQL instance and adds it to your project
- Click on the PostgreSQL service → Variables tab
- Copy the
DATABASE_URLvalue — you will need it shortly
3
Add Redis
- Click New → Database → Add Redis
- Click on the Redis service → Variables tab
- Copy the
REDIS_URLvalue
4
Deploy the API
- Click New → GitHub Repo
- Connect your GitHub account and select your repository
- Railway detects the
Dockerfilein the project root and uses it - Before the first deploy, go to the service’s Variables tab
- Add all required environment variables (see Environment Variables):
- Click Deploy — Railway builds the Docker image and starts the container
5
Run migrations
- Install the Railway CLI:
npm install -g @railway/cli - Log in:
railway login - Link your project:
railway link - Run migrations against the production database:
6
Run the database seeder
--seed-only flag runs seeders and exits without starting the HTTP server.7
Deploy the frontend
- In your Railway project, click New → GitHub Repo again
- Select the same repository, but this time set the Root Directory to
frontend/ - Add the frontend environment variable:
- Railway detects
package.jsonand uses the Vite build command (npm run build) - Set the Start Command to
npx serve -s dist -l 3000
8
Configure custom domains
- For the API service: Settings → Domains → Generate Domain or Add Custom Domain
- Add a CNAME record in your DNS pointing
api.yourdomain.comto the Railway-provided domain - Repeat for the frontend service at
yourdomain.comorapp.yourdomain.com - Railway provisions SSL automatically via Let’s Encrypt
9
Register the Stripe webhook
Now that you have a production API URL:
- Stripe Dashboard → Developers → Webhooks → Add endpoint
- URL:
https://api.yourdomain.com/api/v1/webhooks/stripe - Select all five required events (checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed, invoice.payment_succeeded)
- Copy the signing secret → update
STRIPE_WEBHOOK_SECRETin Railway
10
Verify
- Open
https://yourdomain.com— the login page should load - Log in with admin credentials (email set via
--AdminEmailat scaffold time, passwordAdmin123!) - Change the admin password immediately
- Test a complete checkout with a real payment method
- Confirm the Stripe webhook delivered successfully in the Stripe Dashboard