@cleocode/cleo 2026.3.4 → 2026.3.7
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/dist/cli/index.js +2277 -609
- package/dist/cli/index.js.map +4 -4
- package/dist/mcp/index.js +1838 -443
- package/dist/mcp/index.js.map +4 -4
- package/package.json +1 -1
- package/packages/ct-skills/index.js +1 -1
- package/packages/ct-skills/package.json +0 -2
- package/packages/ct-skills/profiles/core.json +1 -1
- package/packages/ct-skills/profiles/full.json +4 -5
- package/packages/ct-skills/profiles/minimal.json +3 -3
- package/packages/ct-skills/profiles/recommended.json +2 -2
- package/packages/ct-skills/provider-skills-map.json +97 -0
- package/packages/ct-skills/skills/_shared/skill-chaining-patterns.md +23 -26
- package/packages/ct-skills/skills/_shared/testing-framework-config.md +9 -9
- package/packages/ct-skills/skills/ct-cleo/SKILL.md +21 -1
- package/packages/ct-skills/skills/ct-dev-workflow/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-documentor/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-epic-architect/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-orchestrator/SKILL.md +119 -43
- package/packages/ct-skills/skills/ct-orchestrator/orchestrator-prompt.txt +17 -0
- package/packages/ct-skills/skills/ct-orchestrator/references/orchestrator-patterns.md +1 -1
- package/packages/ct-skills/skills/ct-research-agent/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-spec-writer/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-task-executor/SKILL.md +1 -1
- package/packages/ct-skills/skills/ct-validator/SKILL.md +1 -1
- package/packages/ct-skills/skills/manifest.json +217 -947
- package/packages/ct-skills/skills.json +244 -3
- package/server.json +4 -4
- package/templates/CLEO-INJECTION.md +24 -0
- package/packages/ct-skills/protocols/agent-protocol.md +0 -260
- package/packages/ct-skills/protocols/artifact-publish.md +0 -587
- package/packages/ct-skills/protocols/consensus.md +0 -309
- package/packages/ct-skills/protocols/contribution.md +0 -375
- package/packages/ct-skills/protocols/decomposition.md +0 -352
- package/packages/ct-skills/protocols/implementation.md +0 -344
- package/packages/ct-skills/protocols/provenance.md +0 -600
- package/packages/ct-skills/protocols/release.md +0 -635
- package/packages/ct-skills/protocols/research.md +0 -248
- package/packages/ct-skills/protocols/specification.md +0 -287
- package/packages/ct-skills/protocols/testing.md +0 -346
- package/packages/ct-skills/protocols/validation.md +0 -229
- package/packages/ct-skills/skills/ct-gitbook/SKILL.md +0 -516
- package/packages/ct-skills/skills/ct-gitbook/assets/SUMMARY.md +0 -28
- package/packages/ct-skills/skills/ct-gitbook/assets/gitbook.yaml +0 -14
- package/packages/ct-skills/skills/ct-gitbook/references/api-sdk.md +0 -318
- package/packages/ct-skills/skills/ct-gitbook/references/auth-sso.md +0 -208
- package/packages/ct-skills/skills/ct-gitbook/references/change-requests.md +0 -169
- package/packages/ct-skills/skills/ct-gitbook/references/content-blocks.md +0 -230
- package/packages/ct-skills/skills/ct-gitbook/references/docs-sites.md +0 -202
- package/packages/ct-skills/skills/ct-gitbook/references/git-sync.md +0 -175
- package/packages/ct-skills/skills/ct-gitbook/references/llm-ready.md +0 -178
- package/packages/ct-skills/skills/ct-gitbook/references/migration.md +0 -263
- package/packages/ct-skills/skills/ct-library-implementer-bash/SKILL.md +0 -316
- package/packages/ct-skills/skills/ct-skill-lookup/SKILL.md +0 -179
- package/packages/ct-skills/skills/ct-test-writer-bats/SKILL.md +0 -347
- package/packages/ct-skills/skills/railway-platform/SKILL.md +0 -506
- package/packages/ct-skills/skills/railway-platform/_shared/scripts/railway-api.sh +0 -180
- package/packages/ct-skills/skills/railway-platform/_shared/scripts/railway-common.sh +0 -262
- package/packages/ct-skills/skills/railway-platform/references/01-getting-started.md +0 -149
- package/packages/ct-skills/skills/railway-platform/references/02-projects.md +0 -116
- package/packages/ct-skills/skills/railway-platform/references/03-services.md +0 -147
- package/packages/ct-skills/skills/railway-platform/references/04-deployments.md +0 -210
- package/packages/ct-skills/skills/railway-platform/references/05-databases.md +0 -142
- package/packages/ct-skills/skills/railway-platform/references/06-environments.md +0 -261
- package/packages/ct-skills/skills/railway-platform/references/07-domains.md +0 -139
- package/packages/ct-skills/skills/railway-platform/references/08-volumes.md +0 -533
- package/packages/ct-skills/skills/railway-platform/references/09-networking.md +0 -592
- package/packages/ct-skills/skills/railway-platform/references/10-cron.md +0 -488
- package/packages/ct-skills/skills/railway-platform/references/11-functions.md +0 -170
- package/packages/ct-skills/skills/railway-platform/references/12-monorepo.md +0 -294
- package/packages/ct-skills/skills/railway-platform/references/13-troubleshooting.md +0 -335
- package/packages/ct-skills/skills/railway-platform/references/14-railway-metal.md +0 -197
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
# Domain Management
|
|
2
|
-
|
|
3
|
-
Add custom domains and configure SSL certificates.
|
|
4
|
-
|
|
5
|
-
## Railway Domain (Auto-Generated)
|
|
6
|
-
|
|
7
|
-
### Generate Domain
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
railway domain --json
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Creates `*.up.railway.app` domain automatically.
|
|
14
|
-
|
|
15
|
-
### Service-Specific Domain
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
railway domain --json --service backend
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Custom Domain
|
|
22
|
-
|
|
23
|
-
### Add Domain
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
railway domain example.com --json
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Returns DNS records to configure:
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"domain": "example.com",
|
|
34
|
-
"dnsRecords": [
|
|
35
|
-
{
|
|
36
|
-
"type": "CNAME",
|
|
37
|
-
"host": "@",
|
|
38
|
-
"value": "railway.app"
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Configure DNS
|
|
45
|
-
|
|
46
|
-
Add the DNS records to your provider:
|
|
47
|
-
|
|
48
|
-
**CNAME Record:**
|
|
49
|
-
- Type: CNAME
|
|
50
|
-
- Host: @ or subdomain
|
|
51
|
-
- Value: Provided by Railway
|
|
52
|
-
|
|
53
|
-
### Verify Domain
|
|
54
|
-
|
|
55
|
-
Domains are verified automatically once DNS propagates (can take up to 24 hours).
|
|
56
|
-
|
|
57
|
-
### Wildcard Domains
|
|
58
|
-
|
|
59
|
-
Railway supports wildcard domains:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
railway domain "*.example.com" --json
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Domain Configuration
|
|
66
|
-
|
|
67
|
-
### Via Environment Config
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
source _shared/scripts/railway-api.sh
|
|
71
|
-
|
|
72
|
-
ENV_ID=$(get_environment_id)
|
|
73
|
-
SERVICE_ID=$(get_service_id)
|
|
74
|
-
|
|
75
|
-
# Add custom domain
|
|
76
|
-
railway_api '
|
|
77
|
-
mutation stageChanges($environmentId: String!, $input: EnvironmentConfig!) {
|
|
78
|
-
environmentStageChanges(environmentId: $environmentId, input: $input, merge: true) {
|
|
79
|
-
id
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
' "{\"environmentId\": \"$ENV_ID\", \"input\": {\"services\": {\"$SERVICE_ID\": {\"networking\": {\"customDomains\": {\"new-domain\": {\"domain\": \"example.com\"}}}}}}}"
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Remove Domain
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
source _shared/scripts/railway-api.sh
|
|
89
|
-
|
|
90
|
-
# Remove custom domain
|
|
91
|
-
railway_api '
|
|
92
|
-
mutation stageChanges($environmentId: String!, $input: EnvironmentConfig!) {
|
|
93
|
-
environmentStageChanges(environmentId: $environmentId, input: $input, merge: true) {
|
|
94
|
-
id
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
' "{\"environmentId\": \"$ENV_ID\", \"input\": {\"services\": {\"$SERVICE_ID\": {\"networking\": {\"customDomains\": {\"domain-id\": null}}}}}}"
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## SSL Certificates
|
|
101
|
-
|
|
102
|
-
SSL certificates are automatically provisioned and renewed for all domains.
|
|
103
|
-
|
|
104
|
-
No manual configuration required.
|
|
105
|
-
|
|
106
|
-
## Port Configuration
|
|
107
|
-
|
|
108
|
-
Custom domains connect to the same port as Railway domains (your service's exposed port).
|
|
109
|
-
|
|
110
|
-
## Troubleshooting
|
|
111
|
-
|
|
112
|
-
### Domain Not Verifying
|
|
113
|
-
|
|
114
|
-
**Check DNS propagation:**
|
|
115
|
-
```bash
|
|
116
|
-
nslookup example.com
|
|
117
|
-
dig example.com
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
**Check DNS records:**
|
|
121
|
-
Ensure CNAME points exactly to the value Railway provided.
|
|
122
|
-
|
|
123
|
-
### SSL Certificate Issues
|
|
124
|
-
|
|
125
|
-
Certificates are auto-provisioned. If issues persist:
|
|
126
|
-
1. Check domain DNS is correct
|
|
127
|
-
2. Wait 24 hours for propagation
|
|
128
|
-
3. Contact Railway support
|
|
129
|
-
|
|
130
|
-
### Domain Already in Use
|
|
131
|
-
|
|
132
|
-
If domain is used in another project:
|
|
133
|
-
1. Remove from old project first
|
|
134
|
-
2. Or use different domain/subdomain
|
|
135
|
-
|
|
136
|
-
## Next Steps
|
|
137
|
-
|
|
138
|
-
- [09-networking.md](09-networking.md) - Private networking
|
|
139
|
-
- [13-troubleshooting.md](13-troubleshooting.md) - Advanced debugging
|
|
@@ -1,533 +0,0 @@
|
|
|
1
|
-
# Persistent Volumes
|
|
2
|
-
|
|
3
|
-
Railway volumes provide persistent storage that survives deployments and restarts.
|
|
4
|
-
|
|
5
|
-
## When to Use Volumes
|
|
6
|
-
|
|
7
|
-
**Use volumes for:**
|
|
8
|
-
- Database data persistence
|
|
9
|
-
- File uploads and user content
|
|
10
|
-
- Logs that must survive restarts
|
|
11
|
-
- Configuration files that change at runtime
|
|
12
|
-
- Cache directories that should persist
|
|
13
|
-
|
|
14
|
-
**Don't use volumes for:**
|
|
15
|
-
- Temporary files (use /tmp)
|
|
16
|
-
- Build artifacts
|
|
17
|
-
- Static assets (serve from CDN)
|
|
18
|
-
- Source code
|
|
19
|
-
|
|
20
|
-
## Volume Types
|
|
21
|
-
|
|
22
|
-
### Standard Volume
|
|
23
|
-
|
|
24
|
-
General purpose persistent storage:
|
|
25
|
-
- Mount at any path
|
|
26
|
-
- Survives deployments
|
|
27
|
-
- Tied to service and region
|
|
28
|
-
- Backed up automatically
|
|
29
|
-
|
|
30
|
-
### High-Availability Volume (Pro+)
|
|
31
|
-
|
|
32
|
-
Replicated across multiple zones:
|
|
33
|
-
- Higher durability
|
|
34
|
-
- Automatic failover
|
|
35
|
-
- Available on Pro and Enterprise plans
|
|
36
|
-
|
|
37
|
-
## Creating Volumes
|
|
38
|
-
|
|
39
|
-
### Via CLI
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Create volume
|
|
43
|
-
railway volume add --service my-service
|
|
44
|
-
|
|
45
|
-
# List volumes
|
|
46
|
-
railway volume list --service my-service
|
|
47
|
-
|
|
48
|
-
# Delete volume
|
|
49
|
-
railway volume delete <volume-id>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Via Environment Config
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"services": {
|
|
57
|
-
"my-service": {
|
|
58
|
-
"volumes": {
|
|
59
|
-
"my-volume": {
|
|
60
|
-
"mountPath": "/data"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Mount Points
|
|
69
|
-
|
|
70
|
-
### Common Patterns
|
|
71
|
-
|
|
72
|
-
**Database data:**
|
|
73
|
-
```json
|
|
74
|
-
{
|
|
75
|
-
"volumes": {
|
|
76
|
-
"postgres-data": {
|
|
77
|
-
"mountPath": "/var/lib/postgresql/data"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**File uploads:**
|
|
84
|
-
```json
|
|
85
|
-
{
|
|
86
|
-
"volumes": {
|
|
87
|
-
"uploads": {
|
|
88
|
-
"mountPath": "/app/uploads"
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Logs:**
|
|
95
|
-
```json
|
|
96
|
-
{
|
|
97
|
-
"volumes": {
|
|
98
|
-
"app-logs": {
|
|
99
|
-
"mountPath": "/app/logs"
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Mount Path Requirements
|
|
106
|
-
|
|
107
|
-
- Must be absolute path (starts with /)
|
|
108
|
-
- Cannot mount over system directories (/bin, /etc, etc.)
|
|
109
|
-
- Service must have permission to write to path
|
|
110
|
-
- Single volume can only mount to one path per service
|
|
111
|
-
|
|
112
|
-
## Database Volumes
|
|
113
|
-
|
|
114
|
-
### PostgreSQL with Volume
|
|
115
|
-
|
|
116
|
-
Railway's Postgres template automatically creates a volume. For custom setup:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"services": {
|
|
121
|
-
"postgres": {
|
|
122
|
-
"source": {
|
|
123
|
-
"image": "postgres:15"
|
|
124
|
-
},
|
|
125
|
-
"volumes": {
|
|
126
|
-
"postgres-data": {
|
|
127
|
-
"mountPath": "/var/lib/postgresql/data"
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
"variables": {
|
|
131
|
-
"POSTGRES_DB": {"value": "mydb"},
|
|
132
|
-
"POSTGRES_USER": {"value": "user"},
|
|
133
|
-
"POSTGRES_PASSWORD": {"value": "password", "encrypted": true}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### MongoDB with Volume
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"services": {
|
|
145
|
-
"mongo": {
|
|
146
|
-
"source": {
|
|
147
|
-
"image": "mongo:7"
|
|
148
|
-
},
|
|
149
|
-
"volumes": {
|
|
150
|
-
"mongo-data": {
|
|
151
|
-
"mountPath": "/data/db"
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### MySQL with Volume
|
|
160
|
-
|
|
161
|
-
```json
|
|
162
|
-
{
|
|
163
|
-
"services": {
|
|
164
|
-
"mysql": {
|
|
165
|
-
"source": {
|
|
166
|
-
"image": "mysql:8"
|
|
167
|
-
},
|
|
168
|
-
"volumes": {
|
|
169
|
-
"mysql-data": {
|
|
170
|
-
"mountPath": "/var/lib/mysql"
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Application Volumes
|
|
179
|
-
|
|
180
|
-
### File Upload Service
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
{
|
|
184
|
-
"services": {
|
|
185
|
-
"api": {
|
|
186
|
-
"volumes": {
|
|
187
|
-
"uploads": {
|
|
188
|
-
"mountPath": "/app/public/uploads"
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
"variables": {
|
|
192
|
-
"UPLOAD_DIR": {"value": "/app/public/uploads"}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
**In your application:**
|
|
200
|
-
```javascript
|
|
201
|
-
// Node.js
|
|
202
|
-
const uploadDir = process.env.UPLOAD_DIR || './uploads';
|
|
203
|
-
|
|
204
|
-
// Python
|
|
205
|
-
import os
|
|
206
|
-
upload_dir = os.environ.get('UPLOAD_DIR', './uploads')
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Cache Directory
|
|
210
|
-
|
|
211
|
-
```json
|
|
212
|
-
{
|
|
213
|
-
"services": {
|
|
214
|
-
"worker": {
|
|
215
|
-
"volumes": {
|
|
216
|
-
"cache": {
|
|
217
|
-
"mountPath": "/app/cache"
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Volume Sizing
|
|
226
|
-
|
|
227
|
-
### Default Sizes
|
|
228
|
-
|
|
229
|
-
- **Trial/Hobby:** Up to plan limits
|
|
230
|
-
- **Pro:** Configurable up to 100GB
|
|
231
|
-
- **Enterprise:** Custom limits
|
|
232
|
-
|
|
233
|
-
### Monitor Usage
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
# Check volume usage
|
|
237
|
-
railway metrics --service my-service
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
**Metrics to watch:**
|
|
241
|
-
- `DISK_USAGE_GB` - Current usage
|
|
242
|
-
- Volume approaching limit warnings
|
|
243
|
-
|
|
244
|
-
### Resize Volumes
|
|
245
|
-
|
|
246
|
-
Currently, volumes cannot be resized directly. To increase:
|
|
247
|
-
|
|
248
|
-
1. Create new larger volume
|
|
249
|
-
2. Copy data to new volume
|
|
250
|
-
3. Update service to use new volume
|
|
251
|
-
4. Delete old volume
|
|
252
|
-
|
|
253
|
-
## Volume Backup & Restore
|
|
254
|
-
|
|
255
|
-
### Automatic Backups
|
|
256
|
-
|
|
257
|
-
Railway automatically backs up volumes:
|
|
258
|
-
- Daily snapshots
|
|
259
|
-
- Kept for 7 days (Pro+)
|
|
260
|
-
- Point-in-time recovery
|
|
261
|
-
|
|
262
|
-
### Manual Backup
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# Create snapshot (via API)
|
|
266
|
-
# See railway-api.sh for GraphQL mutations
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Restore from Backup
|
|
270
|
-
|
|
271
|
-
Contact Railway support for restore assistance or use API:
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
# Restore volume (via API)
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
## Multi-Region Considerations
|
|
278
|
-
|
|
279
|
-
### Volume Region Lock
|
|
280
|
-
|
|
281
|
-
Volumes are tied to a specific region:
|
|
282
|
-
- Created in service's primary region
|
|
283
|
-
- Cannot be mounted across regions
|
|
284
|
-
- Service must deploy to volume's region
|
|
285
|
-
|
|
286
|
-
### Regional Deployment
|
|
287
|
-
|
|
288
|
-
```json
|
|
289
|
-
{
|
|
290
|
-
"services": {
|
|
291
|
-
"database": {
|
|
292
|
-
"volumes": {
|
|
293
|
-
"data": {
|
|
294
|
-
"mountPath": "/data"
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
"deploy": {
|
|
298
|
-
"multiRegionConfig": {
|
|
299
|
-
"us-west1": {
|
|
300
|
-
"numReplicas": 1
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Railway Metal Volumes
|
|
310
|
-
|
|
311
|
-
### Stateful Railway Metal
|
|
312
|
-
|
|
313
|
-
Available March 2025 for Railway Metal regions:
|
|
314
|
-
- NVMe SSD storage
|
|
315
|
-
- Faster I/O performance
|
|
316
|
-
- Available for all plan types
|
|
317
|
-
|
|
318
|
-
### Migration
|
|
319
|
-
|
|
320
|
-
Volumes on Railway Metal:
|
|
321
|
-
- Created automatically for new services
|
|
322
|
-
- Existing volumes migrated gradually
|
|
323
|
-
- No action required
|
|
324
|
-
|
|
325
|
-
**See railway-metal reference for migration details.**
|
|
326
|
-
|
|
327
|
-
## Best Practices
|
|
328
|
-
|
|
329
|
-
### 1. Use Descriptive Names
|
|
330
|
-
|
|
331
|
-
**Good:**
|
|
332
|
-
```json
|
|
333
|
-
{
|
|
334
|
-
"volumes": {
|
|
335
|
-
"postgres-production-data": {
|
|
336
|
-
"mountPath": "/var/lib/postgresql/data"
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
**Bad:**
|
|
343
|
-
```json
|
|
344
|
-
{
|
|
345
|
-
"volumes": {
|
|
346
|
-
"vol1": {
|
|
347
|
-
"mountPath": "/data"
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### 2. Mount at Standard Paths
|
|
354
|
-
|
|
355
|
-
Use conventional mount points:
|
|
356
|
-
- `/var/lib/<service>` for databases
|
|
357
|
-
- `/app/data` or `/app/uploads` for applications
|
|
358
|
-
- `/var/log/<app>` for logs
|
|
359
|
-
|
|
360
|
-
### 3. Separate Concerns
|
|
361
|
-
|
|
362
|
-
Use multiple volumes for different data:
|
|
363
|
-
```json
|
|
364
|
-
{
|
|
365
|
-
"volumes": {
|
|
366
|
-
"uploads": {"mountPath": "/app/uploads"},
|
|
367
|
-
"logs": {"mountPath": "/app/logs"},
|
|
368
|
-
"cache": {"mountPath": "/app/cache"}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### 4. Environment Variables
|
|
374
|
-
|
|
375
|
-
Expose volume paths via environment variables:
|
|
376
|
-
```json
|
|
377
|
-
{
|
|
378
|
-
"variables": {
|
|
379
|
-
"DATA_DIR": {"value": "/app/data"},
|
|
380
|
-
"LOG_DIR": {"value": "/app/logs"}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
### 5. Handle Missing Volumes Gracefully
|
|
386
|
-
|
|
387
|
-
**Application code:**
|
|
388
|
-
```javascript
|
|
389
|
-
// Create directory if doesn't exist
|
|
390
|
-
const fs = require('fs');
|
|
391
|
-
const uploadDir = process.env.UPLOAD_DIR;
|
|
392
|
-
if (!fs.existsSync(uploadDir)) {
|
|
393
|
-
fs.mkdirSync(uploadDir, { recursive: true });
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
## Troubleshooting
|
|
398
|
-
|
|
399
|
-
### Volume Not Mounting
|
|
400
|
-
|
|
401
|
-
**Symptom:** Data not persisting between deploys
|
|
402
|
-
|
|
403
|
-
**Check:**
|
|
404
|
-
1. Volume created and attached to service
|
|
405
|
-
2. Mount path is correct
|
|
406
|
-
3. Service writing to correct path
|
|
407
|
-
4. Check `railway status --json` for volume info
|
|
408
|
-
|
|
409
|
-
**Debug:**
|
|
410
|
-
```bash
|
|
411
|
-
# SSH into container
|
|
412
|
-
railway ssh
|
|
413
|
-
|
|
414
|
-
# Check mount
|
|
415
|
-
ls -la /your/mount/path
|
|
416
|
-
df -h
|
|
417
|
-
|
|
418
|
-
# Verify writes
|
|
419
|
-
echo "test" > /your/mount/path/test.txt
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
### Permission Denied
|
|
423
|
-
|
|
424
|
-
**Symptom:** Cannot write to volume
|
|
425
|
-
|
|
426
|
-
**Fix:**
|
|
427
|
-
1. Ensure mount path is writable
|
|
428
|
-
2. Check user permissions in container
|
|
429
|
-
3. Use absolute paths
|
|
430
|
-
|
|
431
|
-
**Dockerfile fix:**
|
|
432
|
-
```dockerfile
|
|
433
|
-
RUN mkdir -p /app/data && chown -R app:app /app/data
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
### Out of Space
|
|
437
|
-
|
|
438
|
-
**Symptom:** Write failures, disk full errors
|
|
439
|
-
|
|
440
|
-
**Solution:**
|
|
441
|
-
1. Check current usage: `railway metrics`
|
|
442
|
-
2. Clean up unnecessary files
|
|
443
|
-
3. Contact support to increase limit (Pro+)
|
|
444
|
-
|
|
445
|
-
### Cross-Region Issues
|
|
446
|
-
|
|
447
|
-
**Symptom:** Volume not accessible
|
|
448
|
-
|
|
449
|
-
**Cause:** Service deployed to different region than volume
|
|
450
|
-
|
|
451
|
-
**Fix:** Deploy service to volume's region or create new volume in target region.
|
|
452
|
-
|
|
453
|
-
## Examples
|
|
454
|
-
|
|
455
|
-
### Complete Database Setup
|
|
456
|
-
|
|
457
|
-
```json
|
|
458
|
-
{
|
|
459
|
-
"services": {
|
|
460
|
-
"postgres": {
|
|
461
|
-
"source": {
|
|
462
|
-
"image": "postgres:15-alpine"
|
|
463
|
-
},
|
|
464
|
-
"volumes": {
|
|
465
|
-
"postgres-data": {
|
|
466
|
-
"mountPath": "/var/lib/postgresql/data"
|
|
467
|
-
}
|
|
468
|
-
},
|
|
469
|
-
"variables": {
|
|
470
|
-
"POSTGRES_DB": {"value": "appdb"},
|
|
471
|
-
"POSTGRES_USER": {"value": "appuser"},
|
|
472
|
-
"POSTGRES_PASSWORD": {"value": "changeme", "encrypted": true},
|
|
473
|
-
"PGDATA": {"value": "/var/lib/postgresql/data/pgdata"}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
### File Storage Service
|
|
481
|
-
|
|
482
|
-
```json
|
|
483
|
-
{
|
|
484
|
-
"services": {
|
|
485
|
-
"file-api": {
|
|
486
|
-
"volumes": {
|
|
487
|
-
"uploads": {
|
|
488
|
-
"mountPath": "/data/uploads"
|
|
489
|
-
}
|
|
490
|
-
},
|
|
491
|
-
"variables": {
|
|
492
|
-
"STORAGE_PATH": {"value": "/data/uploads"},
|
|
493
|
-
"MAX_FILE_SIZE": {"value": "10485760"}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
**Express.js handler:**
|
|
501
|
-
```javascript
|
|
502
|
-
const express = require('express');
|
|
503
|
-
const multer = require('multer');
|
|
504
|
-
const path = require('path');
|
|
505
|
-
|
|
506
|
-
const uploadDir = process.env.STORAGE_PATH || './uploads';
|
|
507
|
-
|
|
508
|
-
const storage = multer.diskStorage({
|
|
509
|
-
destination: uploadDir,
|
|
510
|
-
filename: (req, file, cb) => {
|
|
511
|
-
cb(null, `${Date.now()}-${file.originalname}`);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
const upload = multer({ storage });
|
|
516
|
-
|
|
517
|
-
app.post('/upload', upload.single('file'), (req, res) => {
|
|
518
|
-
res.json({ url: `/files/${req.file.filename}` });
|
|
519
|
-
});
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
## Summary
|
|
523
|
-
|
|
524
|
-
| Aspect | Details |
|
|
525
|
-
|--------|---------|
|
|
526
|
-
| **Use case** | Persistent data, uploads, databases |
|
|
527
|
-
| **Survives** | Deployments, restarts, service updates |
|
|
528
|
-
| **Tied to** | Service and region |
|
|
529
|
-
| **Backup** | Automatic daily snapshots |
|
|
530
|
-
| **Size** | Up to plan limits |
|
|
531
|
-
| **Regions** | Must match service region |
|
|
532
|
-
|
|
533
|
-
**Key point:** Volumes persist data across deployments. Use for anything that must survive service restarts.
|