Railway Deployment
Deploy your SaaS to Railway with CI/CD. Push to deploy.
Prerequisites
- Railway account (https://railway.app - sign in with GitHub)
- Railway CLI:
npm install -g @railway/cli
Quick Setup (CLI)
bash
# 1. Login
railway login
# 2. Create project
railway init -n my-saas -w "Your Workspace Name"
# 3. Add services
railway add -d postgres
railway add -d redis
railway add -s app
# 4. Link to app service
railway link -p my-saas -s app
# 5. Set environment variables
railway variables --set "SECRET_KEY=$(openssl rand -hex 32)"
railway variables --set "SECURITY_PASSWORD_SALT=$(openssl rand -hex 32)"
railway variables --set "SECURITY_TOTP_SECRETS=$(openssl rand -hex 32)"
railway variables --set "FLASK_APP=run.py"
railway variables --set "FLASK_DEBUG=0"
# 6. Link database URLs (Railway auto-resolves these)
railway variables --set 'SQLALCHEMY_DATABASE_URI=${{Postgres.DATABASE_URL}}'
railway variables --set 'REDIS_SESSION=${{Redis.REDIS_URL}}'
railway variables --set 'CELERY_BROKER_URL=${{Redis.REDIS_URL}}'
railway variables --set 'CELERY_RESULT_BACKEND=${{Redis.REDIS_URL}}'
# 7. Get project token for GitHub Actions
# Go to: Railway Dashboard → Project Settings → Tokens → CreateGitHub Actions Setup
- Copy your Railway project token
- Go to GitHub repo → Settings → Secrets and variables → Actions
- Create new secret:
RAILWAY_TOKEN= your token
Important: If updating an existing secret, delete it first and recreate. Updating sometimes doesn't work.
Push to railway-deploy branch (or master after testing) to trigger deployment.
Verify Deployment
bash
# Check status
railway status
# View logs
railway logs --tail 50
# Get public URL
railway domainPost-Deployment: Create Admin User
bash
railway run flask create-db
railway run flask installFile Structure
Your repo needs these files (already included):
railway.json - Build config:
json
{
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"startCommand": "gunicorn run:app",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}.github/workflows/deploy-railway.yml - CI/CD workflow:
yaml
name: Deploy to Railway
on:
workflow_dispatch:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
container: ghcr.io/railwayapp/cli:latest
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
steps:
- uses: actions/checkout@v4
- run: railway up --service app --detachRedis Databases
Railway Redis supports multiple logical databases. Append DB number to URL:
${{Redis.REDIS_URL}}/1 # DB 1 for sessions
${{Redis.REDIS_URL}}/2 # DB 2 for Celery broker
${{Redis.REDIS_URL}}/3 # DB 3 for Celery resultsTroubleshooting
403 Forbidden on deploy: Delete and recreate RAILWAY_TOKEN secret in GitHub.
Database connection timeout: Ensure Postgres service is deployed and running.
Health check failed: Check logs with railway logs. Usually a startup error.
Cost (Hobby Plan)
~$5/month total:
- App: ~$2-3/month
- PostgreSQL: ~$1-2/month
- Redis: ~$0.50/month
CLI Reference
bash
railway login # Authenticate
railway init -n NAME # Create project
railway add -d postgres # Add database
railway add -s NAME # Add empty service
railway link -p PROJECT -s SERVICE # Link to service
railway variables # View variables
railway variables --set "KEY=value" # Set variable
railway up # Deploy
railway logs # View logs
railway domain # Get/create public URL
railway run COMMAND # Run command in service