Skills railway-deploy
git clone https://github.com/TerminalSkills/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/railway-deploy" ~/.claude/skills/terminalskills-skills-railway-deploy && rm -rf "$T"
skills/railway-deploy/SKILL.md- global npm install
- shell exec via library
- makes HTTP requests (curl)
- references API keys
Railway Deploy
Overview
Deploy, manage, and monitor applications on Railway using the CLI. Covers the full lifecycle: project setup, service configuration, environment variables, deployments, scaling, logs, and debugging.
Instructions
Task A: Project Setup & Linking
First verify the CLI is installed. If
railway is not found, install it:
npm i -g @railway/cli # or: brew install railway
Check if already linked to a project:
railway status
If not linked, either create a new project or link to an existing one:
railway init # Create a new project railway link # Link to an existing project
After linking, confirm with
railway status to verify project, service, and environment context.
For CI/CD or headless environments, use token auth:
RAILWAY_TOKEN=xxx railway up # Project-scoped token RAILWAY_API_TOKEN=xxx railway up # Account-scoped token
Task B: Deploy
# Deploy current directory and stream logs railway up # Deploy without waiting for logs railway up --detach # Target a specific service railway up -s my-service # Deploy to a specific environment railway up -e staging
To remove the latest deployment:
railway down
To redeploy the latest deployment (same code, fresh build):
railway redeploy
To restart a service without rebuilding:
railway restart
Task C: Manage Services & Resources
# Add a service interactively railway add # Add a database railway add --database postgres # also: mysql, redis, mongo # Add a service from a GitHub repo railway add --repo user/repo # Switch linked service context railway service # Scale a service railway scale # Generate a Railway subdomain or add a custom domain railway domain railway domain example.com # Manage persistent volumes railway volume list railway volume add railway volume delete # Delete the entire project railway delete
Task D: Environment Variables
# List all variables for current service/environment railway variable list # Set a variable railway variable set DATABASE_URL=postgres://user:pass@host:5432/db # Set multiple variables railway variable set KEY1=value1 KEY2=value2 # Delete a variable railway variable delete SECRET_KEY
Task E: Environments
# Switch environment interactively railway environment # Create a new environment railway environment new staging # Delete an environment railway environment delete dev # Deploy to a specific environment railway up -e production
Task F: Logs & Debugging
# Stream live logs railway logs # View build logs railway logs --build # View last N lines railway logs -n 100 # SSH into the running container railway ssh # Connect to a database shell (e.g., psql, mysql, redis-cli) railway connect
Task G: Local Development
# Run a command with Railway environment variables injected railway run npm start railway run python manage.py migrate # Open an interactive shell with Railway env vars railway shell
Examples
Example 1: Deploy a Node.js app from scratch
User request: "Deploy my Node.js app to Railway"
Actions taken:
$ railway login > Opening browser for authentication... > Logged in as andrey@example.com $ railway init > Created project "my-node-app" in workspace "Personal" $ railway up > Uploading 2.3 MB... > Build started > Installing dependencies... > Build completed in 34s > Deployment live at my-node-app.up.railway.app $ railway domain > Service domain: my-node-app.up.railway.app
Example 2: Add a Postgres database and wire it up
User request: "Add a database to my Railway project and set it up"
Actions taken:
$ railway status > Project: my-node-app > Service: web > Environment: production $ railway add --database postgres > Added PostgreSQL service to project # The DATABASE_URL is automatically injected. Verify: $ railway variable list > DATABASE_URL=postgres://railway:abc123@host:5432/railway > PGHOST=host > PGPORT=5432 > ... # Run migrations using Railway env vars $ railway run npx prisma migrate deploy > Applying migrations... > 3 migrations applied successfully $ railway redeploy > Redeploying web service... > Deployment live
Example 3: Debug a failing deployment
User request: "My Railway deployment is crashing, help me debug it"
Actions taken:
$ railway status > Project: my-api > Service: web > Environment: production # Check build logs first $ railway logs --build > Step 4/8: RUN npm ci > npm ERR! Could not resolve dependency: peer express@"^4.0.0" # If build passes but runtime fails, check runtime logs $ railway logs -n 50 > Error: connect ECONNREFUSED 127.0.0.1:5432 # Verify variables are set $ railway variable list > DATABASE_URL=postgres://...@localhost:5432/mydb # BUG: using localhost # Fix: point to the Railway-provided database host $ railway variable set DATABASE_URL=postgres://user:pass@railway-db-host:5432/mydb $ railway redeploy > Redeploying... > Deployment live
Task H: Health Checks and Auto-Rollback
After deploying, verify the service is healthy before considering the deploy complete. If unhealthy, roll back to the previous deployment.
# Deploy and wait for completion $ railway up --detach # Health check loop — verify the service responds HEALTH_URL="https://your-app.railway.app/api/health" TIMEOUT=60 DEADLINE=$((SECONDS + TIMEOUT)) HEALTHY=false while [ $SECONDS -lt $DEADLINE ]; do STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" 2>/dev/null || echo "000") if [ "$STATUS" = "200" ]; then HEALTHY=true break fi echo "Waiting for healthy response... (status: $STATUS)" sleep 3 done if [ "$HEALTHY" = true ]; then echo "✅ Deployment healthy!" else echo "❌ Health check failed! Rolling back..." railway rollback echo "⏪ Rolled back to previous deployment" fi
Automated deploy script with health verification:
# deploy_railway.py — Deploy with health check and auto-rollback import subprocess import time import httpx def deploy_with_health_check(health_url, timeout=60): """Deploy to Railway, verify health, rollback on failure.""" print("🚀 Deploying to Railway...") subprocess.run(["railway", "up", "--detach"], check=True) print(f"🏥 Health checking {health_url}...") deadline = time.time() + timeout while time.time() < deadline: try: r = httpx.get(health_url, timeout=5) if r.status_code == 200: print("✅ Healthy!") return True except httpx.RequestError: pass time.sleep(3) print("❌ Unhealthy! Rolling back...") subprocess.run(["railway", "rollback"], check=True) print("⏪ Rolled back") return False
Guidelines
- Always run
first to confirm project, service, and environment context before making changes.railway status - Use
in CI/CD pipelines to avoid blocking on log output.railway up --detach - Use
for project-scoped CI/CD auth andRAILWAY_TOKEN
for account-level operations.RAILWAY_API_TOKEN - Use
and-s service-name
flags when managing multi-service projects to avoid acting on the wrong target.-e environment-name - Use
to execute one-off commands (migrations, seeds) with production env vars without deploying.railway run - If a deployment fails, check build logs (
) first, then runtime logs (railway logs --build
).railway logs - Use
to get a database shell directly without needing connection strings locally.railway connect - Add
to any command for machine-readable output in scripts.--json - Use
to update env vars, thenrailway variable set
to pick up the changes.railway redeploy - Use
to create staging/preview environments that mirror production config.railway environment new - If
command is not found, install viarailway
ornpm i -g @railway/cli
.brew install railway - If
fails or times out, userailway login
for headless/SSH environments.railway login --browserless