Railway Provider
Deploy preview environments to Railway services.
How it works
- Build: Previewops passes the source commit to Railway. Railway builds from the repo's Dockerfile using its own native build infrastructure — no separate image build step is needed.
- Deploy: Creates a Railway service within your project (or re-deploys an existing one for the same PR). Polls until the deployment reaches
SUCCESSstatus. - Delete: Deletes the Railway service when the PR is closed.
- List: Lists all services in the project that match the
prev-{owner}-{repo}name prefix.
Prerequisites
- A Railway account with an existing project and environment.
- A Railway API token.
Step 1 — Create a Railway project
- Go to railway.app → New Project.
- 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
- Go to Account Settings → Tokens → Create Token.
- Give it a descriptive name (e.g.
previewops). - Copy the token — you'll store it in the Previewops credentials dashboard.
Step 3 — Store credentials in Previewops
- Log in to the Previewops dashboard.
- Go to Credentials → select the Railway provider.
- 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) |
- 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:
- Builds the Docker image using its own managed build pipeline.
- Distributes the pre-built image to Railway using short-lived, deploy-scoped credentials — no long-lived secrets stored on Railway's side.
- 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
Dockerfileso 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. |