The podman quadlet generator fails with "unsupported key 'CapAdd' in group
'Container'" and skips the whole unit. The correct key is AddCapability=
(maps to podman --cap-add). Update the gluetun unit and its test seam.
Remove gluetun/searxng/valkey from dankclaw/compose.yaml (they are now
quadlet units) so podman-compose up can no longer fight them for the netns and
port 8081. Add scripts/deploy-searxng-quadlet.sh: an idempotent installer that
copies the units to ~/.config/containers/systemd/, daemon-reloads, enables them
for boot, and starts them in dependency order. Safe to run on first migration
and on every later change.
Converts the podman-compose SearXNG stack to boot-persistent quadlet units so
it survives a reboot (the compose deployment did not). searxng sets
Network=gluetun.container, which makes it reuse gluetun's network namespace so
outbound search traffic exits the WireGuard tunnel; it publishes no port of its
own (the port lives on gluetun). gluetun and valkey join a pinned searxng
network (10.89.2.0/24, DNS-enabled) so searxng reaches valkey by name.
Secrets stay in /opt/searxng/.env (mode 0600), referenced via [Service]
EnvironmentFile= so ${VAR} expands. Adds a bats seam asserting the netns
wiring, port placement, boot install, and that no secret material is tracked.
The :8000 status server 404s on every path and the image has no curl, so the
prior healthchecks could not pass. Check /sys/class/net/tun0 instead: it exists
only while the WireGuard tunnel is connected, so the healthcheck reflects real
VPN state.
The gluetun image ships wget, not curl, and its status server answers 200 at
/ on port 8000 (not /health). The old curl-based healthcheck always failed, so
the container read 'unhealthy' even with a working tunnel. Use wget against /.
The host has no unqualified-search registries in registries.conf, so the
short names qmcgaw/gluetun and valkey/valkey did not resolve and the pull
hung. Qualify them with docker.io/ so the pull works on any host.
The compose only forwarded VPN_SERVICE_PROVIDER, VPN_TYPE and the private
key, so Gluetun could not form a tunnel. Forward the peer public key,
endpoint IP/port, addresses, allowed IPs and keepalive interval. Add
matching placeholders to .env.example (current Gluetun uses the
single-peer WIREGUARD_* model, not the old WIREGUARD_PEERS_* names).
unattended-upgrades rebooted dankclaw at 15:01; the legacy
podman-compose gitea stack had no systemd units, so rootless podman
did not auto-start the containers. Gitea was down ~1 hour.
- add quadlet units (dankclaw/gitea/quadlet/): gitea-postgres,
gitea-server, gitea-caddy + gitea.network (DNS enabled; the default
rootless podman network has dns_enabled=false)
- add gitea stack Caddyfile (upstream gitea-server:3000) and
.env.example; live password stays in /opt/gitea/.env (0600)
- fix latent name bugs in main stack config: DATABASE_HOST
gitea-postgres, Caddyfile upstream gitea-server
- docs: rewrite Gitea page for the quadlet stack (management, boot
persistence, secrets, gotchas, incident log); fix port 3000 in
stack table; Postgres connection notes
- legacy compose retired on target to /opt/gitea/.deprecated/