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 to APIs/ (capital letters). All deployment files must use APIs/, not apps/.

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