@tachyon-gg/railway-deploy 0.2.10 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +322 -139
- package/dist/index.js +4323 -2208
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://bun.sh/)
|
|
8
8
|
[](https://biomejs.dev/)
|
|
9
9
|
|
|
10
|
-
Declarative infrastructure management for [Railway](https://railway.com). Define your Railway project's services, variables, domains, volumes, and buckets in YAML, and `railway-deploy` will diff against the live state and apply changes -- like Terraform, but purpose-built for Railway.
|
|
10
|
+
Declarative infrastructure management for [Railway](https://railway.com). Define your Railway project's services, variables, domains, volumes, and buckets in YAML, and `railway-deploy` will diff against the live state and apply changes atomically -- like Terraform, but purpose-built for Railway.
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
@@ -16,21 +16,24 @@ Declarative infrastructure management for [Railway](https://railway.com). Define
|
|
|
16
16
|
npx @tachyon-gg/railway-deploy --help
|
|
17
17
|
|
|
18
18
|
# Validate a config file
|
|
19
|
-
npx @tachyon-gg/railway-deploy --validate
|
|
19
|
+
npx @tachyon-gg/railway-deploy --validate project.yaml
|
|
20
20
|
|
|
21
21
|
# Dry-run (show what would change)
|
|
22
|
-
npx @tachyon-gg/railway-deploy
|
|
22
|
+
npx @tachyon-gg/railway-deploy project.yaml -e production
|
|
23
23
|
|
|
24
24
|
# Apply changes
|
|
25
|
-
npx @tachyon-gg/railway-deploy --apply
|
|
25
|
+
npx @tachyon-gg/railway-deploy --apply -e production project.yaml
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## CLI flags
|
|
29
29
|
|
|
30
30
|
| Flag | Description |
|
|
31
31
|
|------|-------------|
|
|
32
|
+
| `-e, --environment <name>` | Target environment (required except for `--validate`) |
|
|
32
33
|
| `--apply` | Execute changes (default: dry-run) |
|
|
34
|
+
| `--stage` | Stage changes in Railway without committing (preview in dashboard) |
|
|
33
35
|
| `-y, --yes` | Skip confirmation for destructive ops |
|
|
36
|
+
| `--allow-data-loss` | Allow operations that can cause data loss (e.g., volume deletion) |
|
|
34
37
|
| `--env-file <path>` | Load `.env` file for `${VAR}` resolution |
|
|
35
38
|
| `-v, --verbose` | Show detailed diffs (old -> new values) |
|
|
36
39
|
| `--no-color` | Disable ANSI color output |
|
|
@@ -46,111 +49,244 @@ npx @tachyon-gg/railway-deploy --apply environments/production.yaml
|
|
|
46
49
|
|
|
47
50
|
## Config reference
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
Project configs are YAML files describing the desired state of a Railway project across one or more environments. Add schema support to your editor:
|
|
50
53
|
|
|
51
54
|
```yaml
|
|
52
|
-
# yaml-language-server: $schema=./schemas/
|
|
55
|
+
# yaml-language-server: $schema=./schemas/project.schema.json
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
### Top-level
|
|
58
|
+
### Top-level structure
|
|
56
59
|
|
|
57
60
|
```yaml
|
|
58
|
-
project: My Project
|
|
59
|
-
|
|
61
|
+
project: My Project # Railway project name (must match exactly)
|
|
62
|
+
environments: # Environments to manage
|
|
63
|
+
- staging
|
|
64
|
+
- production
|
|
65
|
+
|
|
66
|
+
shared_variables: { ... } # Variables shared across all services
|
|
67
|
+
services: { ... } # Service definitions
|
|
68
|
+
volumes: { ... } # Persistent volume definitions
|
|
69
|
+
buckets: { ... } # S3-compatible bucket definitions
|
|
70
|
+
```
|
|
60
71
|
|
|
61
|
-
|
|
62
|
-
APP_ENV: production
|
|
63
|
-
API_PORT: "8080"
|
|
72
|
+
### Shared variables
|
|
64
73
|
|
|
65
|
-
services
|
|
66
|
-
web: { ... }
|
|
67
|
-
worker: { ... }
|
|
74
|
+
Shared variables are available to all services in an environment. Use the string shorthand for values that are the same everywhere, or the object form for per-environment overrides:
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
```yaml
|
|
77
|
+
shared_variables:
|
|
78
|
+
# String shorthand — same value in all environments
|
|
79
|
+
ADMIN_PORT: "8081"
|
|
80
|
+
PUBLIC_PORT: "8080"
|
|
81
|
+
|
|
82
|
+
# Object form — default value with per-environment overrides
|
|
83
|
+
JWT_SECRET:
|
|
84
|
+
value: ${JWT_SECRET_DEFAULT}
|
|
85
|
+
environments:
|
|
86
|
+
staging:
|
|
87
|
+
value: ${JWT_SECRET_STAGING}
|
|
88
|
+
production:
|
|
89
|
+
value: ${JWT_SECRET_PROD}
|
|
72
90
|
```
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
Supports `${ENV_VAR}` syntax (resolved from your local environment or `--env-file`) and `${{shared.OTHER_VAR}}` self-references.
|
|
75
93
|
|
|
76
|
-
|
|
94
|
+
> **Note:** Shared variables cannot contain `${{service.VAR}}` cross-service references. Railway resolves shared variables without a service context.
|
|
95
|
+
|
|
96
|
+
### Volumes
|
|
97
|
+
|
|
98
|
+
Volumes are declared at the top level with optional per-environment overrides. Services reference them by name.
|
|
77
99
|
|
|
78
100
|
```yaml
|
|
101
|
+
volumes:
|
|
102
|
+
pg-data:
|
|
103
|
+
size_mb: 50000
|
|
104
|
+
region: us-east4
|
|
105
|
+
environments:
|
|
106
|
+
production:
|
|
107
|
+
size_mb: 100000
|
|
108
|
+
|
|
109
|
+
redis-data: {} # Minimal declaration — Railway defaults
|
|
110
|
+
|
|
79
111
|
services:
|
|
80
|
-
|
|
81
|
-
redis:
|
|
112
|
+
postgres:
|
|
82
113
|
source:
|
|
83
|
-
image:
|
|
84
|
-
|
|
85
|
-
|
|
114
|
+
image: postgres:17
|
|
115
|
+
volume: # Reference a declared volume
|
|
116
|
+
name: pg-data
|
|
117
|
+
mount: /var/lib/postgresql/data
|
|
118
|
+
```
|
|
86
119
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
Every volume referenced by a service must be declared in the `volumes` block.
|
|
121
|
+
|
|
122
|
+
### Buckets
|
|
123
|
+
|
|
124
|
+
S3-compatible Railway buckets. The key is the bucket name.
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
buckets:
|
|
128
|
+
media-uploads:
|
|
129
|
+
region: iad
|
|
130
|
+
environments:
|
|
131
|
+
eu-production:
|
|
132
|
+
region: fra
|
|
133
|
+
|
|
134
|
+
logs: {} # Minimal — uses default region
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Services
|
|
138
|
+
|
|
139
|
+
Each service defines defaults that apply to all environments. Per-environment overrides go under `environments.<name>`:
|
|
92
140
|
|
|
93
|
-
|
|
141
|
+
```yaml
|
|
142
|
+
services:
|
|
94
143
|
web:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
144
|
+
source:
|
|
145
|
+
repo: myorg/web-app
|
|
146
|
+
start_command: npm start
|
|
98
147
|
variables:
|
|
99
|
-
|
|
148
|
+
PORT: "3000"
|
|
149
|
+
environments:
|
|
150
|
+
staging:
|
|
151
|
+
source:
|
|
152
|
+
repo: myorg/web-app
|
|
153
|
+
branch: develop
|
|
154
|
+
production:
|
|
155
|
+
source:
|
|
156
|
+
repo: myorg/web-app
|
|
157
|
+
branch: main
|
|
158
|
+
wait_for_ci: true
|
|
159
|
+
|
|
160
|
+
# Service without environments block — exists in all environments
|
|
161
|
+
redis:
|
|
162
|
+
source:
|
|
163
|
+
image: redis:7
|
|
164
|
+
|
|
165
|
+
# Service scoped to specific environments
|
|
166
|
+
debug-tools:
|
|
167
|
+
source:
|
|
168
|
+
image: debug:latest
|
|
169
|
+
environments:
|
|
170
|
+
staging: {} # Only in staging
|
|
100
171
|
```
|
|
101
172
|
|
|
102
|
-
|
|
173
|
+
#### Service scope rules
|
|
174
|
+
|
|
175
|
+
- Service **has** `environments` block -> only exists in environments listed there
|
|
176
|
+
- Service **has no** `environments` block -> exists in ALL declared environments
|
|
177
|
+
|
|
178
|
+
#### Merge rules
|
|
179
|
+
|
|
180
|
+
When a service has per-environment overrides:
|
|
181
|
+
|
|
182
|
+
| Field type | Merge behavior |
|
|
183
|
+
|------------|---------------|
|
|
184
|
+
| `params`, `variables` | Shallow merge (override keys replace defaults) |
|
|
185
|
+
| `domains`, `source`, `volume`, `regions`, `healthcheck`, `build` | Replace entirely |
|
|
186
|
+
| Scalar fields (`start_command`, etc.) | Override replaces |
|
|
187
|
+
|
|
188
|
+
---
|
|
103
189
|
|
|
104
|
-
|
|
190
|
+
### Service fields reference
|
|
191
|
+
|
|
192
|
+
Every field below can be used on service defaults, per-environment overrides, and templates.
|
|
105
193
|
|
|
106
194
|
#### Source
|
|
107
195
|
|
|
196
|
+
Source is a discriminated union — use **either** `repo` or `image`, not both.
|
|
197
|
+
|
|
108
198
|
```yaml
|
|
199
|
+
# Repo source — deploy from a GitHub repository
|
|
109
200
|
source:
|
|
110
|
-
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
check_suites: true # Wait for GitHub Actions to pass before deploying
|
|
201
|
+
repo: myorg/my-repo
|
|
202
|
+
branch: main # Branch to deploy from
|
|
203
|
+
root_directory: /packages/api # Root directory (monorepo support)
|
|
204
|
+
wait_for_ci: true # Wait for GitHub Actions to pass before deploying
|
|
205
|
+
```
|
|
116
206
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
207
|
+
```yaml
|
|
208
|
+
# Image source — deploy from a container image
|
|
209
|
+
source:
|
|
210
|
+
image: nginx:latest # Docker image (Docker Hub, GHCR, etc.)
|
|
211
|
+
registry_credentials: # For private container registries
|
|
212
|
+
username: ${REGISTRY_USER}
|
|
213
|
+
password: ${REGISTRY_PASS}
|
|
214
|
+
auto_updates: # Auto-update schedule for image-based services
|
|
215
|
+
monday:
|
|
216
|
+
start_hour: 0
|
|
217
|
+
end_hour: 6
|
|
218
|
+
friday:
|
|
219
|
+
start_hour: 0
|
|
220
|
+
end_hour: 6
|
|
120
221
|
```
|
|
121
222
|
|
|
122
223
|
#### Build
|
|
123
224
|
|
|
225
|
+
Build is a discriminated union — fields depend on the `builder` value.
|
|
226
|
+
|
|
124
227
|
```yaml
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
watch_patterns:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
railway_config_file: railway.toml # Path to railway.json/toml for config-as-code
|
|
133
|
-
metal: true # Enable Railway Metal builds (service-level, see note below)
|
|
228
|
+
# Railpack (default)
|
|
229
|
+
build:
|
|
230
|
+
builder: railpack
|
|
231
|
+
command: npm run build # Custom build command
|
|
232
|
+
watch_patterns: # File patterns that trigger deploys
|
|
233
|
+
- /packages/api/src/**
|
|
234
|
+
metal: true # Enable Metal build environment (faster builds)
|
|
134
235
|
```
|
|
135
236
|
|
|
136
|
-
|
|
237
|
+
```yaml
|
|
238
|
+
# Nixpacks
|
|
239
|
+
build:
|
|
240
|
+
builder: nixpacks
|
|
241
|
+
command: npm run build
|
|
242
|
+
watch_patterns:
|
|
243
|
+
- /packages/api/src/**
|
|
244
|
+
metal: true
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
# Dockerfile
|
|
249
|
+
build:
|
|
250
|
+
builder: dockerfile
|
|
251
|
+
dockerfile_path: Dockerfile.prod # Path to Dockerfile
|
|
252
|
+
watch_patterns:
|
|
253
|
+
- /packages/api/src/**
|
|
254
|
+
metal: true
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`railway_config_file` is a separate service-level field (not part of `build`):
|
|
258
|
+
|
|
259
|
+
```yaml
|
|
260
|
+
railway_config_file: railway.toml # Path to railway.json/toml in the repository
|
|
261
|
+
```
|
|
137
262
|
|
|
138
263
|
#### Deploy
|
|
139
264
|
|
|
140
265
|
```yaml
|
|
141
|
-
start_command: npm start
|
|
142
|
-
|
|
266
|
+
start_command: npm start # Custom start command
|
|
267
|
+
|
|
268
|
+
pre_deploy_command: # Run before deployment (e.g., migrations)
|
|
143
269
|
- npm run migrate
|
|
144
270
|
- npm run seed
|
|
145
|
-
|
|
146
|
-
|
|
271
|
+
|
|
272
|
+
cron_schedule: "*/5 * * * *" # Cron schedule (5-field format)
|
|
273
|
+
# Note: cron forces restart_policy to NEVER
|
|
274
|
+
# and disables serverless
|
|
275
|
+
|
|
276
|
+
healthcheck: # HTTP healthcheck
|
|
147
277
|
path: /health
|
|
148
|
-
timeout: 300
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
278
|
+
timeout: 300 # Timeout in seconds (default: 300)
|
|
279
|
+
|
|
280
|
+
# Restart policy — string shorthand or object with max_retries
|
|
281
|
+
restart_policy: always # always, never, or on_failure
|
|
282
|
+
|
|
283
|
+
restart_policy: # Object form for on_failure with retries
|
|
284
|
+
type: on_failure
|
|
285
|
+
max_retries: 5
|
|
286
|
+
|
|
287
|
+
serverless: true # Enable serverless sleeping (scale to zero when idle)
|
|
288
|
+
draining_seconds: 30 # Graceful shutdown timeout (SIGTERM to SIGKILL)
|
|
289
|
+
overlap_seconds: 10 # Blue-green deploy overlap duration
|
|
154
290
|
```
|
|
155
291
|
|
|
156
292
|
#### Networking
|
|
@@ -158,31 +294,35 @@ overlap_seconds: 10 # Blue-green deploy overlap duration
|
|
|
158
294
|
```yaml
|
|
159
295
|
# Custom domains
|
|
160
296
|
domains:
|
|
161
|
-
- app.example.com
|
|
162
|
-
- domain: api.example.com
|
|
297
|
+
- app.example.com # Simple domain
|
|
298
|
+
- domain: api.example.com # Domain with target port
|
|
163
299
|
target_port: 8080
|
|
164
300
|
|
|
165
|
-
# Railway-provided domain
|
|
166
|
-
railway_domain:
|
|
167
|
-
railway_domain: # ...with a specific target port
|
|
301
|
+
# Railway-provided domain (*.up.railway.app)
|
|
302
|
+
railway_domain:
|
|
168
303
|
target_port: 3000
|
|
169
304
|
|
|
170
|
-
# TCP
|
|
171
|
-
|
|
305
|
+
# TCP proxy (for non-HTTP services like databases)
|
|
306
|
+
tcp_proxy: 5432
|
|
307
|
+
|
|
308
|
+
# Private networking
|
|
309
|
+
private_hostname: postgres # Internal DNS hostname for service-to-service communication
|
|
172
310
|
|
|
173
311
|
# Outbound networking
|
|
174
|
-
ipv6_egress: true
|
|
175
|
-
static_outbound_ips: true
|
|
312
|
+
ipv6_egress: true # Enable IPv6 outbound traffic
|
|
313
|
+
static_outbound_ips: true # Assign permanent outbound IP addresses
|
|
176
314
|
```
|
|
177
315
|
|
|
178
316
|
#### Scaling
|
|
179
317
|
|
|
180
318
|
```yaml
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
319
|
+
regions: us-east4 # Single region (1 replica)
|
|
320
|
+
# or
|
|
321
|
+
regions: # Multi-region with replica counts
|
|
322
|
+
us-east4: 3
|
|
323
|
+
us-west1: 1
|
|
184
324
|
|
|
185
|
-
limits:
|
|
325
|
+
limits: # Resource limits per replica
|
|
186
326
|
memory_gb: 8
|
|
187
327
|
vcpus: 4
|
|
188
328
|
```
|
|
@@ -190,9 +330,9 @@ limits: # Resource limits per replica
|
|
|
190
330
|
#### Storage
|
|
191
331
|
|
|
192
332
|
```yaml
|
|
193
|
-
volume:
|
|
194
|
-
|
|
195
|
-
|
|
333
|
+
volume: # Reference a top-level volume
|
|
334
|
+
name: pg-data # Must match a key in the volumes block
|
|
335
|
+
mount: /var/lib/postgresql/data # Absolute mount path
|
|
196
336
|
```
|
|
197
337
|
|
|
198
338
|
#### Variables
|
|
@@ -215,25 +355,17 @@ variables:
|
|
|
215
355
|
| `%{service_name}` | At config load time | Built-in: the service's config key |
|
|
216
356
|
| `null` | N/A | Marks a variable for deletion |
|
|
217
357
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
`%{param}` is expanded first, so it can be used inside `${{}}` Railway references. This is useful for templates that need to reference their own or other services' variables:
|
|
358
|
+
`%{param}` is expanded first, so it can be used inside `${{}}` Railway references:
|
|
221
359
|
|
|
222
360
|
```yaml
|
|
223
361
|
variables:
|
|
224
|
-
# Reference own service's variable (resolves %{service_name} at config time,
|
|
225
|
-
# Railway resolves the ${{}} reference at runtime)
|
|
226
362
|
DATABASE_URL: ${{%{service_name}.DATABASE_URL}}
|
|
227
|
-
|
|
228
|
-
# Reference another service by param
|
|
229
363
|
REDIS_URL: ${{%{cache_service}.REDIS_URL}}
|
|
230
364
|
```
|
|
231
365
|
|
|
232
366
|
### Service templates
|
|
233
367
|
|
|
234
|
-
Templates extract reusable service definitions with parameterized values.
|
|
235
|
-
|
|
236
|
-
The built-in `%{service_name}` param is always available and resolves to the service's key in the config (e.g., `web`, `api`). It cannot be overridden.
|
|
368
|
+
Templates extract reusable service definitions with parameterized values. The built-in `%{service_name}` param resolves to the service's key in the config.
|
|
237
369
|
|
|
238
370
|
```yaml
|
|
239
371
|
# services/web.yaml
|
|
@@ -258,105 +390,156 @@ healthcheck:
|
|
|
258
390
|
path: /health
|
|
259
391
|
timeout: 300
|
|
260
392
|
|
|
261
|
-
|
|
262
|
-
region: us-east-1
|
|
263
|
-
num_replicas: 1
|
|
393
|
+
regions: us-east4
|
|
264
394
|
```
|
|
265
395
|
|
|
266
|
-
Referenced from
|
|
396
|
+
Referenced from a project config:
|
|
267
397
|
|
|
268
398
|
```yaml
|
|
269
399
|
services:
|
|
270
400
|
web:
|
|
271
|
-
template:
|
|
401
|
+
template: services/web.yaml
|
|
272
402
|
params:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
403
|
+
replicas: "1"
|
|
404
|
+
environments:
|
|
405
|
+
staging:
|
|
406
|
+
params:
|
|
407
|
+
tag: alpha
|
|
408
|
+
production:
|
|
409
|
+
params:
|
|
410
|
+
tag: v2.0.0
|
|
411
|
+
replicas: "3"
|
|
412
|
+
variables:
|
|
413
|
+
EXTRA: added-by-env
|
|
414
|
+
APP_VERSION: null # Deletes the template-defined variable
|
|
415
|
+
domains:
|
|
416
|
+
- production.example.com # Overrides template domains
|
|
280
417
|
```
|
|
281
418
|
|
|
282
|
-
Template override precedence: environment config values override template values for `source`, `domains`, and `variables`.
|
|
283
|
-
|
|
284
419
|
### Complete example
|
|
285
420
|
|
|
286
421
|
```yaml
|
|
287
|
-
# yaml-language-server: $schema=./schemas/
|
|
422
|
+
# yaml-language-server: $schema=./schemas/project.schema.json
|
|
288
423
|
project: My SaaS App
|
|
289
|
-
|
|
424
|
+
environments:
|
|
425
|
+
- staging
|
|
426
|
+
- production
|
|
290
427
|
|
|
291
428
|
shared_variables:
|
|
292
|
-
|
|
293
|
-
SENTRY_DSN:
|
|
429
|
+
APP_PORT: "3000"
|
|
430
|
+
SENTRY_DSN:
|
|
431
|
+
value: ${SENTRY_DSN_DEFAULT}
|
|
432
|
+
environments:
|
|
433
|
+
production:
|
|
434
|
+
value: ${SENTRY_DSN_PROD}
|
|
435
|
+
|
|
436
|
+
volumes:
|
|
437
|
+
pg-data:
|
|
438
|
+
size_mb: 50000
|
|
439
|
+
environments:
|
|
440
|
+
production:
|
|
441
|
+
size_mb: 200000
|
|
442
|
+
redis-data: {}
|
|
443
|
+
|
|
444
|
+
buckets:
|
|
445
|
+
uploads:
|
|
446
|
+
region: iad
|
|
294
447
|
|
|
295
448
|
services:
|
|
296
449
|
web:
|
|
297
450
|
source:
|
|
298
451
|
repo: myorg/web-app
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
452
|
+
root_directory: /packages/web
|
|
453
|
+
build:
|
|
454
|
+
builder: nixpacks
|
|
455
|
+
command: npm run build
|
|
456
|
+
metal: true
|
|
303
457
|
start_command: npm start
|
|
304
|
-
root_directory: /packages/web
|
|
305
458
|
pre_deploy_command: npm run migrate
|
|
306
459
|
healthcheck:
|
|
307
460
|
path: /health
|
|
308
461
|
timeout: 60
|
|
309
|
-
restart_policy:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
railway_domain: true
|
|
316
|
-
region:
|
|
317
|
-
region: us-east-1
|
|
318
|
-
num_replicas: 2
|
|
319
|
-
limits:
|
|
320
|
-
memory_gb: 4
|
|
321
|
-
vcpus: 2
|
|
462
|
+
restart_policy:
|
|
463
|
+
type: on_failure
|
|
464
|
+
max_retries: 5
|
|
465
|
+
serverless: true
|
|
466
|
+
railway_domain:
|
|
467
|
+
target_port: 3000
|
|
322
468
|
variables:
|
|
323
469
|
PORT: "3000"
|
|
324
470
|
DATABASE_URL: ${{Postgres.DATABASE_URL}}
|
|
471
|
+
environments:
|
|
472
|
+
staging:
|
|
473
|
+
source:
|
|
474
|
+
repo: myorg/web-app
|
|
475
|
+
branch: develop
|
|
476
|
+
domains:
|
|
477
|
+
- staging.example.com
|
|
478
|
+
production:
|
|
479
|
+
source:
|
|
480
|
+
repo: myorg/web-app
|
|
481
|
+
branch: main
|
|
482
|
+
wait_for_ci: true
|
|
483
|
+
domains:
|
|
484
|
+
- app.example.com
|
|
485
|
+
- domain: api.example.com
|
|
486
|
+
target_port: 8080
|
|
487
|
+
regions:
|
|
488
|
+
us-east4: 2
|
|
489
|
+
limits:
|
|
490
|
+
memory_gb: 4
|
|
491
|
+
vcpus: 2
|
|
325
492
|
|
|
326
493
|
postgres:
|
|
327
494
|
source:
|
|
328
|
-
image: postgres:
|
|
495
|
+
image: postgres:17
|
|
496
|
+
private_hostname: postgres
|
|
329
497
|
volume:
|
|
330
|
-
mount: /var/lib/postgresql/data
|
|
331
498
|
name: pg-data
|
|
332
|
-
|
|
499
|
+
mount: /var/lib/postgresql/data
|
|
500
|
+
tcp_proxy: 5432
|
|
333
501
|
variables:
|
|
334
502
|
POSTGRES_DB: myapp
|
|
335
503
|
|
|
336
504
|
redis:
|
|
337
505
|
source:
|
|
338
506
|
image: redis:7-alpine
|
|
507
|
+
private_hostname: redis
|
|
339
508
|
volume:
|
|
340
|
-
mount: /data
|
|
341
509
|
name: redis-data
|
|
342
|
-
|
|
510
|
+
mount: /data
|
|
511
|
+
tcp_proxy: 6379
|
|
343
512
|
|
|
344
513
|
worker:
|
|
345
|
-
template:
|
|
514
|
+
template: services/worker.yaml
|
|
346
515
|
params:
|
|
347
516
|
queue: default
|
|
348
|
-
|
|
517
|
+
serverless: false
|
|
349
518
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
519
|
+
cron:
|
|
520
|
+
source:
|
|
521
|
+
repo: myorg/web-app
|
|
522
|
+
root_directory: /packages/cron
|
|
523
|
+
cron_schedule: "0 0 * * *"
|
|
524
|
+
start_command: node scripts/cleanup.js
|
|
353
525
|
```
|
|
354
526
|
|
|
527
|
+
## Known limitations
|
|
528
|
+
|
|
529
|
+
- **Region management.** Setting `regions` deploys to those regions. Railway always maintains at least one region — the last region cannot be removed. Changing regions is supported (old regions are removed and new ones added). Multi-region is supported via a map of region to replica count.
|
|
530
|
+
- **Service groups** are read-only. Railway's public API does not expose group creation -- groups can only be managed via the Railway dashboard. Existing groups are respected when reading config.
|
|
531
|
+
- **Custom domains** may require DNS verification to take effect.
|
|
532
|
+
- **Registry credentials** are write-only. Railway never returns credentials in config responses, so removal of registry credentials from your config is not detectable -- we simply stop sending them.
|
|
533
|
+
- **Static outbound IPs** are managed via a separate API call (not atomic with the config patch). If the patch succeeds but the egress call fails, IPs may not be configured.
|
|
534
|
+
- **Volume size/region** can only be set or increased, not cleared or reduced. Railway does not support shrinking volumes.
|
|
535
|
+
- **Volume mount removal** is supported via the `volumeDelete` mutation and requires the `--allow-data-loss` flag, since it permanently deletes the volume and its data.
|
|
536
|
+
- **Bucket deletion** is not supported by Railway's API. Buckets that are removed from config will be left in place with a warning.
|
|
537
|
+
|
|
355
538
|
## JSON schemas
|
|
356
539
|
|
|
357
540
|
Editor support (autocompletion, validation) is available via JSON schemas:
|
|
358
541
|
|
|
359
|
-
- `schemas/
|
|
542
|
+
- `schemas/project.schema.json` -- project config files
|
|
360
543
|
- `schemas/service-template.schema.json` -- service template files
|
|
361
544
|
|
|
362
545
|
## Development
|