Skip to content

🚂 Railway

📋 Overview

Railway is our primary cloud deployment platform, providing a seamless experience for deploying, scaling, and managing the LIPAIX platform. It offers automatic deployments, environment management, and built-in monitoring.

🏗️ Platform Architecture

Service Structure

Railway organizes our platform into services:

                    LIPAIX Platform
                ┌─────────────────────────┐
                │                         │
    ┌───────────┼─── Web App (Next.js)   │
    │           │                         │
    │           ├─── Discord Bot         │
    │           │                         │
    │           ├─── Database (PostgreSQL)│
    │           │                         │
    │           ├─── Cache (Redis)       │
    │           │                         │
    │           └─── Documentation       │
    │                         │
    │           External Services        │
    │           ┌─────────────────────────┐
    │           │                         │
    │           ├─── Sentry (Monitoring) │
    │           ├─── Discord API         │
    │           └─── Email Service       │
    │                         │
    └───────────┼─────────────────────────┘


            Production
            Environment

Service Connections:

  • Web App ↔ Database, Cache, Sentry
  • Discord Bot ↔ Database, Discord API, Sentry
  • All services ↔ Railway infrastructure

Service Configuration

Each service has its own configuration:

toml
# railway.toml
[build]
builder = "nixpacks"

[deploy]
startCommand = "pnpm run start"
healthcheckPath = "/api/health"
healthcheckTimeout = 300

[env]
NODE_ENV = "production"

🚀 Deployment Process

⚠️ IMPORTANT: Deployment is MANUAL, not automatic!

Manual Deployment via GitHub Actions

Railway deployments are triggered manually through our GitHub Actions workflow:

  1. 👤 Manual Trigger - Developer runs deployment workflow
  2. 🎯 Environment Selection - Choose staging or production
  3. 🔄 Branch Update - Update deploy/web or deploy/staging/web
  4. 🚂 Railway Sync - Railway detects branch changes
  5. 📦 Build & Deploy - Service rebuilds and deploys

Key Points

  • ❌ Merging to main does NOT deploy automatically
  • ✅ Deployment requires manual action via GitHub Actions
  • 🔧 Separate deployment branches for staging and production
  • 📋 Manual approval for each deployment

Railway automatically detects changes to our deployment branches, but we control when those branches are updated.

Build Process

bash
# Railway automatically runs:
pnpm install          # Install dependencies
pnpm run build        # Build the application
pnpm run start        # Start the service

Environment Variables

Railway manages environment variables securely:

bash
# Database Configuration
DATABASE_URL=postgresql://user:pass@host:port/db
REDIS_URL=redis://host:port

# Application Configuration
NODE_ENV=production
JWT_SECRET=your-secret-key
SENTRY_DSN=your-sentry-dsn

# External Services
DISCORD_BOT_TOKEN=your-bot-token
PAYLOAD_SECRET=your-payload-secret

🔧 Service Configuration

Web Application

toml
# apps/web/railway.toml
[build]
builder = "nixpacks"

[deploy]
startCommand = "pnpm run start"
healthcheckPath = "/api/health"
healthcheckTimeout = 300

[env]
NODE_ENV = "production"
PORT = "3000"

Discord Bot

toml
# apps/discord-bot/railway.toml
[build]
builder = "nixpacks"

[deploy]
startCommand = "pnpm run start"
healthcheckPath = "/health"
healthcheckTimeout = 300

[env]
NODE_ENV = "production"
PORT = "3001"

Database Service

toml
# Database configuration
[env]
POSTGRES_DB = "lipaix_production"
POSTGRES_USER = "lipaix_user"
POSTGRES_PASSWORD = "secure_password"

📊 Monitoring & Observability

Built-in Monitoring

Railway provides:

  • Resource Usage - CPU, memory, disk utilization
  • Request Metrics - Response times, error rates
  • Logs - Structured application logs
  • Health Checks - Service availability monitoring

Custom Metrics

We implement custom metrics:

typescript
// Health check endpoint
app.get('/api/health', async (req, res) => {
  try {
    // Check database connectivity
    await db.query('SELECT 1')
    
    // Check external services
    await checkDiscordAPI()
    
    res.json({
      status: 'healthy',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      version: process.env.npm_package_version
    })
  } catch (error) {
    res.status(503).json({
      status: 'unhealthy',
      error: error.message,
      timestamp: new Date().toISOString()
    })
  }
})

🔒 Security & Access Control

Environment Isolation

  • Production - Live production environment
  • Staging - Pre-production testing environment
  • Development - Development and testing environment

Secrets Management

Railway securely manages sensitive data:

bash
# Never commit secrets to version control
# Use Railway's environment variable management

# Database credentials
DATABASE_URL=postgresql://...

# API keys
DISCORD_BOT_TOKEN=...
PAYLOAD_SECRET=...

# JWT secrets
JWT_SECRET=...

📈 Scaling & Performance

Automatic Scaling

Railway automatically scales based on:

  • CPU Usage - Scale up when CPU exceeds thresholds
  • Memory Usage - Scale up when memory is constrained
  • Request Volume - Scale up during traffic spikes
  • Response Time - Scale up when performance degrades

Performance Optimization

typescript
// Implement caching strategies
const cache = new Map()

app.get('/api/events', async (req, res) => {
  const cacheKey = `events:${req.query.type}`
  
  if (cache.has(cacheKey)) {
    const cached = cache.get(cacheKey)
    if (Date.now() - cached.timestamp < 5 * 60 * 1000) { // 5 minutes
      return res.json(cached.data)
    }
  }
  
  const events = await getEvents(req.query.type)
  cache.set(cacheKey, {
    data: events,
    timestamp: Date.now()
  })
  
  res.json(events)
})

🚨 Troubleshooting

Common Issues

  1. Build Failures

    bash
    # Check build logs
    railway logs --service web
    
    # Verify package.json scripts
    # Ensure all dependencies are installed
  2. Runtime Errors

    bash
    # Check application logs
    railway logs --service web --follow
    
    # Verify environment variables
    railway variables list --service web
  3. Health Check Failures

    bash
    # Test health endpoint locally
    curl http://localhost:3000/api/health
    
    # Check service configuration
    railway service show web

Debug Commands

bash
# View service logs
railway logs --service web

# Check service status
railway status

# View environment variables
railway variables list --service web

# Access service shell
railway shell --service web

# View service metrics
railway metrics --service web

🔄 CI/CD Integration

GitHub Actions

Railway integrates with GitHub Actions:

yaml
# .github/workflows/deploy.yml
name: Deploy to Railway

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy to Railway
        uses: railway/deploy@v1
        with:
          service: web
          token: ${{ secrets.RAILWAY_TOKEN }}

Deployment Triggers

  • Main Branch → Production deployment
  • Feature Branches → Preview deployment
  • Pull Requests → Staging deployment
  • Tags → Release deployment

📚 Best Practices

Do's

  • Use environment variables for configuration
  • Implement health checks for monitoring
  • Set resource limits to control costs
  • Use automatic scaling for performance
  • Monitor logs for debugging

Don'ts

  • Don't commit secrets to version control
  • Don't ignore build errors - fix them first
  • Don't skip health checks - they're essential
  • Don't over-provision resources unnecessarily
  • Don't forget monitoring - visibility is key

Released under the MIT License.