Back to Skills

railway-environment

davila7
Updated Today
34 views
15,516
1,344
15,516
View on GitHub
MetaRailwayEnvironmentConfigurationVariablesBuildDeployInfrastructureSettings

About

This skill manages Railway environment configuration including variables, service settings, and deployment changes. It handles all variable operations, service lifecycle management, and configuration staging/application. Developers should use this instead of railway-status for any configuration-related queries or modifications.

Documentation

Environment Configuration

Query, stage, and apply configuration changes for Railway environments.

Shell Escaping

CRITICAL: When running GraphQL queries via bash, you MUST wrap in heredoc to prevent shell escaping issues:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh 'query ...' '{"var": "value"}'
SCRIPT

Without the heredoc wrapper, multi-line commands break and exclamation marks in GraphQL non-null types get escaped, causing query failures.

When to Use

  • User wants to create a new environment
  • User wants to duplicate an environment (e.g., "copy production to staging")
  • User wants to switch to a different environment
  • User asks about current build/deploy settings, variables, replicas, health checks, domains
  • User asks to change service source (Docker image, branch, commit, root directory)
  • User wants to connect a service to a GitHub repo
  • User wants to deploy from a GitHub repo (create empty service first via railway-new skill, then use this)
  • User asks to change build or start command
  • User wants to add/update/delete environment variables
  • User wants to change replica count or configure health checks
  • User asks to delete a service, volume, or bucket
  • User says "apply changes", "commit changes", "deploy changes"
  • Auto-fixing build errors detected in logs

Create Environment

Create a new environment in the linked project:

railway environment new <name>

Duplicate an existing environment:

railway environment new staging --duplicate production

With service-specific variables:

railway environment new staging --duplicate production --service-variable api PORT=3001

Switch Environment

Link a different environment to the current directory:

railway environment <name>

Or by ID:

railway environment <environment-id>

Get Context

railway status --json

Extract:

  • project.id - for service lookup
  • environment.id - for the mutations
  • service.id - default service if user doesn't specify one

Resolve Service ID

If user specifies a service by name, query project services:

query projectServices($projectId: String!) {
  project(id: $projectId) {
    services {
      edges {
        node {
          id
          name
        }
      }
    }
  }
}

Match the service name (case-insensitive) to get the service ID.

Query Configuration

Fetch current environment configuration and staged changes.

query environmentConfig($environmentId: String!) {
  environment(id: $environmentId) {
    id
    config(decryptVariables: false)
    serviceInstances {
      edges {
        node {
          id
          serviceId
        }
      }
    }
  }
  environmentStagedChanges(environmentId: $environmentId) {
    id
    patch(decryptVariables: false)
  }
}

Example:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh \
  'query envConfig($envId: String!) {
    environment(id: $envId) { id config(decryptVariables: false) }
    environmentStagedChanges(environmentId: $envId) { id patch(decryptVariables: false) }
  }' \
  '{"envId": "ENV_ID"}'
SCRIPT

Response Structure

The config field contains current configuration:

{
  "services": {
    "<serviceId>": {
      "source": { "repo": "...", "branch": "main" },
      "build": { "buildCommand": "npm run build", "builder": "NIXPACKS" },
      "deploy": {
        "startCommand": "npm start",
        "multiRegionConfig": { "us-west2": { "numReplicas": 1 } }
      },
      "variables": { "NODE_ENV": { "value": "production" } },
      "networking": { "serviceDomains": {}, "customDomains": {} }
    }
  },
  "sharedVariables": { "DATABASE_URL": { "value": "..." } }
}

The patch field in environmentStagedChanges contains pending changes. The effective configuration is the base config merged with the staged patch.

For complete field reference, see reference/environment-config.md.

For variable syntax and service wiring patterns, see reference/variables.md.

Get Rendered Variables

The GraphQL queries above return unrendered variables - template syntax like ${{shared.DOMAIN}} is preserved. This is correct for management/editing.

To see rendered (resolved) values as they appear at runtime:

# Current linked service
railway variables --json

# Specific service
railway variables --service <service-name> --json

When to use:

  • Debugging connection issues (see actual URLs/ports)
  • Verifying variable resolution is correct
  • Viewing Railway-injected values (RAILWAY_*)

Stage Changes

Stage configuration changes via the environmentStageChanges mutation. Use merge: true to automatically merge with existing staged changes.

mutation stageEnvironmentChanges(
  $environmentId: String!
  $input: EnvironmentConfig!
  $merge: Boolean
) {
  environmentStageChanges(
    environmentId: $environmentId
    input: $input
    merge: $merge
  ) {
    id
  }
}

Important: Always use variables (not inline input) because service IDs are UUIDs which can't be used as unquoted GraphQL object keys.

Example:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh \
  'mutation stageChanges($environmentId: String!, $input: EnvironmentConfig!, $merge: Boolean) {
    environmentStageChanges(environmentId: $environmentId, input: $input, merge: $merge) { id }
  }' \
  '{"environmentId": "ENV_ID", "input": {"services": {"SERVICE_ID": {"build": {"buildCommand": "npm run build"}}}}, "merge": true}'
SCRIPT

Delete Service

Use isDeleted: true:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh \
  'mutation stageChanges($environmentId: String!, $input: EnvironmentConfig!, $merge: Boolean) {
    environmentStageChanges(environmentId: $environmentId, input: $input, merge: $merge) { id }
  }' \
  '{"environmentId": "ENV_ID", "input": {"services": {"SERVICE_ID": {"isDeleted": true}}}, "merge": true}'
SCRIPT

Stage and Apply Immediately

For single changes that should deploy right away, use environmentPatchCommit to stage and apply in one call.

mutation environmentPatchCommit(
  $environmentId: String!
  $patch: EnvironmentConfig
  $commitMessage: String
) {
  environmentPatchCommit(
    environmentId: $environmentId
    patch: $patch
    commitMessage: $commitMessage
  )
}

Example:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh \
  'mutation patchCommit($environmentId: String!, $patch: EnvironmentConfig, $commitMessage: String) {
    environmentPatchCommit(environmentId: $environmentId, patch: $patch, commitMessage: $commitMessage)
  }' \
  '{"environmentId": "ENV_ID", "patch": {"services": {"SERVICE_ID": {"variables": {"API_KEY": {"value": "secret"}}}}}, "commitMessage": "add API_KEY"}'
SCRIPT

When to use: Single change, no need to batch, user wants immediate deployment.

When NOT to use: Multiple related changes to batch, or user says "stage only" / "don't deploy yet".

Apply Staged Changes

Commit staged changes and trigger deployments.

Note: There is no railway apply CLI command. Use the mutation below or direct users to the web UI.

Apply Mutation

Mutation name: environmentPatchCommitStaged

mutation environmentPatchCommitStaged(
  $environmentId: String!
  $message: String
  $skipDeploys: Boolean
) {
  environmentPatchCommitStaged(
    environmentId: $environmentId
    commitMessage: $message
    skipDeploys: $skipDeploys
  )
}

Example:

bash <<'SCRIPT'
${CLAUDE_PLUGIN_ROOT}/skills/lib/railway-api.sh \
  'mutation commitStaged($environmentId: String!, $message: String) {
    environmentPatchCommitStaged(environmentId: $environmentId, commitMessage: $message)
  }' \
  '{"environmentId": "ENV_ID", "message": "add API_KEY variable"}'
SCRIPT

Parameters

FieldTypeDefaultDescription
environmentIdString!-Environment ID from status
messageStringnullShort description of changes
skipDeploysBooleanfalseSkip deploys (only if user explicitly asks)

Commit Message

Keep very short - one sentence max. Examples:

  • "set build command to fix npm error"
  • "add API_KEY variable"
  • "increase replicas to 3"

Leave empty if no meaningful description.

Default Behavior

Always deploy unless user explicitly asks to skip. Only set skipDeploys: true if user says "apply without deploying", "commit but don't deploy", or "skip deploys".

Returns a workflow ID (string) on success.

Auto-Apply Behavior

By default, apply changes immediately.

Flow

Single change: Use environmentPatchCommit to stage and apply in one call.

Multiple changes or batching: Use environmentStageChanges with merge: true for each change, then environmentPatchCommitStaged to apply.

When NOT to Auto-Apply

  • User explicitly says "stage only", "don't deploy yet", or similar
  • User is making multiple related changes that should deploy together

When you don't auto-apply, tell the user:

Changes staged. Apply them at: https://railway.com/project/{projectId} Or ask me to apply them.

Get projectId from railway status --jsonproject.id

Error Handling

Service Not Found

Service "foo" not found in project. Available services: api, web, worker

No Staged Changes

No patch to apply

There are no staged changes to commit. Stage changes first.

Invalid Configuration

Common issues:

  • buildCommand and startCommand cannot be identical
  • buildCommand only valid with NIXPACKS builder
  • dockerfilePath only valid with DOCKERFILE builder

No Permission

You don't have permission to modify this environment. Check your Railway role.

No Linked Project

No project linked. Run `railway link` to link a project.

Composability

  • Create service: Use railway-service skill
  • View logs: Use railway-deployment skill
  • Add domains: Use railway-domain skill
  • Deploy local code: Use railway-deploy skill

Quick Install

/plugin add https://github.com/davila7/claude-code-templates/tree/main/environment

Copy and paste this command in Claude Code to install this skill

GitHub 仓库

davila7/claude-code-templates
Path: cli-tool/components/skills/railway/environment
anthropicanthropic-claudeclaudeclaude-code

Related Skills