rollbridge 0.1.2 → 0.1.5
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/LICENSE +21 -0
- package/README.md +205 -5
- package/TODO.md +21 -18
- package/docs/cli.md +174 -0
- package/docs/config.md +148 -0
- package/docs/deploy-recipes.md +102 -0
- package/docs/nginx.md +104 -0
- package/docs/troubleshooting.md +102 -0
- package/docs/velocious.md +200 -0
- package/package.json +22 -2
- package/src/cli.js +168 -2
- package/src/config.js +146 -8
- package/src/daemon.js +138 -6
- package/src/doctor.js +114 -0
- package/src/health.js +4 -0
- package/src/managed-process.js +73 -10
- package/src/release-group.js +42 -4
- package/test/config-validation.test.js +145 -0
- package/test/doctor.test.js +228 -0
- package/test/fixtures/crasher.js +2 -0
- package/test/health.test.js +63 -0
- package/test/logs.test.js +99 -0
- package/test/managed-process.test.js +146 -0
- package/test/package-metadata.test.js +29 -0
- package/test/release-retention.test.js +107 -0
- package/test/rollbridge.test.js +249 -5
- package/scripts/release-patch.js +0 -83
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kaspernj
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -37,6 +37,7 @@ export default {
|
|
|
37
37
|
proxy: {
|
|
38
38
|
host: "127.0.0.1",
|
|
39
39
|
port: 8182,
|
|
40
|
+
upstreamHost: "127.0.0.1",
|
|
40
41
|
healthPath: "/ping",
|
|
41
42
|
healthTimeoutMs: 30000,
|
|
42
43
|
drainTimeoutMs: 60000,
|
|
@@ -85,6 +86,34 @@ chmod the control socket after it binds. This restricts which users can send
|
|
|
85
86
|
control commands — useful when several deploy users share a group. When unset,
|
|
86
87
|
the socket keeps the default permissions from the daemon's umask.
|
|
87
88
|
|
|
89
|
+
Set the proxied process's `health.startDelayMs` (default `0`) to wait that long
|
|
90
|
+
after the process starts before the first health probe — like a readiness
|
|
91
|
+
probe's initial delay, useful for apps with a known boot time. The delay runs
|
|
92
|
+
before the `health.timeoutMs` window begins.
|
|
93
|
+
|
|
94
|
+
Set a process's `restart` policy to control automatic restarts after a crash.
|
|
95
|
+
`restart.maxRestarts` caps how many restarts are allowed within `restart.windowMs`
|
|
96
|
+
before Rollbridge gives up and leaves the process `failed` (`maxRestarts: 0`
|
|
97
|
+
disables restarts entirely), while `restart.backoffFactor` — with an optional
|
|
98
|
+
`restart.maxDelayMs` cap — backs off the `restartDelayMs` delay on each successive
|
|
99
|
+
restart. With no `restart` block, a crashed process keeps restarting after
|
|
100
|
+
`restartDelayMs`, as before. See [`docs/config.md`](docs/config.md#processesrestart).
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
restart: {maxRestarts: 5, windowMs: 60000, backoffFactor: 2, maxDelayMs: 30000}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Set `releaseRetention` to bound how many stopped (drained) releases the daemon
|
|
107
|
+
keeps in memory and reports in `status`. `keep` (default `10`) retains the most
|
|
108
|
+
recent stopped releases; `maxAgeMs` (default `0`, disabled) also prunes stopped
|
|
109
|
+
releases older than that many milliseconds. The active and draining releases are
|
|
110
|
+
never pruned. This is Rollbridge's own release records — your deploy tool still
|
|
111
|
+
owns cleaning up on-disk release directories.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
releaseRetention: {keep: 5, maxAgeMs: 86400000}
|
|
115
|
+
```
|
|
116
|
+
|
|
88
117
|
A function export receives no arguments and lets you build the config at load
|
|
89
118
|
time:
|
|
90
119
|
|
|
@@ -107,7 +136,7 @@ rendered when the process starts:
|
|
|
107
136
|
|
|
108
137
|
- `{{releasePath}}`, `{{releaseId}}`, `{{revision}}`, `{{application}}`, `{{processId}}`
|
|
109
138
|
- `{{port}}` — the port allocated to this process; `{{ports.<id>}}` — another process's allocated port
|
|
110
|
-
- `{{proxy.host}}`, `{{proxy.port}}`
|
|
139
|
+
- `{{proxy.host}}`, `{{proxy.port}}`, `{{proxy.upstreamHost}}`
|
|
111
140
|
- `{{env.<NAME>}}` — a variable from the daemon's own environment, e.g. `{{env.HOME}}`
|
|
112
141
|
|
|
113
142
|
Referencing a placeholder with no value (including an unset `{{env.<NAME>}}`)
|
|
@@ -116,12 +145,115 @@ fails the process start with a clear error, so typos surface immediately.
|
|
|
116
145
|
Production-ready examples live in `examples/`, including
|
|
117
146
|
`examples/tensorbuzz.com.js` for the current TensorBuzz backend deployment.
|
|
118
147
|
|
|
148
|
+
See [`docs/velocious.md`](docs/velocious.md) for a Velocious deployment guide —
|
|
149
|
+
how Beacon, background-jobs-main, background-jobs-worker, and the web process map
|
|
150
|
+
to Rollbridge policies, with startup ordering and deploy behavior.
|
|
151
|
+
|
|
152
|
+
See [`docs/config.md`](docs/config.md) for the full config reference — every
|
|
153
|
+
field, its default, validation rules, template variables, and the environment
|
|
154
|
+
variables Rollbridge injects.
|
|
155
|
+
|
|
119
156
|
## Process Policies
|
|
120
157
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
158
|
+
Every process declares a `policy` that controls its lifecycle. Pick one per
|
|
159
|
+
process:
|
|
160
|
+
|
|
161
|
+
| You need… | Use |
|
|
162
|
+
| --- | --- |
|
|
163
|
+
| The process that receives external HTTP/WebSocket traffic | `proxied` |
|
|
164
|
+
| A per-release helper tied to the release lifecycle | `companion` |
|
|
165
|
+
| Exactly one instance, never overlapping across deploys | `singleton` |
|
|
166
|
+
| A long-lived shared broker that survives deploys | `service` |
|
|
167
|
+
|
|
168
|
+
### `proxied`
|
|
169
|
+
|
|
170
|
+
The web/API process — exactly one per config. Rollbridge forwards HTTP and
|
|
171
|
+
WebSocket traffic to the active release's proxied process and tracks open
|
|
172
|
+
connections so they can be drained on the next deploy. It must define a `port`
|
|
173
|
+
range, is health-checked before traffic switches to a new release, and is
|
|
174
|
+
auto-restarted while its release is active.
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
{
|
|
178
|
+
id: "web",
|
|
179
|
+
policy: "proxied",
|
|
180
|
+
cwd: "{{releasePath}}",
|
|
181
|
+
command: "npx velocious server --host 127.0.0.1 --port {{port}}",
|
|
182
|
+
port: {from: 18182, to: 18299},
|
|
183
|
+
health: {path: "/ping", timeoutMs: 30000}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### `companion`
|
|
188
|
+
|
|
189
|
+
A release-scoped helper (for example a background worker bound to one release).
|
|
190
|
+
It starts **before** the proxied process in the same release, so release-local
|
|
191
|
+
dependencies are ready before the health check, and it is auto-restarted while
|
|
192
|
+
its release is active. Each release gets its own companions; a release's
|
|
193
|
+
companions stop when that release is drained and retired after a newer release
|
|
194
|
+
takes over.
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
{
|
|
198
|
+
id: "background-jobs-worker",
|
|
199
|
+
policy: "companion",
|
|
200
|
+
cwd: "{{releasePath}}",
|
|
201
|
+
command: "npx velocious background-jobs-worker",
|
|
202
|
+
gracefulStopMs: 60000
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `singleton`
|
|
207
|
+
|
|
208
|
+
A one-at-a-time helper for duplicate-unsafe schedulers or job dispatchers. After
|
|
209
|
+
a new release becomes active, Rollbridge stops the old singleton and then starts
|
|
210
|
+
the new one, so two copies never run at once. Use it when running the old and
|
|
211
|
+
new copies simultaneously during a deploy would be unsafe.
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
{
|
|
215
|
+
id: "scheduler",
|
|
216
|
+
policy: "singleton",
|
|
217
|
+
cwd: "{{releasePath}}",
|
|
218
|
+
command: "npx velocious scheduler"
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### `service`
|
|
223
|
+
|
|
224
|
+
A daemon-wide broker that should outlive individual releases — for example
|
|
225
|
+
Velocious Beacon or `background-jobs-main`. Rollbridge starts it once (before
|
|
226
|
+
release processes that depend on it), keeps it running across deploys, and gives
|
|
227
|
+
it a stable port that does not change between releases. After each successful
|
|
228
|
+
deploy its restart template is refreshed to the latest release, so if it crashes
|
|
229
|
+
it restarts from the newest good release. It keeps restarting until the daemon
|
|
230
|
+
shuts down.
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
{
|
|
234
|
+
id: "background-jobs-main",
|
|
235
|
+
policy: "service",
|
|
236
|
+
cwd: "{{releasePath}}",
|
|
237
|
+
command: "npx velocious background-jobs-main",
|
|
238
|
+
port: 7331
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Deploy ordering
|
|
243
|
+
|
|
244
|
+
On `rollbridge deploy`, Rollbridge:
|
|
245
|
+
|
|
246
|
+
1. starts any `service` that is not already running;
|
|
247
|
+
2. starts the new release's `companion`s, then its `proxied` process, and
|
|
248
|
+
health-checks the proxied process;
|
|
249
|
+
3. switches new traffic to the new release;
|
|
250
|
+
4. refreshes each `service`'s restart template to the new release;
|
|
251
|
+
5. replaces `singleton`s (stops the old one, then starts the new one);
|
|
252
|
+
6. drains the previous release's connections, then stops its `proxied` and
|
|
253
|
+
`companion` processes.
|
|
254
|
+
|
|
255
|
+
If the new release fails to start or health-check, the previous release stays
|
|
256
|
+
active and any service started during this deploy is rolled back.
|
|
125
257
|
|
|
126
258
|
## Commands
|
|
127
259
|
|
|
@@ -130,6 +262,14 @@ Production-ready examples live in `examples/`, including
|
|
|
130
262
|
explicitly, but `rollbridge validate` (or any command) works with no flag when a
|
|
131
263
|
`rollbridge.js` is present.
|
|
132
264
|
|
|
265
|
+
For machine-readable output, `deploy`, `status`, `stop`, `shutdown`, and
|
|
266
|
+
`ensure-daemon` already print JSON, and `validate`, `doctor`, and `logs` accept
|
|
267
|
+
a `--json` flag that switches their output to JSON (with the same exit codes),
|
|
268
|
+
so deploy tooling can parse results.
|
|
269
|
+
|
|
270
|
+
See [`docs/cli.md`](docs/cli.md) for the full per-command reference (every
|
|
271
|
+
option, default, output shape, and exit code).
|
|
272
|
+
|
|
133
273
|
Validate a config without starting the daemon:
|
|
134
274
|
|
|
135
275
|
```bash
|
|
@@ -152,6 +292,30 @@ Found 2 configuration issues in rollbridge.js:
|
|
|
152
292
|
Fix: Give each process a unique id; "web" is used more than once.
|
|
153
293
|
```
|
|
154
294
|
|
|
295
|
+
Check the environment before starting the daemon:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
rollbridge doctor --config rollbridge.js
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`doctor` validates the config and then probes the runtime environment, exiting
|
|
302
|
+
non-zero if any check fails (so deploy tooling can gate on it):
|
|
303
|
+
|
|
304
|
+
```text
|
|
305
|
+
✓ config: valid: 4 processes, proxy on 127.0.0.1:8182
|
|
306
|
+
✓ control socket: no daemon running; /tmp/rollbridge-ticket-server.sock is free to bind
|
|
307
|
+
✓ control socket directory: /tmp is writable
|
|
308
|
+
✓ proxy port: 127.0.0.1:8182 is available
|
|
309
|
+
|
|
310
|
+
All checks passed.
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
A free control socket, a writable socket directory, and a bindable proxy port
|
|
314
|
+
pass. Because `rollbridge daemon` cannot bind a socket or port that is already
|
|
315
|
+
taken, doctor fails the relevant check when a Rollbridge daemon (or any other
|
|
316
|
+
process) is already listening on the control socket or holding the proxy port —
|
|
317
|
+
so a green `doctor` means a fresh daemon can actually start.
|
|
318
|
+
|
|
155
319
|
Start the daemon:
|
|
156
320
|
|
|
157
321
|
```bash
|
|
@@ -182,12 +346,34 @@ Inspect state:
|
|
|
182
346
|
rollbridge status --config rollbridge.js
|
|
183
347
|
```
|
|
184
348
|
|
|
349
|
+
`status` reports each managed process's `state`, `pid`, recent `logs`, last
|
|
350
|
+
`exitCode`/`exitSignal`, and — per process — its automatic-restart count
|
|
351
|
+
(`restarts`), last start time (`startedAt`), and current `uptimeMs` while
|
|
352
|
+
running.
|
|
353
|
+
|
|
354
|
+
Print the recent captured stdout/stderr per process (a one-shot snapshot of the
|
|
355
|
+
retained `outputLines`, not a live stream):
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
rollbridge logs --config rollbridge.js
|
|
359
|
+
rollbridge logs --config rollbridge.js --process web
|
|
360
|
+
```
|
|
361
|
+
|
|
185
362
|
Stop the active release:
|
|
186
363
|
|
|
187
364
|
```bash
|
|
188
365
|
rollbridge stop --config rollbridge.js
|
|
189
366
|
```
|
|
190
367
|
|
|
368
|
+
Restart non-proxied processes in place — all of them, one by id, or a policy
|
|
369
|
+
group (the proxied process is never restarted; use `deploy` for that):
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
rollbridge restart --config rollbridge.js # all non-proxied processes
|
|
373
|
+
rollbridge restart --config rollbridge.js --process background-jobs-worker
|
|
374
|
+
rollbridge restart --config rollbridge.js --policy companion
|
|
375
|
+
```
|
|
376
|
+
|
|
191
377
|
Shut down the daemon and managed processes:
|
|
192
378
|
|
|
193
379
|
```bash
|
|
@@ -210,6 +396,10 @@ location / {
|
|
|
210
396
|
}
|
|
211
397
|
```
|
|
212
398
|
|
|
399
|
+
See [`docs/nginx.md`](docs/nginx.md) for the full guide — WebSocket upgrade
|
|
400
|
+
headers, timeouts for long-lived connections, forwarded headers, and common
|
|
401
|
+
failure modes (502/503, dropped WebSockets).
|
|
402
|
+
|
|
213
403
|
## Running under systemd
|
|
214
404
|
|
|
215
405
|
Run the long-lived daemon as a systemd service so it starts on boot and is
|
|
@@ -246,6 +436,8 @@ absolute CLI path for `ExecStart`.
|
|
|
246
436
|
|
|
247
437
|
Run migrations before `rollbridge deploy`, and keep migrations backwards-compatible while old and new web releases overlap. For stable local brokers such as Velocious Beacon or `background-jobs-main`, use `service` when the process should survive deploys and restart from the latest successful release if it crashes.
|
|
248
438
|
|
|
439
|
+
See [`docs/deploy-recipes.md`](docs/deploy-recipes.md) for ready-to-use shell, CI, and Capistrano recipes that drive Rollbridge through its CLI, and [`docs/troubleshooting.md`](docs/troubleshooting.md) for diagnosing health-check failures, port conflicts, stale sockets, crash loops, and stuck draining releases.
|
|
440
|
+
|
|
249
441
|
## Releasing
|
|
250
442
|
|
|
251
443
|
Maintainers can publish a patch release from the latest default branch:
|
|
@@ -253,3 +445,11 @@ Maintainers can publish a patch release from the latest default branch:
|
|
|
253
445
|
```bash
|
|
254
446
|
npm run release:patch
|
|
255
447
|
```
|
|
448
|
+
|
|
449
|
+
The release script owns the package version bump, lockfile update, default-branch
|
|
450
|
+
commit, push, and npm publish. Do not run `npm version` manually before running
|
|
451
|
+
it.
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
Rollbridge is released under the [MIT License](LICENSE).
|
package/TODO.md
CHANGED
|
@@ -26,9 +26,9 @@ This roadmap tracks planned Rollbridge features and documentation. Rollbridge sh
|
|
|
26
26
|
- [ ] Restart memory-heavy workers gracefully when possible, with a forced stop timeout.
|
|
27
27
|
- [ ] Add tests with a fixture process that allocates memory above the configured limit.
|
|
28
28
|
- [ ] Worker auto-restart and restart policy controls.
|
|
29
|
-
- [
|
|
29
|
+
- [x] Add config for max restarts, restart window, exponential backoff, and disabled restart behavior (per-process `restart` policy).
|
|
30
30
|
- [ ] Distinguish crash restarts, deploy replacements, manual restarts, and memory restarts in status/events.
|
|
31
|
-
- [
|
|
31
|
+
- [x] Add a `restart` CLI command for a single process, a policy group, or all non-proxied workers.
|
|
32
32
|
- [ ] Keep restart behavior safe for job workers by using lifecycle hooks before termination.
|
|
33
33
|
- [ ] Graceful job-worker lifecycle.
|
|
34
34
|
- [ ] Add generic lifecycle hooks such as `quietCommand`, `drainCommand`, `drainTimeoutMs`, and `stopCommand`.
|
|
@@ -52,13 +52,16 @@ This roadmap tracks planned Rollbridge features and documentation. Rollbridge sh
|
|
|
52
52
|
- [ ] Document migration constraints for rollback.
|
|
53
53
|
- [ ] Observability and diagnostics.
|
|
54
54
|
- [ ] Add structured event history for deploys, switches, stops, crashes, memory restarts, and failed commands.
|
|
55
|
-
- [
|
|
56
|
-
- [ ] Add
|
|
55
|
+
- [x] Add restart counters and uptime to status (exit reasons already reported via `exitCode`/`exitSignal`/`state`).
|
|
56
|
+
- [ ] Add memory stats and child-process-tree details to status (with memory supervision).
|
|
57
|
+
- [x] Add a `logs` CLI command (recent per-process output from status).
|
|
58
|
+
- [ ] Add an `events` CLI command (after structured event history lands).
|
|
57
59
|
- [ ] Add optional file logging with rotation guidance.
|
|
58
|
-
- [
|
|
60
|
+
- [x] Add machine-readable JSON output for all CLI commands (data commands print JSON; `validate`/`doctor`/`logs` take `--json`).
|
|
59
61
|
- [ ] Config validation and doctoring.
|
|
60
62
|
- [x] Add `validate` to parse config and report all config errors without starting the daemon.
|
|
61
|
-
- [
|
|
63
|
+
- [x] Add `doctor` to check config validity, control socket reachability, proxy port availability, and control-socket directory writability.
|
|
64
|
+
- [ ] Extend `doctor` with process-command, release-path, and log/state-path checks once those are resolvable (rendered templates, persisted state).
|
|
62
65
|
- [x] Validate duplicate process IDs, missing ports on proxied processes, invalid ranges, and the single-proxied-process policy rule.
|
|
63
66
|
- [ ] Validate unsupported lifecycle-hook combinations once worker lifecycle hooks land.
|
|
64
67
|
- [x] Include example fixes in validation output.
|
|
@@ -68,30 +71,30 @@ This roadmap tracks planned Rollbridge features and documentation. Rollbridge sh
|
|
|
68
71
|
- [x] Add a control-socket permission option (`control.mode`) for shared deploy users.
|
|
69
72
|
- [ ] Add control-socket owner/group options for shared deploy users (needs name-to-id resolution).
|
|
70
73
|
- [x] Make stale control socket diagnostics clearer when another daemon is still alive.
|
|
71
|
-
- [
|
|
74
|
+
- [x] Add old-release cleanup policies by age, count, and stopped state (`releaseRetention`).
|
|
72
75
|
- [x] Add port allocation diagnostics when a range is exhausted.
|
|
73
|
-
- [
|
|
76
|
+
- [x] Add an optional startup delay (`health.startDelayMs`) before health checks begin.
|
|
74
77
|
- [x] Add process output retention config instead of a fixed recent-log count.
|
|
75
78
|
- [x] Add environment variable interpolation from the daemon environment.
|
|
76
79
|
- [x] Add `--config` default lookup resolving to `rollbridge.js` when no path is given.
|
|
77
80
|
- [ ] Add shell completion generation for common shells.
|
|
78
|
-
- [
|
|
81
|
+
- [x] Add npm package metadata such as repository, license, bugs, and homepage.
|
|
79
82
|
- [x] Add systemd service examples for the Rollbridge daemon.
|
|
80
83
|
- [x] Add tests for malformed control socket JSON and unknown control commands.
|
|
81
|
-
- [
|
|
84
|
+
- [x] Add tests for duplicate IDs and singleton replacement failure behavior.
|
|
82
85
|
- [x] Add tests for proxy behavior when the active release exits unexpectedly.
|
|
83
86
|
|
|
84
87
|
## Documentation TODO
|
|
85
88
|
|
|
86
|
-
- [
|
|
87
|
-
- [
|
|
88
|
-
- [
|
|
89
|
+
- [x] Write a full config reference covering every field, default, and template variable (`docs/config.md`).
|
|
90
|
+
- [x] Write a CLI reference for `daemon`, `ensure-daemon`, `deploy`, `status`, `stop`, `shutdown`, and future commands (`docs/cli.md`).
|
|
91
|
+
- [x] Expand process policy docs with deployment examples for `proxied`, `companion`, `singleton`, and `service`.
|
|
89
92
|
- [ ] Document memory checks and auto-restart behavior after the feature lands.
|
|
90
93
|
- [ ] Document worker lifecycle hooks and safe background-job deployment patterns after the feature lands.
|
|
91
|
-
- [
|
|
92
|
-
- [
|
|
93
|
-
- [
|
|
94
|
-
- [
|
|
94
|
+
- [x] Add a Velocious deployment guide with Beacon, background-jobs-main, background-jobs-worker, and web process examples (`docs/velocious.md`).
|
|
95
|
+
- [x] Add an Nginx guide with WebSocket headers, timeouts, and common failure modes (`docs/nginx.md`).
|
|
96
|
+
- [x] Add deploy-tool recipes that call Rollbridge CLI commands directly (`docs/deploy-recipes.md`).
|
|
97
|
+
- [x] Add a Capistrano recipe showing shell commands only; do not add a Capistrano plugin or Rollbridge-specific Capistrano tasks (`docs/deploy-recipes.md`).
|
|
95
98
|
- [ ] Add a TensorBuzz-specific runbook for current production ports, external services, deploy ordering, and rollback constraints.
|
|
96
|
-
- [
|
|
99
|
+
- [x] Add troubleshooting docs for health-check failures, port conflicts, stale sockets, crash loops, and stuck draining releases (`docs/troubleshooting.md`).
|
|
97
100
|
- [ ] Add a release checklist for maintainers using `npm run release:patch`.
|
package/docs/cli.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Rollbridge CLI reference
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
rollbridge <command> [options]
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
This reference covers every current command. See the README for config and
|
|
8
|
+
process-policy details.
|
|
9
|
+
|
|
10
|
+
## Global behavior
|
|
11
|
+
|
|
12
|
+
- **`-c, --config <path>`** is accepted by every command and is optional. When
|
|
13
|
+
omitted, Rollbridge loads `rollbridge.js` from the current directory (a
|
|
14
|
+
JavaScript module that `export default`s the config object or a function
|
|
15
|
+
returning it).
|
|
16
|
+
- Commands that talk to a running daemon — `deploy`, `status`, `stop`,
|
|
17
|
+
`shutdown`, and `logs` — connect to the control socket (`control.path`). They
|
|
18
|
+
fail with an error if no daemon is listening; start one first with
|
|
19
|
+
`rollbridge daemon` or `rollbridge deploy --ensure-daemon`.
|
|
20
|
+
- `validate`, `doctor`, and `logs` accept `--json` for machine-readable output.
|
|
21
|
+
`deploy`, `status`, `stop`, `shutdown`, and `ensure-daemon` always print JSON.
|
|
22
|
+
|
|
23
|
+
## `daemon`
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
rollbridge daemon [--config <path>]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Runs the supervisor in the foreground: binds the stable proxy port and the
|
|
30
|
+
control socket and stays running. On `SIGINT`/`SIGTERM` it stops its managed
|
|
31
|
+
processes, closes the servers, removes the control socket, and exits `0`.
|
|
32
|
+
Structured JSON log lines are written to stdout. Run it under a process manager
|
|
33
|
+
such as systemd (see `examples/rollbridge.service`).
|
|
34
|
+
|
|
35
|
+
## `ensure-daemon`
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
rollbridge ensure-daemon [--config <path>]
|
|
39
|
+
[--daemon-log-path <path>]
|
|
40
|
+
[--daemon-pid-path <path>]
|
|
41
|
+
[--daemon-start-timeout-ms <ms>]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Starts the daemon as a detached process **only if** the control socket is not
|
|
45
|
+
already accepting commands, waits until it responds, then prints the daemon
|
|
46
|
+
status JSON. Idempotent — safe to call before every deploy.
|
|
47
|
+
|
|
48
|
+
- `--daemon-log-path <path>` — file the detached daemon's stdout/stderr is
|
|
49
|
+
appended to. Default: `/tmp/rollbridge-<application>.log`.
|
|
50
|
+
- `--daemon-pid-path <path>` — file the detached daemon's PID is written to.
|
|
51
|
+
Default: `/tmp/rollbridge-<application>.pid`.
|
|
52
|
+
- `--daemon-start-timeout-ms <ms>` — how long to wait for the daemon to accept
|
|
53
|
+
control commands before failing. Default: `10000`.
|
|
54
|
+
|
|
55
|
+
## `deploy`
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
rollbridge deploy --release-path <path>
|
|
59
|
+
[--config <path>]
|
|
60
|
+
[--release-id <id>]
|
|
61
|
+
[--revision <sha>]
|
|
62
|
+
[--ensure-daemon]
|
|
63
|
+
[--daemon-log-path <path>]
|
|
64
|
+
[--daemon-pid-path <path>]
|
|
65
|
+
[--daemon-start-timeout-ms <ms>]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Starts the prepared release, health-checks the proxied process, switches new
|
|
69
|
+
traffic to it, then drains and stops the previous release. Prints
|
|
70
|
+
`{"status": "success", "activeReleaseId": "...", "previousReleaseId": "..."}`.
|
|
71
|
+
If the new release fails to start or health-check, the previous release stays
|
|
72
|
+
active and the command errors.
|
|
73
|
+
|
|
74
|
+
- `--release-path <path>` (**required**) — path to the prepared release
|
|
75
|
+
directory; available to process templates as `{{releasePath}}`.
|
|
76
|
+
- `--release-id <id>` — identifier for the release. Defaults to `--revision`,
|
|
77
|
+
or a timestamp when neither is given.
|
|
78
|
+
- `--revision <sha>` — VCS revision; available as `{{revision}}`.
|
|
79
|
+
- `--ensure-daemon` — start the daemon first if it isn't running (honors the
|
|
80
|
+
same `--daemon-*` options as `ensure-daemon`).
|
|
81
|
+
|
|
82
|
+
## `status`
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
rollbridge status [--config <path>]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Prints the daemon status JSON: the active release id, the proxy address, and —
|
|
89
|
+
per release, service, and singleton process — its `state`, `pid`, automatic
|
|
90
|
+
`restarts`, `startedAt`, `uptimeMs`, last `exitCode`/`exitSignal`, and recent
|
|
91
|
+
`logs`.
|
|
92
|
+
|
|
93
|
+
## `stop`
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
rollbridge stop [--config <path>] [--release-id <id>]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Stops the active release (or the release named by `--release-id`) and prints the
|
|
100
|
+
updated status JSON. With no active release, the proxy answers `503` until the
|
|
101
|
+
next deploy.
|
|
102
|
+
|
|
103
|
+
## `restart`
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
rollbridge restart [--config <path>] [--process <id>] [--policy <policy>]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Restarts **non-proxied** processes and prints `{"restarted": [<ids>]}`. Like
|
|
110
|
+
`systemctl restart`, a running process is bounced (stop, then start) and a
|
|
111
|
+
crashed or stopped one is revived — so this is also how you bring back a process
|
|
112
|
+
that exhausted its `restart` budget (see [`config.md`](config.md#processesrestart)).
|
|
113
|
+
Selectors:
|
|
114
|
+
|
|
115
|
+
- no selector — restart every non-proxied process (companions, singletons, and services);
|
|
116
|
+
- `--process <id>` — restart only that process;
|
|
117
|
+
- `--policy <companion|singleton|service>` — restart only processes with that policy.
|
|
118
|
+
|
|
119
|
+
The proxied process is never restarted in place — that would drop traffic.
|
|
120
|
+
Targeting it (by id or `--policy proxied`) is an error; use `rollbridge deploy`
|
|
121
|
+
for a zero-downtime replacement. `--process <id>` with an id that is not a
|
|
122
|
+
managed process (unknown, or a companion with no active release) is also an
|
|
123
|
+
error. Restarting a `service` bounces a shared broker (for example Velocious
|
|
124
|
+
Beacon), which briefly disrupts every process that depends on it.
|
|
125
|
+
|
|
126
|
+
## `shutdown`
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
rollbridge shutdown [--config <path>]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Stops all managed processes (services, singletons, and releases), closes the
|
|
133
|
+
proxy and control socket, removes the socket file, and prints
|
|
134
|
+
`{"status": "success", "message": "shutdown"}`.
|
|
135
|
+
|
|
136
|
+
## `validate`
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
rollbridge validate [--config <path>] [--json]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Parses and validates the config without starting the daemon, reporting every
|
|
143
|
+
issue with an example fix. Exits `1` when issues are found. With `--json`, prints
|
|
144
|
+
`{"config": {...} | null, "issues": [{"message", "fix"}], "path", "valid"}`.
|
|
145
|
+
|
|
146
|
+
## `doctor`
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
rollbridge doctor [--config <path>] [--json]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Validates the config, then probes the environment: whether a daemon already
|
|
153
|
+
holds the control socket, whether the control socket's directory is writable,
|
|
154
|
+
and whether the proxy port can be bound. Exits `1` when any check fails (so a
|
|
155
|
+
green `doctor` means a fresh daemon can start). With `--json`, prints
|
|
156
|
+
`{"checks": [{"name", "ok", "detail"}], "ok"}`.
|
|
157
|
+
|
|
158
|
+
## `logs`
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
rollbridge logs [--config <path>] [--process <id>] [--json]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Prints the recent stdout/stderr retained per managed process — a one-shot
|
|
165
|
+
snapshot of each process's `outputLines`, not a live stream. `--process <id>`
|
|
166
|
+
limits output to one process. With `--json`, prints
|
|
167
|
+
`[{"id", "source", "logs": [{"at", "line", "stream"}]}]`.
|
|
168
|
+
|
|
169
|
+
## Exit codes
|
|
170
|
+
|
|
171
|
+
- `0` — success.
|
|
172
|
+
- `1` — `validate`/`doctor` found problems, or `--config` could not be resolved.
|
|
173
|
+
- non-zero (with an error message) — a daemon command could not reach the daemon,
|
|
174
|
+
or the daemon returned an error.
|