Railway Deployment Guide
Railway Deployment Guide
Deploy CensusChat to Production in 15 Minutes
Goal: Deploy CensusChat to Railway.app for external access with custom domain and production-grade infrastructure.
Timeline: 15-20 minutes
Cost: ~$20/month (backend + databases)
Result: Publicly accessible at censuschat.up.railway.app or custom domain
Prerequisites
✅ GitHub Repository: Code pushed to GitHub (public or private) ✅ Census API Key: From https://api.census.gov/data/key_signup.html ✅ Railway Account: Sign up at https://railway.com (GitHub OAuth recommended) ✅ Local Testing Complete: System working locally with production data
Quick Start (15 Minutes)
Step 1: Create Railway Project (2 minutes)
# 1. Visit Railway
open https://railway.com
# 2. Sign up with GitHub (recommended)
# - Click "Login with GitHub"
# - Authorize Railway access
# 3. Create new project
# - Click "New Project"
# - Select "Deploy from GitHub repo"
# - Choose: hollandkevint/CensusChat
Step 2: Deploy Backend Service (3 minutes)
In Railway Dashboard:
- Select Backend Directory
- Root Directory:
/backend - Build Command:
npm install && npm run build - Start Command:
npm start
- Root Directory:
- Configure Service Settings
Service Name: censuschat-backend Port: 3001 Health Check Path: /health - Deploy
- Click “Deploy”
- Wait for build to complete (~2 minutes)
Step 3: Add PostgreSQL Database (1 minute)
# In Railway Dashboard:
# 1. Click "+ New Service"
# 2. Select "Database" → "PostgreSQL"
# 3. Railway auto-generates credentials
# PostgreSQL will be automatically connected to your backend
Auto-generated Environment Variables:
DATABASE_URL- Full connection stringPGHOST,PGPORT,PGUSER,PGPASSWORD,PGDATABASE
Step 4: Add Redis Cache (1 minute)
# In Railway Dashboard:
# 1. Click "+ New Service"
# 2. Select "Database" → "Redis"
# 3. Railway auto-generates credentials
# Redis will be automatically connected to your backend
Auto-generated Environment Variables:
REDIS_URL- Full connection stringREDIS_HOST,REDIS_PORT
Step 5: Configure Environment Variables (3 minutes)
In Backend Service Settings → Variables:
# Census API
CENSUS_API_KEY=your_census_api_key_here
# JWT Secret (generate new for production)
JWT_SECRET=your_production_jwt_secret_here
# Node Environment
NODE_ENV=production
# CORS (add your frontend domain later)
ALLOWED_ORIGINS=https://censuschat.vercel.app,https://censuschat.com
# Optional: Anthropic for MCP
ANTHROPIC_API_KEY=your_anthropic_key_here
Generate Secure JWT Secret:
# Run locally to generate
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
Step 6: Deploy Frontend to Vercel (3 minutes)
# 1. Install Vercel CLI
npm i -g vercel
# 2. Deploy from frontend directory
cd frontend
vercel
# 3. Follow prompts:
# - Link to existing project? No
# - Project name? censuschat
# - Framework preset? Next.js
# - Root directory? ./
Configure Frontend Environment:
In Vercel Dashboard → Settings → Environment Variables:
NEXT_PUBLIC_API_URL=https://censuschat-backend.up.railway.app
Step 7: Connect Services (2 minutes)
Update Backend CORS:
In Railway → Backend Service → Variables:
ALLOWED_ORIGINS=https://censuschat.vercel.app,https://censuschat.com
Redeploy Backend:
- Click “Deploy” in Railway dashboard
- Wait for deployment (~1 minute)
Step 8: Verify Deployment (2 minutes)
# Test Backend Health
curl https://censuschat-backend.up.railway.app/health
# Should return: {"status":"healthy","timestamp":"..."}
# Test Frontend
open https://censuschat.vercel.app
# Test Query
# In frontend, ask: "Show me all counties in Texas"
# Should return real Census data
Custom Domain Setup (Optional)
Backend Domain (Railway)
In Railway → Backend Service → Settings → Domains:
- Add Custom Domain
api.censuschat.com - Configure DNS (in your domain provider)
Type: CNAME Name: api Value: censuschat-backend.up.railway.app TTL: 3600 - Wait for SSL (~5 minutes)
- Railway auto-provisions SSL certificate
- Status will change to “Active”
Frontend Domain (Vercel)
In Vercel → Project Settings → Domains:
- Add Domain
censuschat.com www.censuschat.com - Configure DNS
Type: A Name: @ Value: 76.76.21.21 Type: CNAME Name: www Value: cname.vercel-dns.com - Update Backend CORS
ALLOWED_ORIGINS=https://censuschat.com,https://www.censuschat.com
Database Migration & Data Loading
Method 1: Load ACS Data Directly on Railway
# 1. Connect to Railway PostgreSQL locally
railway link
railway run npm run load-acs-data
# This will:
# - Connect to Railway's PostgreSQL
# - Load 3,143 counties from Census API
# - Populate production database
Method 2: Upload DuckDB File
# 1. Create DuckDB with production data locally
cd backend
npm run load-acs-data
# 2. Railway uses ephemeral filesystem
# Better to use PostgreSQL for persistence
# 3. Convert DuckDB → PostgreSQL
npm run migrate:duckdb-to-postgres
Method 3: Automated Data Refresh
Create Railway Cron Job:
In Railway → New Service → Cron:
Schedule: 0 2 1 * * # 2am on 1st of month
Command: npm run load-acs-data
Monitoring & Logs
Railway Dashboard
View Logs:
# In Railway Dashboard:
# 1. Select Backend Service
# 2. Click "Deployments" tab
# 3. View real-time logs
# Or use Railway CLI:
railway logs --service censuschat-backend
Monitor Performance:
- CPU usage
- Memory usage
- Request count
- Response times
Set Alerts:
- Settings → Notifications
- Configure Slack/Email alerts for:
- High CPU (>80%)
- Memory spikes
- Deployment failures
- Health check failures
Health Checks
Backend Health Endpoint:
// Already configured in backend/src/index.ts
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
services: {
postgres: 'connected',
redis: 'connected',
duckdb: 'available'
}
});
});
Railway Health Check Config:
Path: /health
Interval: 30s
Timeout: 10s
Success Threshold: 2
Scaling Configuration
Vertical Scaling (Automatic)
Railway auto-scales resources based on usage:
- Starter: 512MB RAM, 1 vCPU
- Scale up: Up to 32GB RAM, 8 vCPU
- Billing: Pay only for what you use
Horizontal Scaling (Manual)
Add Replicas:
# In Railway Dashboard:
# 1. Backend Service → Settings → Replicas
# 2. Set: 2-3 replicas for high availability
# 3. Railway auto-load balances requests
Configure Auto-Sleep (Development Only):
# Settings → Auto Sleep
# Enabled: Save costs when inactive
# Wake time: <1 second on first request
Security Configuration
Environment Secrets
Never commit to GitHub:
- ✅ All secrets in Railway Variables
- ✅ Use
.env.exampletemplates only - ✅ Rotate secrets quarterly
Production Secrets Checklist:
JWT_SECRET- Unique 64-char hexCENSUS_API_KEY- From Census BureauANTHROPIC_API_KEY- From Anthropic ConsoleDATABASE_URL- Railway auto-generatedREDIS_URL- Railway auto-generated
CORS Configuration
Restrict Origins:
// backend/src/index.ts
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [
'https://censuschat.com',
'https://www.censuschat.com',
'https://censuschat.vercel.app'
];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true
}));
Rate Limiting
Add to Backend:
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: 'Too many requests, please try again later'
});
app.use('/api/', limiter);
Cost Estimation
Railway Costs
Monthly Pricing:
Backend Service (Starter): $5/month
PostgreSQL Database: $5/month
Redis Cache: $5/month
Bandwidth (10GB included): $0
Additional Bandwidth: $0.10/GB
Estimated Total: $15/month
Vercel Costs (Frontend):
Hobby Plan (Free): $0/month
- 100GB bandwidth
- 100 serverless functions
- SSL included
Pro Plan (if needed): $20/month
- 1TB bandwidth
- Advanced analytics
Total Monthly Cost:
Development: $15/month (Railway + Vercel Free)
Production: $35/month (Railway + Vercel Pro)
Deployment Checklist
Pre-Deployment
- Code pushed to GitHub
- All tests passing locally
- Production data loaded and tested
- Environment variables documented
- CORS origins defined
- Health checks implemented
Railway Setup
- Project created and linked to GitHub
- Backend service deployed
- PostgreSQL database added
- Redis cache added
- Environment variables configured
- Health checks enabled
Frontend Setup
- Deployed to Vercel
- API URL configured
- Custom domain added (optional)
- SSL certificate active
Post-Deployment
- Backend health check passing
- Frontend loads successfully
- Test queries returning data
- Excel export working
- Logs show no errors
- Monitoring alerts configured
External Access
- Share URL with beta testers
- Document known limitations
- Set up feedback collection
- Monitor usage patterns
Troubleshooting
Build Fails
Symptom: Railway build errors
Solutions:
# Check build logs in Railway dashboard
# Common issues:
# 1. Missing dependencies
npm install --production=false
# 2. TypeScript compilation errors
npm run build
# 3. Node version mismatch
# Add to package.json:
"engines": {
"node": ">=20.0.0"
}
Database Connection Issues
Symptom: “Cannot connect to database”
Solutions:
# 1. Verify environment variables
# In Railway → Variables → Check DATABASE_URL exists
# 2. Test connection locally
railway run node -e "require('./src/db').testConnection()"
# 3. Check PostgreSQL service status
# In Railway → PostgreSQL service → Status should be "Active"
CORS Errors
Symptom: “Blocked by CORS policy”
Solutions:
# 1. Verify ALLOWED_ORIGINS includes frontend URL
# Railway → Backend → Variables
# 2. Check frontend is using correct API URL
# Vercel → Environment Variables → NEXT_PUBLIC_API_URL
# 3. Ensure credentials: true in both places
Slow Query Performance
Symptom: Queries taking >2 seconds
Solutions:
# 1. Check database indexes
# Railway → PostgreSQL → Run:
CREATE INDEX idx_state ON county_data(state);
CREATE INDEX idx_county ON county_data(county);
# 2. Monitor resource usage
# Railway → Backend → Metrics tab
# 3. Scale up if needed
# Settings → Increase RAM/CPU limits
External Access Guide
Sharing with Beta Testers
Create Access Instructions:
# CensusChat Beta Access
Welcome to CensusChat! Here's how to get started:
## Access the Application
🔗 **URL**: https://censuschat.vercel.app
🔐 **No login required** (beta testing)
## Try These Queries
1. "Show me all counties in Texas"
2. "Medicare eligible seniors in Florida"
3. "Counties with median income over $75,000"
4. "Compare poverty rates in California and New York"
## Features to Test
✅ Natural language queries
✅ Excel export (click "Export" button)
✅ Response time (<2 seconds)
✅ Data accuracy
## Provide Feedback
📧 Email: kevin@kevintholland.com
📋 Issues: https://github.com/hollandkevint/CensusChat/issues
Thank you for helping improve CensusChat!
Public Launch Checklist
Before Public Release:
- Privacy policy published
- Terms of service published
- Rate limiting configured
- Analytics implemented
- Error monitoring (Sentry)
- Backup strategy defined
- Support email configured
- Documentation complete
Rollback Procedure
If deployment fails:
# 1. In Railway Dashboard → Deployments
# 2. Find last working deployment
# 3. Click "..." → "Rollback to this deployment"
# 4. Confirm rollback
# Rollback completes in ~30 seconds
Or via CLI:
railway rollback
Next Steps After Deployment
- Monitor First 24 Hours
- Watch logs for errors
- Track response times
- Monitor resource usage
- Collect Beta Feedback
- Send access instructions to 10 beta users
- Create feedback form
- Schedule follow-up interviews
- Optimize Performance
- Add database indexes based on query patterns
- Implement caching for common queries
- Consider CDN for frontend assets
- Plan for Scale
- Set up auto-scaling rules
- Configure backup automation
- Implement monitoring alerts
Support Resources
- Railway Docs: https://docs.railway.com
- Vercel Docs: https://vercel.com/docs
- CensusChat Docs:
docs/index.md - Technical Support: Create GitHub issue
- Email Support: kevin@kevintholland.com
Quick Reference Commands
# Link to Railway project
railway link
# View logs
railway logs
# Run commands on Railway environment
railway run npm run load-acs-data
# Deploy latest changes
git push origin main # Auto-deploys to Railway & Vercel
# SSH into Railway container (debugging)
railway shell
# Check service status
railway status
Deployment Status: Ready to deploy ✅ Estimated Time: 15-20 minutes Next Action: Create Railway account and deploy backend