RAILWAY GITHUB DEPLOYMENT
Documentation for Deployment
Railway GitHub Deployment Guide
Last Updated: February 28, 2026
Overview
All 4 backend API services deploy via GitHub branch-based triggers. Each service has a dedicated deploy/* branch. Pushing to that branch triggers Railway to build and deploy automatically via the Railway GitHub App.
Preferred method: Use the smart deploy CLI (
yarn deploy) which handles merging, toml validation, and pushing. See deployment/docs/RAILWAY_DEPLOYMENT_GUIDE.md.
Architecture
┌────────────────────────┐ ┌──────────────────┐ ┌───────────────────┐
│ Your working branch │ │ deploy/api │ ──► │ backend-api │
│ (integration/session) │ ──► │ deploy/ai-api │ ──► │ backend-ai-api │
│ │ │ deploy/docs-api │ ──► │ backend-docs-api │
│ │ │ deploy/vitto-api│ ──► │ backend-vitto-api│
└────────────────────────┘ └──────────────────┘ └───────────────────┘
Local Git GitHub (triggers build) Railway Services
All 4 services live in one consolidated Railway project: 3990549d-4313-47e4-9682-d17b382bdba2
Service Configuration
| Service | Deploy Branch | Domain | Health Check | Service ID |
|---|---|---|---|---|
| backend-api | deploy/api |
api.gograb.space |
/api/health |
1ad0b79a-b722-4c69-920c-5dcb35978f0d |
| backend-ai-api | deploy/ai-api |
ai-api.gograb.space |
/ai-api/health |
fa00811a-db8e-4232-a23f-2becd96615c7 |
| backend-docs-api | deploy/docs-api |
docs-api.gograb.space |
/docs-api/health |
0f7af191-d7a4-4366-82b6-312c4ab8fa7e |
| backend-vitto-api | deploy/vitto-api |
vitto-api.gograb.space |
/vitto-api/health |
072352ed-2e34-468e-bec9-03f6d299f867 |
Deployment via Smart CLI (Recommended)
# Deploy all 4 APIs
yarn deploy --apis api,ai-api,docs-api,vitto-api --no-interactive --force
# Deploy a single API
yarn deploy --apis api --no-interactive --force
The CLI handles: stashing work, branch checkout, merge, toml copy, validation, push, restore, and health checks.
Manual Deployment (If CLI is unavailable)
# Deploy backend-api
git stash
git checkout deploy/api
git merge <your-branch> --no-edit
cp deployment/backend-api/railway.toml railway.toml
git add railway.toml
git commit -m "chore: update railway.toml for deploy"
git push origin deploy/api
git checkout <your-branch>
git stash pop
# Repeat for deploy/ai-api, deploy/docs-api, deploy/vitto-api
# using the corresponding deployment/{service}/railway.toml
Branch Structure
Each deploy branch must have a railway.toml at the repo root. The smart deploy CLI copies the canonical toml from deployment/{service}/railway.toml automatically.
deploy/api → railway.toml
[build]
builder = "DOCKERFILE"
dockerfilePath = "deployment/backend-api/Dockerfile.railway"
dockerContext = "."
watchPatterns = [
"APIs/backend-api/**",
"libs/libs-api/backend-core/**",
"libs/libs-api/auth-core/**",
"libs/libs-foundational/core-models/**",
"deployment/backend-api/Dockerfile.railway",
"package.json", "yarn.lock", "tsconfig.base.json", "nx.json"
]
[deploy]
startCommand = "node dist/APIs/backend-api/main.js"
healthcheckPath = "/api/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
deploy/ai-api → railway.toml
[build]
builder = "DOCKERFILE"
dockerfilePath = "deployment/backend-ai-api/Dockerfile.railway"
dockerContext = "."
watchPatterns = [
"APIs/backend-ai-api/**",
"APIs/claude-agent-mcp/**",
"libs/libs-api/backend-core/**",
"libs/libs-api/auth-core/**",
"libs/libs-api/llm-integration/**",
"libs/libs-foundational/core-models/**",
"deployment/backend-ai-api/Dockerfile.railway",
"package.json", "yarn.lock", "tsconfig.base.json", "nx.json"
]
[deploy]
startCommand = "node dist/APIs/backend-ai-api/main.js"
healthcheckPath = "/ai-api/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
deploy/docs-api → railway.toml
[build]
builder = "DOCKERFILE"
dockerfilePath = "deployment/backend-docs-api/Dockerfile.railway"
dockerContext = "."
watchPatterns = [
"APIs/backend-docs-api/**",
"libs/libs-api/backend-core/**",
"libs/libs-api/auth-core/**",
"deployment/backend-docs-api/Dockerfile.railway",
"package.json", "yarn.lock", "tsconfig.base.json", "nx.json"
]
[deploy]
startCommand = "node dist/APIs/backend-docs-api/main.js"
healthcheckPath = "/docs-api/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
deploy/vitto-api → railway.toml
[build]
builder = "DOCKERFILE"
dockerfilePath = "deployment/backend-vitto-api/Dockerfile.railway"
dockerContext = "."
watchPatterns = [
"APIs/backend-vitto-api/**",
"libs/libs-api/backend-core/**",
"libs/libs-foundational/core-models/**",
"deployment/backend-vitto-api/Dockerfile.railway",
"package.json", "yarn.lock", "tsconfig.base.json", "nx.json"
]
[deploy]
startCommand = "node dist/APIs/backend-vitto-api/main.js"
healthcheckPath = "/vitto-api/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
Critical: Path Naming Convention
The
apps/directory was renamed toAPIs/(capital letters). All deployment files must useAPIs/, notapps/.
| Component | Correct | Wrong |
|---|---|---|
| Source directory | APIs/backend-api/ |
apps/backend-api/ |
| Build output | dist/APIs/backend-api/main.js |
dist/apps/backend-api/main.js |
| Dockerfile path | deployment/backend-api/Dockerfile.railway |
deployment/Dockerfile.railway.backend |
| Railway config | deployment/backend-api/railway.toml |
deployment/railway.backend.toml |
| watchPatterns | APIs/backend-api/** |
apps/backend-api/** |
The railway.toml startCommand overrides the Dockerfile CMD. If these paths don't match the actual NX build output, the service will fail to start.
Railway Settings (per service)
Source Configuration
| Setting | Value |
|---|---|
| Source Repo | GoGrabSpace/editor |
| Branch | deploy/api / deploy/ai-api / deploy/docs-api / deploy/vitto-api |
| Root Directory | / (default) |
Build Configuration
| Setting | Value |
|---|---|
| Builder | Dockerfile (set via railway.toml) |
| Dockerfile Path | From railway.toml (deployment/{service}/Dockerfile.railway) |
Verification
Health Checks
curl -s https://api.gograb.space/api/health | jq
curl -s https://ai-api.gograb.space/ai-api/health | jq
curl -s https://docs-api.gograb.space/docs-api/health | jq
curl -s https://vitto-api.gograb.space/vitto-api/health | jq
Troubleshooting
Build Uses Railpack Instead of Dockerfile
Cause: railway.toml missing or doesn't have builder = "DOCKERFILE"
Fix: Use yarn deploy — it copies the canonical toml automatically.
startCommand Path Wrong → Service Crashes on Start
Cause: railway.toml says dist/apps/... but NX builds to dist/APIs/...
Fix: Update the canonical deployment/{service}/railway.toml to use dist/APIs/.
Deploy Branch Out of Sync
Fix: Use yarn deploy (it merges your current branch). Or manually:
git checkout deploy/api
git merge <your-branch>
git push origin deploy/api
CORS Errors
Fix: Add the missing origin to ALLOWED_ORIGINS in Railway dashboard variables.
Related Files
| File | Purpose |
|---|---|
deployment/backend-api/Dockerfile.railway |
Backend API production Dockerfile |
deployment/backend-ai-api/Dockerfile.railway |
Backend AI API production Dockerfile |
deployment/backend-docs-api/Dockerfile.railway |
Backend Docs API production Dockerfile |
deployment/backend-vitto-api/Dockerfile.railway |
Backend Vitto API production Dockerfile |
deployment/backend-api/railway.toml |
Canonical Railway config for backend-api |
deployment/backend-ai-api/railway.toml |
Canonical Railway config for backend-ai-api |
deployment/backend-docs-api/railway.toml |
Canonical Railway config for backend-docs-api |
deployment/backend-vitto-api/railway.toml |
Canonical Railway config for backend-vitto-api |
deployment/cli/railway-deploy-cli.js |
Smart deploy CLI |
deployment/cli/lib/deployment-config.js |
Service IDs, branches, paths |