docker: make log rotation a preference, 100m x 10 by default, judged by a step before daemon.json takes it (novox/hq issue 452)
mesh/merge-gate pass: builds docker → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery covered after its failure: a later walk that contains it was delivered: plan-1791734868297400826 (novox/mesh-catalog at 0a558319 into main,…

The controller pastes a setting into daemon.json as text and the runtime is its
only reader, so a bad size would surface as a runtime that does not start and a
quote could add any key. A step refuses the value first and gates the module.
The defaults are the one hand-set machine's, so it does not change; nothing
restarts the runtime, which takes the keys at its next start.
This commit is contained in:
2026-10-11 04:43:14 +02:00
parent 33ee89794e
commit 9a1a97cc43
5 changed files with 379 additions and 4 deletions
+26 -3
View File
@@ -14,7 +14,9 @@ tools below are the module's own.
| `socket` | `docker.socket` running, enabled at boot | given back as found when the module goes (ADR 0118) |
| `prune-service`, `prune-timer` | `/etc/systemd/system/docker-prune.{service,timer}`, written whole | removed with the module |
| `prune` | `docker-prune.timer` running, enabled at boot; restarted when either file changes | stopped and disabled with the module (the mesh made the unit) |
| `daemon` | `live-restore` and the mesh's registry in `insecure-registries` written into `/etc/docker/daemon.json`, beside other keys | each key given back as found when the module goes; only the member this module added leaves the list |
| `state`, `log-rotation` | the module's own directory, and in it `log-rotation.conf`: the settings `log-max-size` and `log-max-file` as the step judges them (0600) | removed with the module |
| `log-rotation-check` | a step, `docker-tools check-log-rotation`, run as root when `log-rotation` changes; it refuses a bad value, and the rest of the module (`daemon` with it) is then skipped | removed with the module |
| `daemon` | `live-restore`, the mesh's registry in `insecure-registries`, `log-driver` and `log-opts` written into `/etc/docker/daemon.json`, beside other keys | each key given back as found when the module goes; only the member this module added leaves the list |
| `runtime` | `docker.service` running, enabled at boot; reloaded, never restarted, when `daemon` changes | given back as found (ADR 0118) |
The weekly prune takes **dangling images and build cache unused for a week, and nothing else**. It
@@ -64,8 +66,27 @@ once, for `daemon`. The address is the same one, so the runtime's trust does not
Still elsewhere:
- **Nobody** writes log rotation. One machine has `log-driver` and `log-opts` by hand; they are left
as they are until a size is chosen for every machine.
## Log rotation (novox/hq issue 452)
`daemon` writes `"log-driver": "json-file"` and `"log-opts": {"max-size": …, "max-file": …}` from two
preferences: `log-max-size` (default `100m`) and `log-max-file` (default `10`), about 1 GB of log per
container. The defaults are what the one machine with rotation set by hand already had, so that machine
does not change; the others gain rotation. Both settings are terminal-only (`"trusted": true`).
**A bad value never reaches `daemon.json`.** The controller pastes a setting into a file as text and judges
only that it is one line (novox/hq issue 346), and the runtime is the only reader of `daemon.json`: a bad
size would be found as a runtime that does not start, and a quote could add any key. So the same two values
are written into `log-rotation.conf` first, and the step `log-rotation-check` judges them before `daemon`
is applied: a size is a whole number from 1 with `k`, `m` or `g` after it, a count is 1 to 99. Refused, the
step fails, the host skips the rest of this module (ADR 0136), `daemon.json` keeps what it had, and the
apply's report names the setting.
**Nothing restarts.** The runtime reads `log-driver` and `log-opts` only when it starts. A change to
`daemon` reloads it, as before; the reload takes neither key, and stops no container. The new rotation
holds from the runtime's next start (the machine's next boot, for one), and then only for
containers created after it: a container keeps the log options it was created with until it is created
again. `docker_daemon_config` lists the keys the daemon has not taken yet.
## What it does not declare yet, and why
@@ -242,6 +263,8 @@ The tests run against a fake runner and cover:
- a printed secret found by name and never answered by value, in the scan and in `docker_logs`;
- size parsing;
- what the daemon has not yet taken;
- the log rotation: the defaults `daemon.json` takes, the step declared before `daemon`, a bad size or
count refused, a good one read, and the runtime never restarted for it;
- event filtering;
- volume ownership;
- that the tools served are exactly the manifest's `tools`.