Skip to main content

Deploy to Railway

Railway turns a Docker image into a running service with zero infrastructure config. Choose between SQLite (simplest) or PostgreSQL (production-ready) storage.

One-click deployโ€‹

Deploy on Railway: SQLiteDeploy on Railway: PostgreSQL
TemplateStorageBest for
SQLiteFile-based on Railway VolumeDevelopment, single-instance, low traffic
PostgreSQLManaged Railway PostgresProduction, multiple instances, durability

Both templates prompt you for provider API keys and configure storage automatically.

SQLite templateโ€‹

The SQLite template attaches a Railway Volume at /data for persistent file storage. Environment variables:

MASTER_KEY=fgw_your-master-key          # auto-generated
OPENAI_API_KEY=sk-your-key # you provide
PORT=8080

# SQLite storage โ€” persisted to Railway Volume
API_KEY_STORE_BACKEND=sqlite
API_KEY_STORE_DSN=/data/keys.db
CONFIG_STORE_BACKEND=sqlite
CONFIG_STORE_DSN=/data/config.db
REQUEST_LOG_STORE_BACKEND=sqlite
REQUEST_LOG_STORE_DSN=/data/logs.db
RAILWAY_RUN_UID=0
When to use SQLite

SQLite is the fastest path to a running gateway. It works well for development, demos, and low-traffic production workloads. For high availability or multi-replica deployments, use PostgreSQL.

PostgreSQL templateโ€‹

The PostgreSQL template provisions a managed Postgres instance and wires all three store backends automatically:

MASTER_KEY=fgw_your-master-key
OPENAI_API_KEY=sk-your-key
PORT=8080

# PostgreSQL storage โ€” auto-wired to Railway Postgres
API_KEY_STORE_BACKEND=postgres
API_KEY_STORE_DSN=${{Postgres.DATABASE_URL}}
CONFIG_STORE_BACKEND=postgres
CONFIG_STORE_DSN=${{Postgres.DATABASE_URL}}
REQUEST_LOG_STORE_BACKEND=postgres
REQUEST_LOG_STORE_DSN=${{Postgres.DATABASE_URL}}

Manual setupโ€‹

Step 1: Install the Railway CLIโ€‹

npm install -g @railway/cli
railway login

Step 2: Create the projectโ€‹

railway init

Step 3: Deploy the gateway imageโ€‹

railway up --image ghcr.io/ferro-labs/ai-gateway:latest

Or create a minimal Dockerfile:

Dockerfile
FROM ghcr.io/ferro-labs/ai-gateway:latest

Step 4: Set environment variablesโ€‹

railway variables set MASTER_KEY=fgw_your-master-key
railway variables set OPENAI_API_KEY=sk-your-key
railway variables set PORT=8080
railway variables set API_KEY_STORE_BACKEND=sqlite
railway variables set API_KEY_STORE_DSN=/data/keys.db
railway variables set CONFIG_STORE_BACKEND=sqlite
railway variables set CONFIG_STORE_DSN=/data/config.db
railway variables set REQUEST_LOG_STORE_BACKEND=sqlite
railway variables set REQUEST_LOG_STORE_DSN=/data/logs.db
warning

Never hardcode API keys in your Dockerfile or config files. Always use Railway environment variables โ€” they are encrypted at rest.

Step 5: Attach a volume (SQLite only)โ€‹

In the Railway dashboard, go to your service โ†’ Settings โ†’ Volumes and mount a volume at /data.

Step 6: Deployโ€‹

railway up

Adding more providersโ€‹

Add provider keys as environment variables:

railway variables set ANTHROPIC_API_KEY=sk-ant-...
railway variables set GEMINI_API_KEY=...
railway variables set MISTRAL_API_KEY=...

The gateway picks up new keys on restart.

Verify the deploymentโ€‹

# Health check
curl https://your-project.up.railway.app/health

# Test request
curl https://your-project.up.railway.app/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MASTER_KEY" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello from Railway!"}]
}'
tip

Your Railway URL is shown in the dashboard under your service's Settings tab, or in the output of railway up.