Railway Provider

Deploy preview environments to Railway services.

How it works

Prerequisites

  1. A Railway account with an existing project and environment.
  2. A Railway API token.

Step 1 — Create a Railway project

  1. Go to railway.appNew Project.
  2. Open the project and note the Project ID and Environment ID — both are visible in the dashboard URL: https://railway.com/project/{projectId}?environmentId={environmentId} You can also find them in Settings → General (project) and Settings → Environments (environment).

Step 2 — Get a Railway API token

  1. Go to Account Settings → Tokens → Create Token.
  2. Give it a descriptive name (e.g. previewops).
  3. Copy the token — you'll store it in the Previewops credentials dashboard.

Step 3 — Store credentials in Previewops

  1. Log in to the Previewops dashboard.
  2. Go to Credentials → select the Railway provider.
  3. Fill in the three fields:
Field Description
Railway API Token The token from Step 2
Project ID Your Railway project UUID
Environment ID Your Railway environment UUID (e.g. production)
  1. Click Save.

Once credentials are stored, you can deploy with just a comment — no .previewops.yaml needed.

Step 4 — (Optional) Configure per-repo via .previewops.yaml

If you prefer to pin the project or environment per-repo (instead of using stored credentials), add:

provider: railway
providerConfig:
  projectId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx       # overrides stored RAILWAY_PROJECT_ID credential
  environmentId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   # overrides stored RAILWAY_ENVIRONMENT_ID credential

providerConfig values take precedence over dashboard credentials when both are set.

Complete example with all options:

# .previewops.yaml
provider: railway
providerConfig:
  projectId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx       # optional if RAILWAY_PROJECT_ID stored as credential
  environmentId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   # optional if RAILWAY_ENVIRONMENT_ID stored as credential

# Common options — all optional
concurrency: 3                  # max simultaneous active previews per repo
ttlHours: 24                    # auto-delete after N hours (default: 24)
port: 3000                      # optional — auto-detected from your Dockerfile EXPOSE; falls back to 8080
memory: 512Mi                   # container memory (default: 512Mi)
cpu: 1                          # container vCPU (default: 1)
dockerfile: Dockerfile          # Dockerfile path relative to repo root (default: Dockerfile)
buildContext: .                 # Docker build context (default: .)
env:
  NODE_ENV: preview             # inject env vars into the preview container

Step 5 — Verify

Comment /validate-previewops on any open PR. The bot verifies the API token and reports the authenticated Railway account name.

Private repositories

Railway's native build pipeline requires the Railway GitHub App to be installed on your org to access private repos. Previewops handles private repos automatically — no Railway GitHub App setup required.

When Previewops detects a private repository, it:

  1. Builds the Docker image using its own managed build pipeline.
  2. Distributes the pre-built image to Railway using short-lived, deploy-scoped credentials — no long-lived secrets stored on Railway's side.
  3. Railway deploys the pre-built image — no direct source code access required from Railway.

No extra configuration is needed. Previewops switches to the managed pipeline automatically when a private repo is detected.

Requirement: Premium BYOC plan or higher. Free BYOC is limited to public repos. Upgrade →

Deploy times

|---|---| | First deploy for a new PR (public repo) | 3–6 minutes | | First deploy for a new PR (private repo, managed build) | 5–10 minutes | | Redeploy on same PR | 2–4 minutes |

Railway builds your image using its own native build infrastructure. The main variables are your Dockerfile complexity and dependency install time.

Tip: structure your Dockerfile so dependency installation (COPY package.json && npm install) comes before copying source files (COPY . .). Railway caches layers between builds, so unchanged dependencies are not reinstalled on subsequent deploys.

Troubleshooting

Error / symptom Fix
RAILWAY_API_TOKEN environment variable is required Add RAILWAY_API_TOKEN to your credentials in the dashboard
providerConfig.projectId (or RAILWAY_PROJECT_ID credential) is required Add RAILWAY_PROJECT_ID to your credentials, or set providerConfig.projectId in .previewops.yaml
providerConfig.environmentId (or RAILWAY_ENVIRONMENT_ID credential) is required Add RAILWAY_ENVIRONMENT_ID to your credentials, or set providerConfig.environmentId in .previewops.yaml
Railway GraphQL errors: ... Token is expired or lacks project permissions — regenerate in Railway Account Settings
Deployment stuck in BUILDING Railway quota may be exhausted; check your Railway dashboard for billing or resource limits
Preview URL returns "not found" immediately after deploy Normal — Railway domain propagation and app startup complete shortly after the deploy is marked live. Wait 30–60 seconds and refresh.
Deploy marked ✅ Live but the "Visit →" link does nothing Retry the deploy command. If it persists, run /validate-previewops to confirm your credentials are still valid.
Build stuck at "Pulling image" for several minutes Large container layers can take several minutes to transfer. Expected for images over 500 MiB. Restructure your Dockerfile so unchanged dependencies are cached in early layers to reduce layer sizes.
Registry proxy auth failed The managed build pipeline is not configured for this installation. Contact support.