docs(wiki): document scripts/booth.sh in container-deployment

Add a "Booth operator wrapper" section (commands, the update flow, env
handling, the volume/ledger safety notes) + a log entry.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-06-24 20:38:44 +02:00
parent 50dd554b43
commit b1c4109045
2 changed files with 39 additions and 1 deletions
+24 -1
View File
@@ -2,7 +2,7 @@
type: decision type: decision
tags: [parking, deployment, docker, ci, offline-first] tags: [parking, deployment, docker, ci, offline-first]
sources: [] sources: []
updated: 2026-06-22 updated: 2026-06-24
status: settled status: settled
--- ---
@@ -36,6 +36,29 @@ The **desktop** app stays on its own tag-only `release.yml` (Tauri installers),
`restart: always`, `fast_alpr`, vision kept internal). `REGISTRY`/`TAG` come from env, so a deploy `restart: always`, `fast_alpr`, vision kept internal). `REGISTRY`/`TAG` come from env, so a deploy
on a branch pulls that branch's image — the branch→environment mapping IS the override file. on a branch pulls that branch's image — the branch→environment mapping IS the override file.
## Booth operator wrapper — `scripts/booth.sh`
So the on-site operator runs one command instead of the long `docker compose -f … -f … --env-file …`
line, **`scripts/booth.sh`** wraps the base + override + env-file. **Prod by default** (the booth is
prod); `ENV=dev` switches to the dev override.
- `./scripts/booth.sh up` — start (detached). `down` / `restart` / `status` / `logs [service]` /
`pull` / `config` / `exec <svc> …` as expected.
- **`./scripts/booth.sh update`** — the "**I know there are new images**" path: `compose pull` the
moving branch tag, then `up -d --remove-orphans` (recreates only services whose image digest moved;
**named volumes — the SQLite ledger — are preserved**), then `docker image prune -f` to reclaim the
old layers. This is the routine update after a `dev`/`main` push republishes the branch tag.
- **Env handling.** Reads **`.env`** (copy from `.env.example`: `REGISTRY`, `TAG`, `JWT_SECRET`,
`EVENT_SIGNING_KEY`, `COOKIE_SECURE=0`, `WS_ALLOWED_ORIGINS`). Prod **refuses to run without
`.env`** (no safe `JWT_SECRET` default — `auth.ts` rejects weak ones). Dev with no `.env` injects
the documented benign local secret so `up` works out of the box. The base file makes `JWT_SECRET`
shell-required (`${JWT_SECRET:?}`), so the env-file is mandatory for both — the script surfaces that
early with a clear message rather than a raw compose interpolation error.
- **Safety:** `down` never passes `-v` (deleting `parking-data` would wipe the signed
[[append-only-event-chain|ledger]]); `help`/unknown-command short-circuit before any Docker/.env
requirement. The operator never types `JWT_SECRET` on the CLI — it lives in `.env` (the user
generates it with `openssl rand -hex 32`).
## Registry + CI ## Registry + CI
- Published to the house **Gitea registry** `git.infra.msai.al/mca/parking_solution/{parking-server, - Published to the house **Gitea registry** `git.infra.msai.al/mca/parking_solution/{parking-server,
+15
View File
@@ -1606,3 +1606,18 @@ the exact rendered bytes; probe present/absent; `transportFromConfig` TCP back-c
green (29). **Flagged open-questions #14**: confirm the on-site printer is USB and bake the green (29). **Flagged open-questions #14**: confirm the on-site printer is USB and bake the
**usblp + udev write-access** rule into the appliance image (provisioning, not app code; unverified on **usblp + udev write-access** rule into the appliance image (provisioning, not app code; unverified on
hardware). See [[printer-usb-transport]], [[rongta-printer]]. hardware). See [[printer-usb-transport]], [[rongta-printer]].
## [2026-06-24] build | Booth operator wrapper script — scripts/booth.sh
The booth PC (Ubuntu) needs one command instead of the long
`docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env …` line over the
three compose files. Added **`scripts/booth.sh`** (+ root **`.env.example`**): **prod by default**
(`ENV=dev` for the dev override); subcommands `up`/`down`/`restart`/`status`/`logs`/`pull`/`config`/
`exec`, and the requested **`update`** = `compose pull` the moving branch tag → `up -d --remove-orphans`
(recreates only digest-changed services, **named volumes/SQLite ledger preserved**) → `docker image
prune -f`. Prod **refuses to run without `.env`** (no safe `JWT_SECRET` default); dev with no `.env`
injects the documented benign local secret (the base file makes `JWT_SECRET` shell-required via
`${JWT_SECRET:?}`, which the dev override's service-level default alone can't satisfy). `down` never
passes `-v` (would wipe the signed [[append-only-event-chain|ledger]] volume); `help`/unknown-command
short-circuit before any Docker/.env requirement. Verified: prod `config` renders Caddy:80 + internal
server + pinned images + `fast_alpr`; dev `config` renders `:dev` images + `stub` + published ports.
Documented in [[container-deployment]] ("Booth operator wrapper").