ReviewOS

also looking at this

stacks/ts-cloud

fix: honor release-local background runtimes

#198
Merged chris wants to merge codex/release-local-background-runtime into main
13 files +724 -35
docs/config.mdmodified+54-0
Changes to docs/config.md
@@ -448,6 +448,60 @@ sharedPaths: [{ path: 'database/app.sqlite', target: '/var/www/acme-app/shared/d
448448Each site installs under its own base, so a plain string would give each of them
449449a database of its own. `seed: false` marks the sites that do not own the file.
450450
451### Background services and release-local Bun
452
453Stacks server sites can select a Bun executable shipped inside each release for
454their scheduler and queue workers:
455
456```typescript
457sites: {
458 main: {
459 root: '.',
460 start: 'bun server.ts',
461 port: 3000,
462 backgroundBun: 'pantry/bun.com/v1.4.4/bin/bun',
463 scheduler: true,
464 queues: [{ queue: 'reports,emails', tries: 3, stopWaitSecs: 120 }],
465 },
466}
467```
468
469Install the selected executable into the release during your normal artifact
470build or `preStart` commands. This option does not install Bun, infer a runtime
471from `start`, or change the main service's start command. Omission retains the
472host Bun for background services. Laravel commands and arbitrary daemon commands
473retain their existing runtime behavior.
474
475The native deploy supplies its release ID. Selected scheduler and queue units
476use that physical `releases/<id>` directory for WorkingDirectory, ExecStart and
477child PATH from process launch. Switching `current` cannot redirect a running
478worker's later Bun children. Bun's default child environment is
479[captured at worker launch](https://bun.com/reference/bun/Spawn/BaseOptions).
480
481The selected path must be relative, contain only ASCII letters, digits, `_`,
482`.`, `/` and `-`, and end in `bun`. Empty, `.` and `..` segments are refused. Release-directory paths use the
483same ASCII characters.
484A symlink may resolve inside the same physical release, including a Pantry
485`.bin/bun` alias. Before loading application work, the native entry verifies the
486selected executable, its release containment, the running executable and the
487leading PATH entry. A missing or mismatched selection fails that process;
488there is no global-runtime retry.
489
490Selected Stacks queue names accept ASCII letters, digits and `_ . : , { } / @ + -`
491without spaces. Tuning values must be finite numbers. Whitespace, directives,
492systemd expansion characters and command fragments are refused before unit
493creation.
494
495For non-PHP server sites, background services reconcile after the new release's
496activation and any health gate, before old releases are pruned. Removing the
497last declared service still reconciles the empty desired set and stops its old managed units. When a deploy
498replaces an existing release ID, managed background work stops before that
499directory is reset. Stopped background services restart only after activation;
500a failed replacement can leave them stopped until a recovery deploy. Systemd's
501configured stop timeout bounds worker draining. The configured release
502retention count still applies after reconciliation. A refused stop or disable stops the deploy
503before unit-file removal and this pruning step.
504
451505### Liveness probe
452506
453507Every server-app site with a `port` gets a systemd timer,