Railway Deployment
Railway provides a simple platform for deploying Rivet Engine with automatic scaling and managed infrastructure.
Video Tutorial
PostgreSQL is the recommended backend for multi-node self-hosted deployments today, but it remains experimental. For a production-ready single-node Rivet deployment, use the file system backend (RocksDB-based). Enterprise teams can contact enterprise support about FoundationDB for the most scalable production-ready deployment.
Quick Deploy
Choose the template that best fits your needs:
You can also use the Rivet Railway template as a starting point for your application.
After deploying either template, you can find the RIVET__AUTH__ADMIN_TOKEN under the Variables tab in the Railway dashboard. This token is required to access the Rivet Inspector.
Manual Deployment
Prerequisites
- Railway account
- Railway CLI (optional)
Step 1: Create New Project
# Using Railway CLI
railway init
# Or create via dashboard
# https://railway.app/new
Step 2: Add Services
Deploy PostgreSQL Database
- Click “New Service” → “Database” → “PostgreSQL”
- Railway automatically provisions and configures PostgreSQL
- Note the connection string from the service variables
Deploy Rivet Engine
- Click “New Service” → “Docker Image”
- Set image:
rivetdev/engine:latest - Configure environment variables:
RIVET__POSTGRES__URL=${{Postgres.DATABASE_URL}}
- Configure graceful shutdown (see Graceful Shutdown below)
Step 3: Deploy Your Application
Follow the Railway Quick Start guide to deploy your repository:
- Connect your GitHub account to Railway
- Select your repository containing your Rivet application
- Railway will automatically detect and deploy your application
- Configure environment variables for your application:
RIVET_ENDPOINT=${{Rivet.RAILWAY_PRIVATE_DOMAIN}}- Points to the Rivet Engine service’s private domain
Graceful Shutdown
By default, Railway kills the old deploy 0 seconds after sending SIGTERM (see Railway’s docs), so in-flight requests are dropped and state flushes can be interrupted on every deploy. Rivet ships with a SIGTERM handler that drains cleanly, but it only gets to run if Railway is configured to give it time.
Configure the following under Settings → Deploy on your service:
- Draining seconds — the grace window between
SIGTERMandSIGKILL. This is how long Rivet has to finish in-flight work and flush state. See Railway’s deployment teardown docs.
Set draining seconds in the dashboard, via drainingSeconds in config-as-code, or via the RAILWAY_DEPLOYMENT_DRAINING_SECONDS service variable. A reasonable value is 60 seconds.
If your start command is a wrapper process (for example npm start, yarn start, pnpm start, or a shell script), the wrapper becomes PID 1 and swallows the signal — your app never drains and Railway force-kills it at the end of the window.
- Invoke your binary directly as the start command (for example
node dist/index.js, notnpm start). - Or run
dumb-init/tinias PID 1 in your Dockerfile so signals forward to your process.
Next Steps
- Review the Production Checklist before going live
- See Configuration for all options