Deploy SaaS kit to Railway
Learn how to deploy your SaaS application to Railway.
Railway is a modern cloud platform that makes it easy to deploy full-stack applications with databases and storage. This guide walks you through deploying your application to Railway.
Flexible Hosting Options
While this guide uses Railway's integrated Postgres and S3-compatible storage for simplicity, you can use external providers for your database (Neon, PlanetScale, Supabase, AWS RDS) and storage (AWS S3, Cloudflare R2, DigitalOcean Spaces). Railway makes it easy to connect to external services via environment variables. However, Railway's all-in-one approach provides an excellent developer experience with minimal configuration.
Prerequisites
Before you begin, ensure you have:
- A Railway account
- Your application code pushed to a GitHub repository
- Your billing provider credentials (Stripe, Polar)
Architecture Overview
Your Railway deployment will consist of three services:
- Web Service - Your Next.js application
- Postgres Database - Railway's managed PostgreSQL instance (if you use a different database, you can use the external provider's database)
- Storage Bucket - S3-compatible object storage for file uploads (if you use a different storage provider, you can use the external provider's storage)
Step 1: Create a New Railway Project
- Log in to your Railway dashboard
- Click New Project
- Select Deploy from GitHub repo
- Connect your GitHub account if not already connected
- Select your repository
Railway will automatically detect your Next.js application and begin the initial deployment setup.
Note: the initial deployment will fail because we need to configure the environment variables. It's okay, we will do that in the next steps.
Step 2: Add a PostgreSQL Database
- In your project canvas, click the + New button
- Select Database → Add PostgreSQL
- Railway will provision a PostgreSQL instance with SSL enabled
The database will appear in your architecture view with a postgres-volume for persistent storage.
We will need the variable DATABASE_URL to connect to the database. You can find it in the Credentials tab of the Postgres service.
Step 3: Add S3-Compatible Storage
Railway provides S3-compatible storage buckets for file uploads:
- Click the + New button in your project canvas
- Select Storage Bucket
- Choose your preferred region (e.g., US West - California, USA)
Region Selection
The bucket's region cannot be changed after creation. Choose a region close to your web service for optimal performance.
After creation, click on the Storage Bucket service to view:
- Credentials tab: Contains your S3 access credentials
- Settings tab: Shows the bucket region and management options
Step 4: Configure Environment Variables
Click on your web service and navigate to the Variables tab. You need to configure the following environment variables:
Database Configuration
DATABASE_URL=${{Postgres.DATABASE_URL}}Railway automatically injects the DATABASE_URL when you reference it using the ${{Postgres.DATABASE_URL}} syntax. This ensures your web service always has the correct connection string.
Site Configuration
Please copy the exposes URL of your web service that you find in the web service and set it as the NEXT_PUBLIC_SITE_URL environment variable.
NEXT_PUBLIC_SITE_URL=https://your-domain.up.railway.appReplace with your actual Railway domain or custom domain.
Storage Configuration
Configure the S3-compatible storage variables from your Storage Bucket credentials:
STORAGE_BASE_URL=https://your-bucket.railway.storageSTORAGE_S3_ACCESS_KEY_ID=your-access-keySTORAGE_S3_SECRET_ACCESS_KEY=your-secret-keySTORAGE_S3_BUCKET=your-bucket-nameSTORAGE_S3_REGION=us-west-1Storage Credentials
You can find these credentials in the Storage Bucket service under the Credentials tab.
Billing Provider Configuration
Set your billing provider and its credentials:
NEXT_PUBLIC_BILLING_PROVIDER=stripeThe NEXT_PUBLIC_BILLING_PROVIDER can be one of: stripe or polar.
For Stripe:
STRIPE_SECRET_KEY=sk_live_...STRIPE_WEBHOOK_SECRET=whsec_...For Polar:
NEXT_PUBLIC_BILLING_PROVIDER=polarPOLAR_ACCESS_TOKEN=your-polar-access-tokenComplete Environment Variables List
Here's a summary of all the minumum required environment variables that you need to set:
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string (use Railway reference) |
NEXT_PUBLIC_SITE_URL | Your production URL |
NEXT_PUBLIC_BILLING_PROVIDER | stripe or polar |
STORAGE_BASE_URL | S3 storage endpoint URL |
STORAGE_S3_ACCESS_KEY_ID | S3 access key |
STORAGE_S3_SECRET_ACCESS_KEY | S3 secret key |
STORAGE_S3_BUCKET | S3 bucket name |
STORAGE_S3_REGION | S3 bucket region |
Plus your billing provider-specific variables as listed above.
Other Environment Variables
Don't Forget Dev Tools Variables
If you configured additional settings using the Dev Tools during development (OAuth providers, email, feature flags, etc.), make sure to add those environment variables to your Railway project as well. Refer to the Environment Setup guide for the complete list.
Step 5: Run Database Migrations
After setting up your environment variables, run Drizzle migrations to create your database schema.
Copy the DATABASE_URL from Railway's Postgres Variables tab and run:
read -s DATABASE_URL && export DATABASE_URL && pnpm --filter "@kit/database" drizzle:migrateThis prompts you to paste the URL without displaying it in your terminal history.
Deployment Workflow
Once configured, Railway automatically deploys your application when you push to your connected branch:
- Push changes to GitHub
- Railway detects the push and starts a new deployment
- The build runs with your configured settings
- If successful, the new version goes live
Monitoring and Logs
Railway provides built-in monitoring:
- Deployments tab: View deployment history and status
- Logs tab: Real-time application logs
- Metrics tab: CPU, memory, and network usage
- Observability: Application performance monitoring
Troubleshooting
Database Connection Issues
If your application can't connect to the database:
- Verify
DATABASE_URLis correctly set using Railway's variable reference syntax - Check that your Postgres service is Online
- Ensure you're using the private networking URL for internal connections
Build Failures
If your build fails:
- Check the build logs in the Deployments tab
- Verify all required environment variables are set
- Ensure your
package.jsonscripts are correct - For monorepos, verify the root directory setting
Storage Issues
If file uploads aren't working:
- Verify all
STORAGE_S3_*variables are correctly set - Check that the Storage Bucket service is active
- Ensure your application code uses the correct S3 client configuration
Production Checklist
Before going live, ensure:
- [ ] All environment variables are set
- [ ] Database migrations have been run
- [ ] Billing webhooks are configured
- [ ] Custom domain is set up (if using)
- [ ] SSL is enabled (automatic with Railway)
- [ ] Application health checks are passing
- [ ] Monitoring and alerts are configured