From 4bb988824fd65c3b203128dc2f3a7010868bd886 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 11 May 2026 22:47:41 +0200 Subject: [PATCH] docs(ci): update nsenter example to Alpine, document alternatives considered Co-Authored-By: Claude Sonnet 4.6 --- docs/infrastructure/ci-gitea.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/infrastructure/ci-gitea.md b/docs/infrastructure/ci-gitea.md index f58bfde4..d54adcfa 100644 --- a/docs/infrastructure/ci-gitea.md +++ b/docs/infrastructure/ci-gitea.md @@ -27,12 +27,22 @@ Job containers are unprivileged and do not share the host's PID/mount/network na - name: Reload Caddy run: | docker run --rm --privileged --pid=host \ - ubuntu:22.04 \ - nsenter -t 1 -m -u -n -p -i -- /bin/systemctl reload caddy + alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d \ + sh -c 'apk add --no-cache util-linux -q && nsenter -t 1 -m -u -n -p -i -- /bin/systemctl reload caddy' ``` `nsenter -t 1 -m -u -n -p -i` enters the init process's mount, UTS, IPC, network, PID, and cgroup namespaces, giving `systemctl` a view of the real host systemd. No sudoers entry is required — the Docker socket already grants root-equivalent host access. +Alpine is used instead of Ubuntu: ~5 MB vs ~70 MB, and the digest is pinned to a specific sha256 so any upstream change requires an explicit Renovate bump PR. `util-linux` (which ships `nsenter`) is not part of the Alpine base image but is installed at run time in ~1 s from the warm VPS cache. + +#### Why not `sudo systemctl` in the job container? + +Job containers run as root inside an unprivileged Docker namespace. There is no systemd PID 1 inside the container — `systemctl` would attempt to reach a socket that does not exist. `sudo` is not present in container images and would not help even if it were. + +#### Why not Caddy's admin API? + +Caddy ships a localhost admin API at `:2019` by default. Job containers do not share the host network namespace, so they cannot reach `localhost:2019` on the host. Exposing `:2019` on a host-bound port to make it reachable would add a network attack surface with no benefit over the current approach. + ### Caddyfile symlink contract The deploy workflows reload Caddy to pick up committed Caddyfile changes. This relies on a symlink that must exist on the VPS: