@icarusmx/creta 1.5.3 → 1.5.6
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/bin/creta.js +14 -4
- package/lib/builders/MenuBuilder.js +23 -4
- package/lib/executors/ExercisesExecutor.js +271 -0
- package/lib/exercises/array-object-manipulation.md +1281 -0
- package/lib/exercises/git-stash-workflow.md +426 -0
- package/lib/exercises/railway-deployment.md +1185 -0
- package/lib/papers/bitcoin/bitcoin.md +92 -0
- package/lib/papers/mapreduce/mapreduce.md +476 -0
- package/lib/papers/spark/spark.md +49 -0
- package/package.json +5 -1
- package/ascii-logo.txt +0 -8
- package/codex-refactor.txt +0 -13
- package/docs/diagrams/README.md +0 -131
- package/docs/diagrams/architecture-overview.mmd +0 -71
- package/docs/diagrams/architecture.svg +0 -1
- package/docs/diagrams/ecosystem-integration.mmd +0 -49
- package/docs/diagrams/evolution-phases.mmd +0 -49
- package/docs/diagrams/output.svg +0 -1
- package/docs/diagrams/phase2-command-help-flow.mmd +0 -51
- package/docs/diagrams/user-journey.mmd +0 -78
- package/ejemplo.sh +0 -3
- package/refactor.txt +0 -581
- package/templates/sveltekit-portfolio/package.json +0 -20
- package/templates/sveltekit-portfolio/src/app.css +0 -51
- package/templates/sveltekit-portfolio/src/app.html +0 -12
- package/templates/sveltekit-portfolio/src/routes/+layout.svelte +0 -108
- package/templates/sveltekit-portfolio/src/routes/+page.svelte +0 -79
- package/templates/sveltekit-portfolio/static/favicon.png +0 -0
- package/templates/sveltekit-portfolio/svelte.config.js +0 -10
- package/templates/sveltekit-portfolio/vite.config.js +0 -10
- package/test/enunciados.test.js +0 -72
- package/test/sintaxis-menu.test.js +0 -45
- package/wea-fome-qlia.sh +0 -92
|
@@ -0,0 +1,1185 @@
|
|
|
1
|
+
# Railway Deployment Guide - Node.js Apps
|
|
2
|
+
|
|
3
|
+
<!-- vim: set foldmethod=marker foldlevel=0: -->
|
|
4
|
+
|
|
5
|
+
## 📖 LazyVim Reading Guide {{{
|
|
6
|
+
|
|
7
|
+
**Start with:** `zM` (close all folds) → Navigate with `za` (toggle fold under cursor)
|
|
8
|
+
|
|
9
|
+
This document uses fold markers `{{{` and `}}}` for organized reading.
|
|
10
|
+
|
|
11
|
+
**Navigation Tips:**
|
|
12
|
+
- `zM` - Close all folds (see just section headers)
|
|
13
|
+
- `zR` - Open all folds (see everything)
|
|
14
|
+
- `za` - Toggle current fold
|
|
15
|
+
- `zj` - Jump to next fold
|
|
16
|
+
- `zk` - Jump to previous fold
|
|
17
|
+
|
|
18
|
+
}}}
|
|
19
|
+
|
|
20
|
+
## 🎯 What You'll Learn {{{
|
|
21
|
+
|
|
22
|
+
This guide covers the complete Railway deployment workflow for Node.js applications:
|
|
23
|
+
|
|
24
|
+
1. **Initial Setup** - Install CLI, authenticate, initialize project
|
|
25
|
+
2. **Deploy Node.js/Express** - From local dev to production deployment
|
|
26
|
+
3. **Environment Variables** - Manage secrets and configuration
|
|
27
|
+
4. **Custom Domains** - Set up domains, DNS, and SSL certificates
|
|
28
|
+
|
|
29
|
+
**Prerequisites:**
|
|
30
|
+
- Node.js and npm installed
|
|
31
|
+
- Git knowledge (basic commands)
|
|
32
|
+
- A Node.js/Express app to deploy (or use example provided)
|
|
33
|
+
- Railway account (free tier available at railway.app)
|
|
34
|
+
|
|
35
|
+
**Time to complete:** 30-45 minutes
|
|
36
|
+
|
|
37
|
+
}}}
|
|
38
|
+
|
|
39
|
+
## 🚂 Part 1: Initial Setup {{{
|
|
40
|
+
|
|
41
|
+
### Install Railway CLI {{{
|
|
42
|
+
|
|
43
|
+
**macOS/Linux:**
|
|
44
|
+
```bash
|
|
45
|
+
# Using Homebrew (recommended for macOS)
|
|
46
|
+
brew install railway
|
|
47
|
+
|
|
48
|
+
# Or using npm (cross-platform)
|
|
49
|
+
npm install -g @railway/cli
|
|
50
|
+
|
|
51
|
+
# Verify installation
|
|
52
|
+
railway --version
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Expected output:**
|
|
56
|
+
```
|
|
57
|
+
railway version 3.5.0
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Windows:**
|
|
61
|
+
```bash
|
|
62
|
+
# Using npm
|
|
63
|
+
npm install -g @railway/cli
|
|
64
|
+
|
|
65
|
+
# Or using Scoop
|
|
66
|
+
scoop install railway
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**LazyVim Tip:** Open a floating terminal to run commands while reading:
|
|
70
|
+
- `<leader>ft` - Open floating terminal
|
|
71
|
+
- `<C-\><C-n>` - Exit terminal insert mode (go to Normal mode)
|
|
72
|
+
- `<C-w>w` - Cycle between terminal and guide
|
|
73
|
+
- `i` - Back to terminal insert mode (type commands)
|
|
74
|
+
|
|
75
|
+
}}}
|
|
76
|
+
|
|
77
|
+
### Login and Authentication {{{
|
|
78
|
+
|
|
79
|
+
**Step 1: Login via browser**
|
|
80
|
+
```bash
|
|
81
|
+
railway login
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**What happens:**
|
|
85
|
+
1. Opens browser to Railway login page
|
|
86
|
+
2. Authenticate with GitHub/Google/Email
|
|
87
|
+
3. CLI receives access token
|
|
88
|
+
4. Token stored in `~/.railway/config.json`
|
|
89
|
+
|
|
90
|
+
**Expected output:**
|
|
91
|
+
```
|
|
92
|
+
🚝 Logging in...
|
|
93
|
+
✓ Logged in as your-email@example.com
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Verify authentication:**
|
|
97
|
+
```bash
|
|
98
|
+
railway whoami
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Output:**
|
|
102
|
+
```
|
|
103
|
+
Logged in as: Your Name (your-email@example.com)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Troubleshooting:**
|
|
107
|
+
- If browser doesn't open: `railway login --browserless`
|
|
108
|
+
- Manual token: Get from railway.app/account/tokens
|
|
109
|
+
|
|
110
|
+
}}}
|
|
111
|
+
|
|
112
|
+
### Initialize Project {{{
|
|
113
|
+
|
|
114
|
+
**Two ways to start:**
|
|
115
|
+
|
|
116
|
+
#### Option 1: Link Existing Railway Project
|
|
117
|
+
```bash
|
|
118
|
+
# If you already created a project on Railway dashboard
|
|
119
|
+
cd your-app-directory
|
|
120
|
+
railway link
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Interactive prompt:**
|
|
124
|
+
```
|
|
125
|
+
Select a project:
|
|
126
|
+
> my-express-api
|
|
127
|
+
my-portfolio-site
|
|
128
|
+
test-project
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Option 2: Create New Project from CLI
|
|
132
|
+
```bash
|
|
133
|
+
cd your-app-directory
|
|
134
|
+
railway init
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Prompts you'll see:**
|
|
138
|
+
```
|
|
139
|
+
Enter project name: my-express-api
|
|
140
|
+
Select environment: production
|
|
141
|
+
✓ Project created: my-express-api
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Verify project setup:**
|
|
145
|
+
```bash
|
|
146
|
+
railway status
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Output:**
|
|
150
|
+
```
|
|
151
|
+
Project: my-express-api
|
|
152
|
+
Environment: production
|
|
153
|
+
Service: Not deployed yet
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**LazyVim Workflow:**
|
|
157
|
+
- Use `<leader>/` to search "railway init" in this file
|
|
158
|
+
- Press `n` to jump to next occurrence
|
|
159
|
+
- Press `N` to go back
|
|
160
|
+
|
|
161
|
+
}}}
|
|
162
|
+
|
|
163
|
+
### Understanding Railway Project Structure {{{
|
|
164
|
+
|
|
165
|
+
**After initialization, Railway creates:**
|
|
166
|
+
```
|
|
167
|
+
your-app/
|
|
168
|
+
├── .railway/ # Railway metadata (gitignored)
|
|
169
|
+
│ └── config.json # Project/service mapping
|
|
170
|
+
├── railway.json # Deployment configuration (optional)
|
|
171
|
+
├── railway.toml # Alternative config format (optional)
|
|
172
|
+
└── your app files...
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Important:**
|
|
176
|
+
- `.railway/` is automatically added to `.gitignore`
|
|
177
|
+
- `railway.json` defines build/deploy settings (we'll create this next)
|
|
178
|
+
|
|
179
|
+
}}}
|
|
180
|
+
|
|
181
|
+
}}}
|
|
182
|
+
|
|
183
|
+
## 🚀 Part 2: Deploy Node.js/Express Apps {{{
|
|
184
|
+
|
|
185
|
+
### Prepare Your Express App {{{
|
|
186
|
+
|
|
187
|
+
**Example Express App Structure:**
|
|
188
|
+
```
|
|
189
|
+
my-express-api/
|
|
190
|
+
├── package.json
|
|
191
|
+
├── index.js # or server.js
|
|
192
|
+
├── .env # Local env vars (gitignored)
|
|
193
|
+
├── .gitignore
|
|
194
|
+
└── README.md
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Minimal Express App (index.js):**
|
|
198
|
+
```javascript
|
|
199
|
+
import express from 'express'
|
|
200
|
+
|
|
201
|
+
const app = express()
|
|
202
|
+
const PORT = process.env.PORT || 3000
|
|
203
|
+
|
|
204
|
+
app.get('/', (req, res) => {
|
|
205
|
+
res.json({ message: 'Hello from Railway!' })
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
app.get('/health', (req, res) => {
|
|
209
|
+
res.json({ status: 'ok', timestamp: new Date() })
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
app.listen(PORT, () => {
|
|
213
|
+
console.log(`Server running on port ${PORT}`)
|
|
214
|
+
})
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**package.json Requirements:**
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"name": "my-express-api",
|
|
221
|
+
"type": "module",
|
|
222
|
+
"scripts": {
|
|
223
|
+
"start": "node index.js",
|
|
224
|
+
"dev": "node --watch index.js"
|
|
225
|
+
},
|
|
226
|
+
"dependencies": {
|
|
227
|
+
"express": "^4.18.2"
|
|
228
|
+
},
|
|
229
|
+
"engines": {
|
|
230
|
+
"node": ">=18.0.0"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Critical: Specify `start` script!** Railway runs `npm start` by default.
|
|
236
|
+
|
|
237
|
+
**LazyVim Tip:** Use `gf` (go to file) on `"./index.js"` to quickly navigate to that file.
|
|
238
|
+
|
|
239
|
+
}}}
|
|
240
|
+
|
|
241
|
+
### Create railway.json Config {{{
|
|
242
|
+
|
|
243
|
+
**Purpose:** Define build and deployment behavior explicitly.
|
|
244
|
+
|
|
245
|
+
**Create `railway.json` in project root:**
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"$schema": "https://railway.app/railway.schema.json",
|
|
249
|
+
"build": {
|
|
250
|
+
"builder": "NIXPACKS",
|
|
251
|
+
"buildCommand": "npm install"
|
|
252
|
+
},
|
|
253
|
+
"deploy": {
|
|
254
|
+
"startCommand": "npm start",
|
|
255
|
+
"restartPolicyType": "ON_FAILURE",
|
|
256
|
+
"restartPolicyMaxRetries": 3
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Configuration explained:**
|
|
262
|
+
|
|
263
|
+
| Field | Purpose | Options |
|
|
264
|
+
|-------|---------|---------|
|
|
265
|
+
| `builder` | Build system | `NIXPACKS` (auto-detect), `DOCKERFILE` (use Dockerfile) |
|
|
266
|
+
| `buildCommand` | Install dependencies | `npm install`, `npm ci`, `pnpm install` |
|
|
267
|
+
| `startCommand` | Run the app | `npm start`, `node index.js` |
|
|
268
|
+
| `restartPolicyType` | When to restart | `ON_FAILURE`, `ALWAYS`, `NEVER` |
|
|
269
|
+
|
|
270
|
+
**Advanced: Multiple environments:**
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"environments": {
|
|
274
|
+
"production": {
|
|
275
|
+
"deploy": {
|
|
276
|
+
"startCommand": "npm start"
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"staging": {
|
|
280
|
+
"deploy": {
|
|
281
|
+
"startCommand": "npm run start:staging"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**LazyVim Editing:**
|
|
289
|
+
- `ci{` - Change inside braces (replace JSON value)
|
|
290
|
+
- `va{` - Select entire object (visual select around braces)
|
|
291
|
+
|
|
292
|
+
}}}
|
|
293
|
+
|
|
294
|
+
### Deploy with railway up {{{
|
|
295
|
+
|
|
296
|
+
**The magic command:**
|
|
297
|
+
```bash
|
|
298
|
+
railway up
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**What happens (step by step):**
|
|
302
|
+
```
|
|
303
|
+
1. 📦 Creating deployment...
|
|
304
|
+
2. 🔨 Building application...
|
|
305
|
+
- Detecting build system: Nixpacks
|
|
306
|
+
- Installing dependencies: npm install
|
|
307
|
+
- Running build command (if specified)
|
|
308
|
+
3. 🚀 Deploying...
|
|
309
|
+
- Creating container
|
|
310
|
+
- Starting service
|
|
311
|
+
- Assigning public URL
|
|
312
|
+
4. ✓ Deployment successful!
|
|
313
|
+
- URL: https://my-express-api-production.up.railway.app
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Expected output:**
|
|
317
|
+
```
|
|
318
|
+
⚡ Deploying...
|
|
319
|
+
✓ Build successful
|
|
320
|
+
✓ Deployment live at https://my-express-api-production.up.railway.app
|
|
321
|
+
|
|
322
|
+
Deployment ID: d3pl0ym3nt-1234
|
|
323
|
+
Service: my-express-api
|
|
324
|
+
Environment: production
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**Verify deployment:**
|
|
328
|
+
```bash
|
|
329
|
+
# Open in browser
|
|
330
|
+
railway open
|
|
331
|
+
|
|
332
|
+
# Or curl the health endpoint
|
|
333
|
+
curl https://your-app.up.railway.app/health
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**First-time deployment:**
|
|
337
|
+
- Usually takes 2-5 minutes
|
|
338
|
+
- Subsequent deploys are faster (cached layers)
|
|
339
|
+
|
|
340
|
+
}}}
|
|
341
|
+
|
|
342
|
+
### Monitor Logs and Debugging {{{
|
|
343
|
+
|
|
344
|
+
**View live logs:**
|
|
345
|
+
```bash
|
|
346
|
+
railway logs
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Output (real-time stream):**
|
|
350
|
+
```
|
|
351
|
+
[2025-01-15 10:30:45] Server running on port 3000
|
|
352
|
+
[2025-01-15 10:30:50] GET /health 200 15ms
|
|
353
|
+
[2025-01-15 10:31:00] GET / 200 8ms
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Follow logs (like tail -f):**
|
|
357
|
+
```bash
|
|
358
|
+
railway logs --follow
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Filter logs by service:**
|
|
362
|
+
```bash
|
|
363
|
+
railway logs --service my-express-api
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Common deployment errors:**
|
|
367
|
+
|
|
368
|
+
#### Error 1: Build Failed
|
|
369
|
+
```
|
|
370
|
+
Error: Cannot find module 'express'
|
|
371
|
+
```
|
|
372
|
+
**Fix:** Add `express` to `package.json` dependencies
|
|
373
|
+
|
|
374
|
+
#### Error 2: Port Binding
|
|
375
|
+
```
|
|
376
|
+
Error: listen EADDRINUSE: address already in use :::3000
|
|
377
|
+
```
|
|
378
|
+
**Fix:** Use `process.env.PORT` (Railway assigns dynamic port)
|
|
379
|
+
|
|
380
|
+
```javascript
|
|
381
|
+
// ❌ Wrong
|
|
382
|
+
const PORT = 3000
|
|
383
|
+
|
|
384
|
+
// ✅ Correct
|
|
385
|
+
const PORT = process.env.PORT || 3000
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Error 3: Start Command Failed
|
|
389
|
+
```
|
|
390
|
+
Error: Missing script: "start"
|
|
391
|
+
```
|
|
392
|
+
**Fix:** Add to `package.json`:
|
|
393
|
+
```json
|
|
394
|
+
"scripts": {
|
|
395
|
+
"start": "node index.js"
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**LazyVim Debugging Workflow:**
|
|
400
|
+
1. `<leader>ft` - Open floating terminal
|
|
401
|
+
2. `railway logs` - Watch errors in real-time
|
|
402
|
+
3. `<C-\><C-n>` - Exit terminal insert mode
|
|
403
|
+
4. `<C-w>w` - Switch back to code
|
|
404
|
+
5. Fix issue
|
|
405
|
+
6. `<C-w>w` - Back to terminal, then `i` to type
|
|
406
|
+
7. `git commit && railway up`
|
|
407
|
+
|
|
408
|
+
}}}
|
|
409
|
+
|
|
410
|
+
### Redeploy After Changes {{{
|
|
411
|
+
|
|
412
|
+
**Automatic deploys (recommended):**
|
|
413
|
+
```bash
|
|
414
|
+
# Connect GitHub repo to Railway
|
|
415
|
+
railway link
|
|
416
|
+
|
|
417
|
+
# Enable auto-deploys on Railway dashboard
|
|
418
|
+
# Now every git push triggers deployment
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Manual redeploy:**
|
|
422
|
+
```bash
|
|
423
|
+
# Make changes to your code
|
|
424
|
+
git add .
|
|
425
|
+
git commit -m "fix: correct port binding"
|
|
426
|
+
|
|
427
|
+
# Deploy to Railway
|
|
428
|
+
railway up
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Rollback to previous deployment:**
|
|
432
|
+
```bash
|
|
433
|
+
railway rollback
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**View deployment history:**
|
|
437
|
+
```bash
|
|
438
|
+
railway deployments
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Output:**
|
|
442
|
+
```
|
|
443
|
+
ID Status Created Duration
|
|
444
|
+
d3pl0y-5 ACTIVE 2 hours ago 1m 30s
|
|
445
|
+
d3pl0y-4 SUCCESS 5 hours ago 1m 45s
|
|
446
|
+
d3pl0y-3 FAILED 1 day ago 0m 20s
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
}}}
|
|
450
|
+
|
|
451
|
+
}}}
|
|
452
|
+
|
|
453
|
+
## 🔐 Part 3: Environment Variables & Secrets {{{
|
|
454
|
+
|
|
455
|
+
### Setting Variables via CLI {{{
|
|
456
|
+
|
|
457
|
+
**Add single variable:**
|
|
458
|
+
```bash
|
|
459
|
+
railway variables set DATABASE_URL="postgresql://user:pass@host:5432/db"
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Add multiple variables:**
|
|
463
|
+
```bash
|
|
464
|
+
railway variables set \
|
|
465
|
+
NODE_ENV=production \
|
|
466
|
+
API_KEY=sk_live_abc123 \
|
|
467
|
+
MAX_CONNECTIONS=100
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**List all variables:**
|
|
471
|
+
```bash
|
|
472
|
+
railway variables
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
**Output:**
|
|
476
|
+
```
|
|
477
|
+
Name Value
|
|
478
|
+
DATABASE_URL postgresql://...
|
|
479
|
+
NODE_ENV production
|
|
480
|
+
API_KEY sk_live_*** (hidden for security)
|
|
481
|
+
MAX_CONNECTIONS 100
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Delete variable:**
|
|
485
|
+
```bash
|
|
486
|
+
railway variables delete API_KEY
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Bulk import from .env file:**
|
|
490
|
+
```bash
|
|
491
|
+
railway variables set --from-env-file .env.production
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
}}}
|
|
495
|
+
|
|
496
|
+
### Using .env Files Locally {{{
|
|
497
|
+
|
|
498
|
+
**Local development setup:**
|
|
499
|
+
|
|
500
|
+
**1. Create `.env` (local only, gitignored):**
|
|
501
|
+
```bash
|
|
502
|
+
# .env
|
|
503
|
+
NODE_ENV=development
|
|
504
|
+
PORT=3000
|
|
505
|
+
DATABASE_URL=postgresql://localhost:5432/mydb_dev
|
|
506
|
+
API_KEY=sk_test_abc123
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**2. Add to `.gitignore`:**
|
|
510
|
+
```bash
|
|
511
|
+
# .gitignore
|
|
512
|
+
.env
|
|
513
|
+
.env.*
|
|
514
|
+
!.env.example
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**3. Create `.env.example` (committed to repo):**
|
|
518
|
+
```bash
|
|
519
|
+
# .env.example
|
|
520
|
+
NODE_ENV=development
|
|
521
|
+
PORT=3000
|
|
522
|
+
DATABASE_URL=postgresql://localhost:5432/dbname
|
|
523
|
+
API_KEY=your_api_key_here
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**4. Load variables in code:**
|
|
527
|
+
```javascript
|
|
528
|
+
// index.js
|
|
529
|
+
import 'dotenv/config' // Load .env file
|
|
530
|
+
|
|
531
|
+
const config = {
|
|
532
|
+
nodeEnv: process.env.NODE_ENV,
|
|
533
|
+
port: process.env.PORT || 3000,
|
|
534
|
+
databaseUrl: process.env.DATABASE_URL,
|
|
535
|
+
apiKey: process.env.API_KEY
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
console.log('Config loaded:', config.nodeEnv)
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
**Install dotenv:**
|
|
542
|
+
```bash
|
|
543
|
+
npm install dotenv
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Railway automatically loads env vars** - no dotenv needed in production!
|
|
547
|
+
|
|
548
|
+
}}}
|
|
549
|
+
|
|
550
|
+
### Secrets Management Best Practices {{{
|
|
551
|
+
|
|
552
|
+
**1. Never commit secrets:**
|
|
553
|
+
```bash
|
|
554
|
+
# ❌ Bad
|
|
555
|
+
git add .env
|
|
556
|
+
git commit -m "add environment variables"
|
|
557
|
+
|
|
558
|
+
# ✅ Good
|
|
559
|
+
# Add .env to .gitignore BEFORE committing
|
|
560
|
+
echo ".env" >> .gitignore
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**2. Use Railway's built-in variables:**
|
|
564
|
+
|
|
565
|
+
Railway provides these automatically:
|
|
566
|
+
```bash
|
|
567
|
+
RAILWAY_ENVIRONMENT # production, staging, etc.
|
|
568
|
+
RAILWAY_PROJECT_ID # Unique project ID
|
|
569
|
+
RAILWAY_SERVICE_ID # Unique service ID
|
|
570
|
+
RAILWAY_DEPLOYMENT_ID # Current deployment ID
|
|
571
|
+
RAILWAY_PUBLIC_DOMAIN # Your app's URL
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**Access in code:**
|
|
575
|
+
```javascript
|
|
576
|
+
if (process.env.RAILWAY_ENVIRONMENT === 'production') {
|
|
577
|
+
// Production-only logic
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
**3. Separate secrets by environment:**
|
|
582
|
+
```bash
|
|
583
|
+
# Production
|
|
584
|
+
railway variables set --environment production \
|
|
585
|
+
DATABASE_URL=postgresql://prod-host/db
|
|
586
|
+
|
|
587
|
+
# Staging
|
|
588
|
+
railway variables set --environment staging \
|
|
589
|
+
DATABASE_URL=postgresql://staging-host/db
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**4. Rotate secrets regularly:**
|
|
593
|
+
```bash
|
|
594
|
+
# Generate new API key
|
|
595
|
+
NEW_KEY=$(openssl rand -hex 32)
|
|
596
|
+
|
|
597
|
+
# Update Railway
|
|
598
|
+
railway variables set API_KEY=$NEW_KEY
|
|
599
|
+
|
|
600
|
+
# Trigger redeploy
|
|
601
|
+
railway up
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**5. Validate required variables:**
|
|
605
|
+
```javascript
|
|
606
|
+
// config.js
|
|
607
|
+
const requiredVars = [
|
|
608
|
+
'DATABASE_URL',
|
|
609
|
+
'API_KEY',
|
|
610
|
+
'JWT_SECRET'
|
|
611
|
+
]
|
|
612
|
+
|
|
613
|
+
for (const varName of requiredVars) {
|
|
614
|
+
if (!process.env[varName]) {
|
|
615
|
+
throw new Error(`Missing required env var: ${varName}`)
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
**LazyVim Tip:**
|
|
621
|
+
- Search for env vars: `<leader>/` then type `process.env.`
|
|
622
|
+
- Jump between matches with `n` and `N`
|
|
623
|
+
|
|
624
|
+
}}}
|
|
625
|
+
|
|
626
|
+
### Using Railway Plugins for Databases {{{
|
|
627
|
+
|
|
628
|
+
**Add PostgreSQL database:**
|
|
629
|
+
```bash
|
|
630
|
+
railway add
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Interactive prompt:**
|
|
634
|
+
```
|
|
635
|
+
Select a plugin to add:
|
|
636
|
+
> PostgreSQL
|
|
637
|
+
MySQL
|
|
638
|
+
MongoDB
|
|
639
|
+
Redis
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
**Railway automatically sets:**
|
|
643
|
+
```bash
|
|
644
|
+
DATABASE_URL=postgresql://user:pass@host:5432/railway
|
|
645
|
+
PGHOST=containers-us-west-1.railway.app
|
|
646
|
+
PGPORT=5432
|
|
647
|
+
PGUSER=postgres
|
|
648
|
+
PGPASSWORD=generated_password
|
|
649
|
+
PGDATABASE=railway
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
**Connect in your app:**
|
|
653
|
+
```javascript
|
|
654
|
+
import pg from 'pg'
|
|
655
|
+
const { Pool } = pg
|
|
656
|
+
|
|
657
|
+
const pool = new Pool({
|
|
658
|
+
connectionString: process.env.DATABASE_URL,
|
|
659
|
+
ssl: { rejectUnauthorized: false } // Railway requires SSL
|
|
660
|
+
})
|
|
661
|
+
|
|
662
|
+
// Test connection
|
|
663
|
+
const client = await pool.connect()
|
|
664
|
+
console.log('Database connected!')
|
|
665
|
+
client.release()
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
**Install pg driver:**
|
|
669
|
+
```bash
|
|
670
|
+
npm install pg
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
}}}
|
|
674
|
+
|
|
675
|
+
}}}
|
|
676
|
+
|
|
677
|
+
## 🌐 Part 4: Custom Domains & Networking {{{
|
|
678
|
+
|
|
679
|
+
### Add Custom Domain {{{
|
|
680
|
+
|
|
681
|
+
**Prerequisites:**
|
|
682
|
+
- Own a domain (from Namecheap, Google Domains, etc.)
|
|
683
|
+
- Access to DNS settings
|
|
684
|
+
|
|
685
|
+
**Add domain via CLI:**
|
|
686
|
+
```bash
|
|
687
|
+
railway domain
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
**Interactive prompt:**
|
|
691
|
+
```
|
|
692
|
+
Enter custom domain: api.yourdomain.com
|
|
693
|
+
✓ Domain added: api.yourdomain.com
|
|
694
|
+
⚠️ DNS not configured yet - see instructions below
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
**Or specify directly:**
|
|
698
|
+
```bash
|
|
699
|
+
railway domain add api.yourdomain.com
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**View current domains:**
|
|
703
|
+
```bash
|
|
704
|
+
railway domain list
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Output:**
|
|
708
|
+
```
|
|
709
|
+
Domain Status Service
|
|
710
|
+
my-app.up.railway.app Active my-express-api (auto)
|
|
711
|
+
api.yourdomain.com Pending my-express-api (custom)
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
**Remove domain:**
|
|
715
|
+
```bash
|
|
716
|
+
railway domain remove api.yourdomain.com
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
}}}
|
|
720
|
+
|
|
721
|
+
### Configure DNS Settings {{{
|
|
722
|
+
|
|
723
|
+
**Railway provides DNS instructions after adding domain.**
|
|
724
|
+
|
|
725
|
+
**Step 1: Get DNS records**
|
|
726
|
+
```bash
|
|
727
|
+
railway domain --service my-express-api
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
**Output:**
|
|
731
|
+
```
|
|
732
|
+
Domain: api.yourdomain.com
|
|
733
|
+
Status: Pending DNS verification
|
|
734
|
+
|
|
735
|
+
Add these records to your DNS provider:
|
|
736
|
+
Type Name Value
|
|
737
|
+
CNAME api my-app.up.railway.app
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
**Step 2: Add CNAME record at your DNS provider**
|
|
741
|
+
|
|
742
|
+
**Example: Cloudflare**
|
|
743
|
+
```
|
|
744
|
+
Type: CNAME
|
|
745
|
+
Name: api
|
|
746
|
+
Target: my-app.up.railway.app
|
|
747
|
+
Proxy: OFF (or ON, both work)
|
|
748
|
+
TTL: Auto
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
**Example: Namecheap**
|
|
752
|
+
```
|
|
753
|
+
Type: CNAME Record
|
|
754
|
+
Host: api
|
|
755
|
+
Value: my-app.up.railway.app
|
|
756
|
+
TTL: Automatic
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
**Step 3: Wait for DNS propagation**
|
|
760
|
+
```bash
|
|
761
|
+
# Check DNS propagation
|
|
762
|
+
dig api.yourdomain.com
|
|
763
|
+
|
|
764
|
+
# Or use online tool
|
|
765
|
+
# https://dnschecker.org/#CNAME/api.yourdomain.com
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Propagation time:** 5 minutes to 48 hours (usually ~1 hour)
|
|
769
|
+
|
|
770
|
+
**Step 4: Verify in Railway**
|
|
771
|
+
```bash
|
|
772
|
+
railway domain list
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
**Once verified:**
|
|
776
|
+
```
|
|
777
|
+
Domain Status SSL
|
|
778
|
+
api.yourdomain.com Active Provisioning...
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
**SSL certificate is automatic!** Railway uses Let's Encrypt.
|
|
782
|
+
|
|
783
|
+
}}}
|
|
784
|
+
|
|
785
|
+
### SSL/TLS Certificates {{{
|
|
786
|
+
|
|
787
|
+
**Railway handles SSL automatically:**
|
|
788
|
+
1. You add custom domain
|
|
789
|
+
2. DNS verification completes
|
|
790
|
+
3. Railway provisions Let's Encrypt cert (free)
|
|
791
|
+
4. HTTPS enabled automatically
|
|
792
|
+
|
|
793
|
+
**No configuration needed!**
|
|
794
|
+
|
|
795
|
+
**Verify SSL:**
|
|
796
|
+
```bash
|
|
797
|
+
curl -I https://api.yourdomain.com
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Look for:**
|
|
801
|
+
```
|
|
802
|
+
HTTP/2 200
|
|
803
|
+
server: Railway
|
|
804
|
+
x-forwarded-proto: https
|
|
805
|
+
strict-transport-security: max-age=31536000
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
**Force HTTPS in your app (optional):**
|
|
809
|
+
```javascript
|
|
810
|
+
// middleware/force-https.js
|
|
811
|
+
export function forceHTTPS(req, res, next) {
|
|
812
|
+
if (process.env.NODE_ENV === 'production' &&
|
|
813
|
+
req.headers['x-forwarded-proto'] !== 'https') {
|
|
814
|
+
return res.redirect(301, `https://${req.headers.host}${req.url}`)
|
|
815
|
+
}
|
|
816
|
+
next()
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// index.js
|
|
820
|
+
import { forceHTTPS } from './middleware/force-https.js'
|
|
821
|
+
app.use(forceHTTPS)
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
**SSL certificate renewal:** Automatic (every 60 days)
|
|
825
|
+
|
|
826
|
+
}}}
|
|
827
|
+
|
|
828
|
+
### Database Connections {{{
|
|
829
|
+
|
|
830
|
+
**Railway networking:**
|
|
831
|
+
- Services within same project can communicate via **private network**
|
|
832
|
+
- No public internet needed for internal connections
|
|
833
|
+
|
|
834
|
+
**Connect to PostgreSQL from your app:**
|
|
835
|
+
|
|
836
|
+
**Option 1: Use DATABASE_URL (simplest)**
|
|
837
|
+
```javascript
|
|
838
|
+
import pg from 'pg'
|
|
839
|
+
const pool = new pg.Pool({
|
|
840
|
+
connectionString: process.env.DATABASE_URL
|
|
841
|
+
})
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
**Option 2: Use individual env vars**
|
|
845
|
+
```javascript
|
|
846
|
+
const pool = new pg.Pool({
|
|
847
|
+
host: process.env.PGHOST,
|
|
848
|
+
port: process.env.PGPORT,
|
|
849
|
+
database: process.env.PGDATABASE,
|
|
850
|
+
user: process.env.PGUSER,
|
|
851
|
+
password: process.env.PGPASSWORD,
|
|
852
|
+
ssl: { rejectUnauthorized: false }
|
|
853
|
+
})
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Connection pooling best practices:**
|
|
857
|
+
```javascript
|
|
858
|
+
const pool = new pg.Pool({
|
|
859
|
+
connectionString: process.env.DATABASE_URL,
|
|
860
|
+
max: 20, // Max connections in pool
|
|
861
|
+
idleTimeoutMillis: 30000, // Close idle connections after 30s
|
|
862
|
+
connectionTimeoutMillis: 2000 // Fail fast if can't connect
|
|
863
|
+
})
|
|
864
|
+
|
|
865
|
+
// Graceful shutdown
|
|
866
|
+
process.on('SIGTERM', async () => {
|
|
867
|
+
await pool.end()
|
|
868
|
+
process.exit(0)
|
|
869
|
+
})
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
**Test database connection:**
|
|
873
|
+
```javascript
|
|
874
|
+
async function testConnection() {
|
|
875
|
+
try {
|
|
876
|
+
const client = await pool.connect()
|
|
877
|
+
const result = await client.query('SELECT NOW()')
|
|
878
|
+
console.log('Database connected:', result.rows[0].now)
|
|
879
|
+
client.release()
|
|
880
|
+
} catch (err) {
|
|
881
|
+
console.error('Database connection failed:', err)
|
|
882
|
+
process.exit(1)
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
testConnection()
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
}}}
|
|
890
|
+
|
|
891
|
+
### CORS Configuration {{{
|
|
892
|
+
|
|
893
|
+
**Allow requests from your frontend domain:**
|
|
894
|
+
|
|
895
|
+
```javascript
|
|
896
|
+
import cors from 'cors'
|
|
897
|
+
|
|
898
|
+
const allowedOrigins = [
|
|
899
|
+
'https://yourdomain.com',
|
|
900
|
+
'https://www.yourdomain.com',
|
|
901
|
+
process.env.RAILWAY_ENVIRONMENT === 'development' && 'http://localhost:3000'
|
|
902
|
+
].filter(Boolean)
|
|
903
|
+
|
|
904
|
+
app.use(cors({
|
|
905
|
+
origin: allowedOrigins,
|
|
906
|
+
credentials: true,
|
|
907
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
908
|
+
allowedHeaders: ['Content-Type', 'Authorization']
|
|
909
|
+
}))
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
**Install cors:**
|
|
913
|
+
```bash
|
|
914
|
+
npm install cors
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
**Test CORS:**
|
|
918
|
+
```bash
|
|
919
|
+
curl -H "Origin: https://yourdomain.com" \
|
|
920
|
+
-H "Access-Control-Request-Method: POST" \
|
|
921
|
+
-X OPTIONS \
|
|
922
|
+
https://api.yourdomain.com/endpoint
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
**Expected headers in response:**
|
|
926
|
+
```
|
|
927
|
+
Access-Control-Allow-Origin: https://yourdomain.com
|
|
928
|
+
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
|
|
929
|
+
Access-Control-Allow-Credentials: true
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
}}}
|
|
933
|
+
|
|
934
|
+
}}}
|
|
935
|
+
|
|
936
|
+
## 🎓 Quick Reference {{{
|
|
937
|
+
|
|
938
|
+
### Common Commands Cheat Sheet {{{
|
|
939
|
+
|
|
940
|
+
**Authentication:**
|
|
941
|
+
```bash
|
|
942
|
+
railway login # Login via browser
|
|
943
|
+
railway logout # Logout
|
|
944
|
+
railway whoami # Show current user
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
**Project Management:**
|
|
948
|
+
```bash
|
|
949
|
+
railway init # Create new project
|
|
950
|
+
railway link # Link to existing project
|
|
951
|
+
railway status # Show project info
|
|
952
|
+
railway list # List all projects
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
**Deployment:**
|
|
956
|
+
```bash
|
|
957
|
+
railway up # Deploy current directory
|
|
958
|
+
railway up --detach # Deploy without watching logs
|
|
959
|
+
railway logs # View logs
|
|
960
|
+
railway logs -f # Follow logs (tail -f)
|
|
961
|
+
railway open # Open app in browser
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
**Environment Variables:**
|
|
965
|
+
```bash
|
|
966
|
+
railway variables # List all vars
|
|
967
|
+
railway variables set KEY=value # Set variable
|
|
968
|
+
railway variables delete KEY # Delete variable
|
|
969
|
+
railway variables --environment staging # Target specific env
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
**Domains:**
|
|
973
|
+
```bash
|
|
974
|
+
railway domain # Interactive domain management
|
|
975
|
+
railway domain add example.com # Add custom domain
|
|
976
|
+
railway domain list # List all domains
|
|
977
|
+
railway domain remove example.com # Remove domain
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
**Plugins:**
|
|
981
|
+
```bash
|
|
982
|
+
railway add # Add plugin (database, Redis, etc.)
|
|
983
|
+
railway plugins # List plugins
|
|
984
|
+
railway remove # Remove plugin
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
**Utilities:**
|
|
988
|
+
```bash
|
|
989
|
+
railway run node script.js # Run command with Railway env vars
|
|
990
|
+
railway shell # Open shell with env vars loaded
|
|
991
|
+
railway environment # Switch environment
|
|
992
|
+
railway service # Manage services
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
}}}
|
|
996
|
+
|
|
997
|
+
### Troubleshooting Guide {{{
|
|
998
|
+
|
|
999
|
+
**Problem: Build fails with "command not found"**
|
|
1000
|
+
```
|
|
1001
|
+
Error: sh: npm: command not found
|
|
1002
|
+
```
|
|
1003
|
+
**Solution:** Specify Node.js version in `railway.json`:
|
|
1004
|
+
```json
|
|
1005
|
+
{
|
|
1006
|
+
"build": {
|
|
1007
|
+
"builder": "NIXPACKS"
|
|
1008
|
+
},
|
|
1009
|
+
"deploy": {
|
|
1010
|
+
"nixpacksVersion": "1.x"
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
---
|
|
1016
|
+
|
|
1017
|
+
**Problem: App crashes immediately after deploy**
|
|
1018
|
+
```
|
|
1019
|
+
Error: Application exited with code 1
|
|
1020
|
+
```
|
|
1021
|
+
**Debug:**
|
|
1022
|
+
```bash
|
|
1023
|
+
railway logs --tail 100
|
|
1024
|
+
```
|
|
1025
|
+
**Common causes:**
|
|
1026
|
+
- Missing environment variables
|
|
1027
|
+
- Port binding to hardcoded port instead of `process.env.PORT`
|
|
1028
|
+
- Missing `start` script in package.json
|
|
1029
|
+
|
|
1030
|
+
---
|
|
1031
|
+
|
|
1032
|
+
**Problem: Environment variables not loading**
|
|
1033
|
+
```javascript
|
|
1034
|
+
console.log(process.env.MY_VAR) // undefined
|
|
1035
|
+
```
|
|
1036
|
+
**Solution:**
|
|
1037
|
+
1. Check variable is set: `railway variables`
|
|
1038
|
+
2. Restart app: `railway up`
|
|
1039
|
+
3. Verify environment: `railway status`
|
|
1040
|
+
|
|
1041
|
+
---
|
|
1042
|
+
|
|
1043
|
+
**Problem: Database connection timeout**
|
|
1044
|
+
```
|
|
1045
|
+
Error: connect ETIMEDOUT
|
|
1046
|
+
```
|
|
1047
|
+
**Checklist:**
|
|
1048
|
+
- [ ] DATABASE_URL is set: `railway variables | grep DATABASE`
|
|
1049
|
+
- [ ] SSL is enabled in connection: `ssl: { rejectUnauthorized: false }`
|
|
1050
|
+
- [ ] Database plugin is running: `railway plugins`
|
|
1051
|
+
- [ ] Network connectivity: Database and app in same project?
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
**Problem: Custom domain shows "DNS not configured"**
|
|
1056
|
+
```
|
|
1057
|
+
Status: Pending DNS verification
|
|
1058
|
+
```
|
|
1059
|
+
**Steps:**
|
|
1060
|
+
1. Verify CNAME record exists at DNS provider
|
|
1061
|
+
2. Check DNS propagation: `dig yourdomain.com`
|
|
1062
|
+
3. Wait up to 48 hours (usually ~1 hour)
|
|
1063
|
+
4. Use DNS checker: https://dnschecker.org
|
|
1064
|
+
|
|
1065
|
+
---
|
|
1066
|
+
|
|
1067
|
+
**Problem: High memory usage / crashes**
|
|
1068
|
+
```
|
|
1069
|
+
Error: JavaScript heap out of memory
|
|
1070
|
+
```
|
|
1071
|
+
**Solution:** Increase Node.js memory limit:
|
|
1072
|
+
```json
|
|
1073
|
+
{
|
|
1074
|
+
"deploy": {
|
|
1075
|
+
"startCommand": "node --max-old-space-size=4096 index.js"
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
```
|
|
1079
|
+
|
|
1080
|
+
Or upgrade Railway plan for more resources.
|
|
1081
|
+
|
|
1082
|
+
---
|
|
1083
|
+
|
|
1084
|
+
**Problem: Slow cold starts**
|
|
1085
|
+
|
|
1086
|
+
**Optimization strategies:**
|
|
1087
|
+
1. **Reduce dependencies:** Review `package.json`, remove unused packages
|
|
1088
|
+
2. **Use build cache:** Railway caches `node_modules` between deploys
|
|
1089
|
+
3. **Lazy load modules:** Only import what you need when you need it
|
|
1090
|
+
4. **Optimize Docker layers:** If using Dockerfile, order commands by change frequency
|
|
1091
|
+
|
|
1092
|
+
---
|
|
1093
|
+
|
|
1094
|
+
**Get help:**
|
|
1095
|
+
- Railway Docs: https://docs.railway.app
|
|
1096
|
+
- Railway Discord: https://discord.gg/railway
|
|
1097
|
+
- Railway CLI help: `railway --help`
|
|
1098
|
+
|
|
1099
|
+
}}}
|
|
1100
|
+
|
|
1101
|
+
### LazyVim Workflow Summary {{{
|
|
1102
|
+
|
|
1103
|
+
**Quick navigation in this file:**
|
|
1104
|
+
```vim
|
|
1105
|
+
zM " Close all folds - see outline
|
|
1106
|
+
/railway up " Search for deployment command
|
|
1107
|
+
n " Next match
|
|
1108
|
+
za " Toggle fold under cursor
|
|
1109
|
+
<leader>ft " Open floating terminal to run commands
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
**Working with code:**
|
|
1113
|
+
```vim
|
|
1114
|
+
gf " Go to file under cursor
|
|
1115
|
+
gd " Go to definition
|
|
1116
|
+
K " Show hover docs
|
|
1117
|
+
<leader>/ " Search across entire project
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
**Editing tricks:**
|
|
1121
|
+
```vim
|
|
1122
|
+
ci" " Change inside quotes (update URLs)
|
|
1123
|
+
ci{ " Change inside braces (edit JSON)
|
|
1124
|
+
>> " Indent line
|
|
1125
|
+
=i{ " Auto-format JSON object
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
**Terminal integration:**
|
|
1129
|
+
```vim
|
|
1130
|
+
<leader>ft " Open floating terminal
|
|
1131
|
+
<C-\><C-n> " Exit terminal insert mode → Normal mode
|
|
1132
|
+
<C-w>w " Cycle between terminal and code
|
|
1133
|
+
i " Back to terminal insert mode (type commands)
|
|
1134
|
+
:terminal " Alternative: open terminal in current window
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
}}}
|
|
1138
|
+
|
|
1139
|
+
}}}
|
|
1140
|
+
|
|
1141
|
+
## 🎯 Next Steps {{{
|
|
1142
|
+
|
|
1143
|
+
**After completing this guide, you should be able to:**
|
|
1144
|
+
- ✅ Deploy Node.js apps to Railway from CLI
|
|
1145
|
+
- ✅ Manage environment variables and secrets
|
|
1146
|
+
- ✅ Configure custom domains with SSL
|
|
1147
|
+
- ✅ Connect databases and manage networking
|
|
1148
|
+
- ✅ Debug deployment issues with logs
|
|
1149
|
+
|
|
1150
|
+
**Level up your deployment skills:**
|
|
1151
|
+
1. **Add CI/CD:** Connect GitHub for auto-deploys on push
|
|
1152
|
+
2. **Multi-environment setup:** Create staging + production environments
|
|
1153
|
+
3. **Monitoring:** Set up health checks and alerts
|
|
1154
|
+
4. **Scaling:** Configure autoscaling for high traffic
|
|
1155
|
+
5. **Database migrations:** Learn Railway's migration workflows
|
|
1156
|
+
|
|
1157
|
+
**Resources:**
|
|
1158
|
+
- Railway Docs: https://docs.railway.app
|
|
1159
|
+
- Railway Templates: https://railway.app/templates
|
|
1160
|
+
- Railway Discord: https://discord.gg/railway
|
|
1161
|
+
- This guide in Creta: `creta` → "Practicar con ejercicios" → "Railway Deployment Guide"
|
|
1162
|
+
|
|
1163
|
+
}}}
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
1167
|
+
**💡 Pro Tip:** Keep this guide open in LazyVim while deploying with Railway CLI!
|
|
1168
|
+
|
|
1169
|
+
**Terminal Workflow:**
|
|
1170
|
+
1. Open this guide: `nvim lib/exercises/railway-deployment.md`
|
|
1171
|
+
2. `<leader>ft` - Open floating terminal
|
|
1172
|
+
3. Type Railway commands (e.g., `railway up`)
|
|
1173
|
+
4. `<C-\><C-n>` - Exit terminal insert mode (to Normal mode)
|
|
1174
|
+
5. `<C-w>w` - Cycle back to guide to read next steps
|
|
1175
|
+
6. `<C-w>w` - Back to terminal
|
|
1176
|
+
7. `i` - Enter insert mode to type more commands
|
|
1177
|
+
8. Repeat steps 3-7 as you work through the guide!
|
|
1178
|
+
|
|
1179
|
+
**Quick reference:**
|
|
1180
|
+
- `<leader>ft` → Open terminal
|
|
1181
|
+
- `<C-\><C-n>` → Exit terminal typing mode
|
|
1182
|
+
- `<C-w>w` → Switch windows
|
|
1183
|
+
- `i` → Start typing in terminal
|
|
1184
|
+
|
|
1185
|
+
**🏛️ Salgamos de este laberinto** - Happy deploying with Railway! 🚂
|