v0.20.0: golden stacks-dir bind + per-guest hostname/CT + bake base-infra images

build-golden.sh: same-path /opt/docker/stacks host bind (Section-G fix, breaks
all bind-mounted stacks without it) + --hostname <customer-id> from bootstrap.json
(portable sed parse, no jq) + bake the 3 pinned public base-infra images with a
manifest-inspect hard gate. Provision --selftest defaults -hostname to the
DNS-safe-sanitized customer-id so the CT/LXC is named meaningfully.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 14:56:57 +02:00
parent de34d170d2
commit cfebdf5cd4
3 changed files with 100 additions and 7 deletions
+26
View File
@@ -3,6 +3,32 @@
All notable changes to **felhom-agent** are recorded here. Update on every code
change that gets pushed.
## v0.20.0 — golden: stacks-dir bind + per-guest hostname/CT name + bake base-infra images (2026-06-11)
Lockstep with `felhom-controller` v0.41.0 + a golden rebake. Changes in `configs/build-golden.sh` and
the provision path; no change to the proxmox/authz/token fences.
- **Section-G mount fix (the load-bearing one):** the in-guest controller writes app/infra compose
stacks under `/opt/docker/stacks` *inside its container*, but the baked controller-bootstrap `docker run`
never bind-mounted that path. So `docker compose up` (run by the GUEST daemon over the shared socket)
resolved every relative bind source on the guest filesystem — silently creating empty dirs — which
broke **every** bind-mounted stack (base infra AND customer apps like immich/nextcloud). The bootstrap
unit now `mkdir -p /opt/docker/stacks` and adds a **same-path host bind**
`-v /opt/docker/stacks:/opt/docker/stacks` (a named volume would NOT fix this). Empirically confirmed on
guest 9201 before writing the fix.
- **Per-guest container hostname (3A):** the bootstrap unit derives `customer.id` from
`/etc/felhom-bootstrap/bootstrap.json` with a portable `sed` parse (NO jq in the golden) and passes
`--hostname <customer-id>` to `docker run`, so the controller's `os.Hostname()` (its hub-reported
hostname) is the customer id, not the Docker container ID. Fail-safe: no parse → no `--hostname`.
- **Per-guest CT/LXC name (3B):** `--selftest=provision` now defaults `-hostname` to the (DNS-safe
sanitized) `-customer-id` when not given, so the bring-up's existing `SetConfig hostname` step
(`bringup.go`) names the CT meaningfully (e.g. `demo-felhom`) instead of inheriting the golden's
`felhom-golden`. New `sanitizeHostname` (lowercase, collapse invalid → `-`, trim, ≤63).
- **Bake base-infra images:** the golden now also pulls the three PINNED, PUBLIC base-infra images
(`traefik:v3.6.7`, `cloudflare/cloudflared:2026.6.0`, `gtstef/filebrowser:1.3.3-stable`) into its Docker
storage so the controller's first-boot bring-up is OFFLINE-capable. A hard gate (`docker manifest
inspect`) fails the bake early on a bad pin. Tags MUST match the controller's `internal/infra` constants.
## v0.19.0 — bootstrap contract v2: agent relays the hub retrieval passphrase (no host key in the guest) (2026-06-11)
Lockstep with `felhom-controller` v0.40.0. Fixes the onboarding 401: a freshly provisioned guest's