|Docs

railway config

Manage a Railway project and environment from an Infrastructure as Code file at .railway/railway.ts (generally available), .railway/railway.py, or .railway/railway.go (Python and Go authoring are in beta).

Usage

The config command creates, imports, previews, and applies Railway Infrastructure as Code.

railway config <COMMAND> [OPTIONS]
CommandDescription
initCreate .railway/railway.ts by default
pullImport the selected Railway environment into the authoring file
planPreview changes without applying them
applyPreview, confirm, and apply changes
migrateConvert Config as Code into IaC (--lang ts | py | go)

See Infrastructure as Code for the complete workflow and the IaC reference for the TypeScript DSL. Prefer one configuration file per project. Named partials are a last resort for split repositories, not the default.

Find the configuration file

railway config plan and railway config apply use the nearest .railway/railway.ts, .railway/railway.py, or .railway/railway.go. The CLI checks the current directory and then walks up through its parent directories. Keep only one of those files.

Override discovery with an explicit file:

railway config plan --file path/to/railway.ts

Initialize configuration

Run init from the repository root where you want Railway to create the .railway directory.

railway config init
FlagDescription
--forceOverwrite an existing authoring file

The interactive flow can scan the repository, import a Railway project, or create a minimal file.

Import Railway state

Use pull to render the selected Railway project and environment as authoring code (TypeScript unless .railway/railway.py or .railway/railway.go already exists).

railway config pull
FlagDescription
--forceOverwrite an existing authoring file
--jsonPrint the imported graph as JSON instead of writing files
--runner <PATH>Use a specific TypeScript configuration runner
--omit-preserved-variablesOmit unknown variables instead of rendering preserve()
--include-variablesDecrypt and inline non-sealed variable values into the file
--agentPrint a suggestion to ask an agent to turn imported state into idiomatic TypeScript

--include-variables writes non-sealed values, including secrets that were never sealed, into .railway/railway.ts. The CLI prints a warning when you use it. Sealed variables stay as preserve().

The TypeScript file imports railway/iac. Install the SDK from the repository root (npm install railway, or the equivalent pnpm / yarn / bun command) before plan or apply.

--agent doesn't invoke an agent or change the generated file. The flag has no effect with --json, which prints only the imported graph.

Review an imported configuration with railway config plan before applying it.

Migrate Config as Code

railway config migrate finds every railway.json and railway.toml in the repository — including files in monorepo packages — and emits one .railway/railway.ts. Linked services whose Railway Config File points at those paths keep their Railway service names.

railway config migrate
railway config migrate --apply
railway config migrate --apply --delete-files
FlagDescription
--applyWrite the file and clear Railway Config File settings
--forceOverwrite an existing .railway/railway.ts
--delete-filesDelete the discovered CaC files after a successful apply
--service <name>Migrate only this service
--lang ts|py|goAuthoring language (default ts)

A single-service migrate still writes a named partial export. A merged migrate does not.

Preview changes

Use plan to compare the authoring file with the selected Railway environment without changing resources.

railway config plan
FlagDescription
--file <PATH>Use a specific configuration file
--jsonOutput raw runner JSON
--decrypt-variablesRequest decrypted variables when authorized
--include-typesInclude generated graph TypeScript types in runner output
--runner <PATH>Use a specific TypeScript configuration runner
--verbose, --fullShow full change details
--detailed-exit-codeExit 2 when changes are pending and 0 when none are pending
--show-valuesPrint variable values instead of redacting them
--out <PATH>Write a pinned plan artifact (change set, configEtag, .railway/ tree)
--source-tree <SHA>Override the tree written into --out (defaults to git rev-parse HEAD:.railway)

Plan output redacts variable values by default. Treat output from --show-values or --decrypt-variables as sensitive.

--out is the CI pin. Merge should apply that file, not re-plan:

railway config plan --out railway-plan.json
railway config apply --plan railway-plan.json --yes --confirm-destructive

Apply fails if the live environment etag no longer matches, or if the checked-out .railway/ tree is not the planned tree. In GitHub Actions, use railwayapp/config so pull requests get a plan comment and merge applies that pinned artifact. See Apply from GitHub Actions.

Apply changes

Use apply to run a fresh plan and apply its changes. Without a non-interactive flag, the CLI asks for confirmation.

railway config apply

apply accepts the plan options except --detailed-exit-code. It also accepts these confirmation flags:

FlagDescription
--yesSkip the confirmation prompt and run non-interactively
--confirm-destructivePermit destructive changes in non-interactive, JSON, or agent sessions
--plan <PATH>Apply a pinned --out artifact without re-evaluating the authoring file

For a destructive non-interactive apply with human-readable output, pass both confirmation flags:

railway config apply --yes --confirm-destructive

In JSON mode, pass --confirm-destructive to apply destructive changes. The --json flag already skips the confirmation prompt, so --yes isn't required:

railway config apply --json --confirm-destructive

These pages cover Infrastructure as Code and Railway configuration files.