You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/adr/0003-source-env-instead-of-pm2-env-file.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,12 +7,12 @@ We now drop `env_file` from the ecosystem and emit each app as a `bash` script w
7
7
```js
8
8
{
9
9
script:'bash',
10
-
args: ['-c', "set -a && . '/var/www/app/shared/.env.production' && set +a && exec node dist/server.js"],
10
+
args: ['-c', "set -a && . '/var/www/app/shared/.env.production' && set +a && export NODE_ENV='production' PORT='3000' && exec node dist/server.js"],
11
11
env: { NODE_ENV:'production', PORT:3000 }
12
12
}
13
13
```
14
14
15
-
`set -a` exports everything sourced. `exec` replaces the wrapper shell so PM2 supervises the real process directly — signals, reloads, and crash detection behave exactly as before. Per-app `env:` overrides (e.g. `WORKER_QUEUE`) still apply because PM2 layers them on top of the inherited env. Secrets stay in the chmod-600 `.env` file; they do **not** leak into the world-readable `ecosystem.config.cjs`.
15
+
`set -a` exports everything sourced. The wrapper then reapplies the ecosystem's explicit values so `NODE_ENV`, per-app overrides, and especially a blue-green target `PORT` take precedence over stale values in the shared dotenv file. `exec` replaces the wrapper shell so PM2 supervises the real process directly — signals, reloads, and crash detection behave exactly as before. Secrets from the dotenv file stay in the chmod-600 shared file; they are not duplicated into the world-readable ecosystem configuration.
16
16
17
17
`args` is emitted as an array because PM2 word-splits string args on whitespace, which would shred the inline shell snippet.
Copy file name to clipboardExpand all lines: docs/adr/0005-blue-green-zero-downtime.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,15 +9,15 @@ Two ports, named **blue** and **green**. Blue is the web app's configured `port`
9
9
Each deploy:
10
10
11
11
1. Stages the release and switches the `current` symlink (as always). The previously-started colour keeps running the old code in memory — the symlink move doesn't touch a running process.
12
-
2. Boots the **idle** colour on its own port (`pm2 start ecosystem.web.cjs`), reaping any stale same-colour instance first. The active colour is never touched. Workers are **not** reloaded yet.
12
+
2. Boots the **idle** colour on its own port (`pm2 start ecosystem.web.config.cjs`), reaping any stale same-colour instance first. The active colour is never touched. Workers are **not** reloaded yet.
13
13
3. Health-checks the new colour on **its** port and colour-suffixed pm2 name (`api-green`).
14
14
4. Only on success: reloads the single worker set against the new release, then rewrites the Caddy site to the new colour's port and `systemctl reload caddy` — a graceful reload that drains in-flight requests. Then persists the new active colour. On the first migration only, the legacy uncoloured process is removed after this sequence.
15
15
16
16
A failed health check throws before step 4: Caddy is untouched, workers stay on the previous release, the old colour is still serving, `current` is reverted to the previous release when one exists, and the failed colour is reaped by the next deploy. Zero user impact on a bad release — the main prize.
17
17
18
18
## Why the web app is duplicated but workers are not
19
19
20
-
Blue-green needs two copies of the *web* app (old + new, different ports) resident at once. Workers have no port and aren't behind Caddy; running two copies would double-process their queues. So the ecosystem is split: `ecosystem.web.cjs` holds only the colour-suffixed web app; `ecosystem.workers.cjs` holds the workers as a single set, reloaded in place **after** health passes (a brief worker blip on a successful deploy is acceptable — they're not serving HTTP). Reloading before health would leave workers on a bad release while traffic stayed on the old colour.
20
+
Blue-green needs two copies of the *web* app (old + new, different ports) resident at once. Workers have no port and aren't behind Caddy; running two copies would double-process their queues. So the ecosystem is split: `ecosystem.web.config.cjs` holds only the colour-suffixed web app; `ecosystem.workers.config.cjs` holds the workers as a single set, reloaded in place **after** health passes (a brief worker blip on a successful deploy is acceptable — they're not serving HTTP). The `.config.cjs` suffix is required so PM2 parses these files as ecosystem configuration instead of launching the file itself as an application. Reloading before health would leave workers on a bad release while traffic stayed on the old colour.
0 commit comments