Skip to content

Latest commit

 

History

History
374 lines (277 loc) · 10 KB

File metadata and controls

374 lines (277 loc) · 10 KB

Railway Deployment Guide

Deploy KP Rück to Railway with separate services for database, backend, and frontend. This guide also applies broadly to other Docker-compatible PaaS providers.

Prerequisites

Deployment Architecture

Railway will deploy three separate services:

  1. PostgreSQL - Managed database
  2. Backend - FastAPI application
  3. Frontend - Next.js application

Deployment Steps

Method 1: Railway Dashboard (Recommended)

1. Create New Project

  1. Go to https://railway.app/new
  2. Click "Deploy from GitHub repo"
  3. Select your kp-rueck repository
  4. Railway will create a new project

2. Add PostgreSQL Database

  1. In your Railway project, click "New"
  2. Select "Database" → "PostgreSQL"
  3. Railway will provision a PostgreSQL instance
  4. Note: Railway automatically creates DATABASE_URL variable

3. Deploy Backend Service

  1. Click "New" → "GitHub Repo" → Select kp-rueck

  2. Configure the service:

    • Name: backend
    • Root Directory: /backend
    • Build Command: (Auto-detected from Dockerfile)
    • Start Command: ./start.sh
  3. Add Volume for Photo Storage:

    • Go to backend service → Settings → Volumes
    • Click "New Volume"
    • Mount path: /mnt/data
    • Size: 5GB+ (adjust based on expected photo storage needs)
  4. Add environment variables:

    DATABASE_URL=${{Postgres.DATABASE_URL}}
    CORS_ORIGINS=https://your-frontend-url.railway.app
    PHOTOS_DIR=/mnt/data/photos
    SECRET_KEY=<openssl rand -hex 32>
    AUTH_SECRET_KEY=<openssl rand -hex 32>
    ADMIN_SEED_PASSWORD=<strong initial admin password>
    EDITOR_PASSWORD=<strong shared editor password, or disable this user after first login>
    PORT=8000
    
  5. Click "Deploy"

4. Deploy Frontend Service

  1. Click "New" → "GitHub Repo" → Select kp-rueck

  2. Configure the service:

    • Name: frontend
    • Root Directory: /frontend
    • Build Command: (Auto-detected from Dockerfile)
    • Start Command: node server.js
  3. Add environment variables:

    NEXT_PUBLIC_API_URL=https://your-backend-url.railway.app
    PORT=3000
    
  4. Click "Deploy"

5. Update CORS Origins

After frontend deploys, copy its URL and update backend's CORS_ORIGINS:

CORS_ORIGINS=https://your-frontend-url.railway.app

Method 2: Railway CLI

# Install Railway CLI
npm install -g @railway/cli

# Login
railway login

# Initialize project
railway init

# Link to project
railway link

# Deploy backend
cd backend
railway up

# Deploy frontend
cd ../frontend
railway up

# Add database
railway add --database postgresql

Environment Variables

Backend (backend service)

Variable Value Description
DATABASE_URL ${{Postgres.DATABASE_URL}} Auto-linked from PostgreSQL service
CORS_ORIGINS https://your-frontend.railway.app Frontend URL for CORS
PHOTOS_DIR /mnt/data/photos Photo storage directory. Must point inside the mounted Railway volume
SECRET_KEY Generated 32-byte hex string Signs public check-in, Reko, viewer, and alarm-intake tokens
AUTH_SECRET_KEY Generated 32-byte hex string Signs login access and refresh JWTs
ADMIN_SEED_PASSWORD Strong password, 12+ characters Required for the initial admin user when the database is first seeded
EDITOR_PASSWORD Strong password, 12+ characters Password for the seeded shared editor account. Set this explicitly or disable the account after first login
PORT 8000 Port (Railway sets automatically)

Important: The PHOTOS_DIR environment variable must point to the volume mount path. Without this, photos will be stored in ephemeral container storage and lost on restart.

Generate secrets locally with:

openssl rand -hex 32

SECRET_KEY and AUTH_SECRET_KEY protect different token families in the backend. They can be generated the same way, but should be stored as separate Railway variables.

Frontend (frontend service)

Variable Value Description
NEXT_PUBLIC_API_URL https://your-backend.railway.app Backend API URL
PORT 3000 Port (Railway sets automatically)

Post-Deployment

1. Initialize Database

The backend's start.sh script automatically:

  • Creates database tables
  • Seeds initial data (on first run)

2. Verify Deployment

3. Monitor Logs

View logs in Railway dashboard:

  • Click on each service
  • Navigate to "Deployments" tab
  • Click "View Logs"

Service Configuration

Each service has a railway.json file:

Backend (backend/railway.json):

{
  "build": {
    "builder": "DOCKERFILE",
    "dockerfilePath": "Dockerfile"
  },
  "deploy": {
    "startCommand": "uv run uvicorn app.main:app --host 0.0.0.0 --port $PORT",
    "healthcheckPath": "/health"
  }
}

Frontend (frontend/railway.json):

{
  "build": {
    "builder": "DOCKERFILE",
    "dockerfilePath": "Dockerfile"
  },
  "deploy": {
    "startCommand": "node server.js"
  }
}

Connecting Services

Railway automatically handles:

  • Database → Backend: Use ${{Postgres.DATABASE_URL}} reference
  • Backend → Frontend: Set NEXT_PUBLIC_API_URL to backend URL
  • Service Discovery: Internal networking between services

Custom Domains

  1. Go to service settings
  2. Click "Settings" → "Domains"
  3. Click "Generate Domain" or add custom domain
  4. Update CORS and API URL environment variables accordingly

Scaling

Railway allows horizontal scaling:

  1. Go to service settings
  2. Adjust "Replicas" count
  3. Backend and Frontend can scale independently

Database Backups

Railway PostgreSQL includes:

  • Automatic daily backups
  • Point-in-time recovery
  • Manual snapshot creation

Database Reset (If Needed)

If the Railway database contains stale data with incorrect enum values, you can reset it:

Option 1: Via Railway Dashboard

  1. Go to your Railway project
  2. Click on the PostgreSQL service
  3. Go to "Data" tab
  4. Click "Reset Database" (this will delete all data and tables)
  5. Redeploy the backend service to trigger automatic re-seeding

Option 2: Via Railway CLI

# Connect to Railway project
railway link

# Open Railway shell for backend service
railway run bash

# Inside the shell, reset database
PGPASSWORD=$PGPASSWORD psql -h $PGHOST -p $PGPORT -U $PGUSER -d $PGDATABASE -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"

# Exit shell
exit

# Trigger redeployment to re-seed
railway up

Option 3: Manual SQL Reset

  1. Open Railway dashboard
  2. Navigate to PostgreSQL service → "Data" tab
  3. Run SQL query:
    DROP SCHEMA public CASCADE;
    CREATE SCHEMA public;
  4. Redeploy backend service

After reset, the backend's start.sh script will automatically:

  • Run Alembic migrations to recreate tables
  • Seed initial data with correct values

Troubleshooting

Backend not connecting to database

  1. Check DATABASE_URL is set correctly
  2. Verify PostgreSQL service is running
  3. Check logs for connection errors

Frontend can't reach backend

  1. Verify NEXT_PUBLIC_API_URL is set
  2. Check backend CORS settings
  3. Ensure backend service is deployed and healthy

Build failures

  1. Check Dockerfile syntax
  2. Verify all dependencies are listed
  3. Review build logs in Railway dashboard

Costs

Railway pricing (as of 2024):

  • Hobby Plan: $5/month + usage
  • PostgreSQL: ~$5-10/month
  • Compute: Pay for what you use
  • Bandwidth: Generous free tier

Photo Storage (Reko Reports)

The backend supports photo uploads for Reko (reconnaissance) reports. Photos require persistent storage to survive container restarts.

Volume Setup

  1. Attach Volume to Backend Service:

    • Railway Dashboard → Backend Service → Settings → Volumes
    • Click "New Volume"
    • Mount path: /mnt/data
    • Size: 5GB+ (recommended)
  2. Set Environment Variable:

    PHOTOS_DIR=/mnt/data/photos
  3. Verify Setup:

    • Check backend logs during startup for:
      Photo storage directory: /mnt/data/photos
      Photos directory ready: /mnt/data/photos
      

Storage Estimates

  • Average photo after compression: ~200KB
  • Max photos per report: 20
  • Max size per report: ~4MB

Storage needs:

  • 100 reports: ~400MB
  • 1,000 reports: ~4GB
  • 10,000 reports: ~40GB

Troubleshooting Photos

Photos disappear after restart:

  • Verify PHOTOS_DIR=/mnt/data/photos is set
  • Check volume is mounted at /mnt/data
  • Review backend startup logs

Upload fails:

  • Check volume has available space
  • Verify mount path is correct
  • Review backend error logs

Detailed Documentation: See docs/PHOTO_STORAGE.md for comprehensive photo storage documentation, including:

  • API endpoints
  • Testing procedures
  • Security considerations
  • Performance optimization

Production Checklist

  • Set strong PostgreSQL password
  • Enable Railway's built-in DDoS protection
  • Set up custom domain with SSL
  • Configure backend environment variables: DATABASE_URL, CORS_ORIGINS, PHOTOS_DIR, SECRET_KEY, AUTH_SECRET_KEY, ADMIN_SEED_PASSWORD, EDITOR_PASSWORD
  • Configure frontend environment variables: NEXT_PUBLIC_API_URL and, if needed, NEXT_PUBLIC_WS_URL
  • Attach volume for photo storage (/mnt/data)
  • Set PHOTOS_DIR=/mnt/data/photos environment variable
  • Verify backend startup logs show Photo storage directory: /mnt/data/photos and Photos directory ready: /mnt/data/photos
  • Enable automatic deployments from main branch
  • Set up monitoring and alerts
  • Configure backups retention policy
  • Review and optimize resource allocation

Support