caddy + pihole: make both boot-persistent and self-healing
Caddy left compose.yaml for a quadlet unit (caddy.service): joins dankclaw_default for container-name upstreams, Pull=never for the local-only image, Porkbun credentials via /home/dank/Containers/caddy/env written by deploy from .env, bare-IP-catch-all health check. deploy_caddy installs, enables, and starts the unit after retiring the bare container (state is in host volumes). Pi-hole: the repo now owns the sysctl drop-in (dankclaw/pihole/sysctl/99-dnsmasq.conf, ip_unprivileged_port_start=53); deploy_pihole installs it to /etc/sysctl.d/, stages conflicting later-sorted drop-ins in the home trash, and applies 'sysctl --system' (the boot code path). This fixes the 2026-08-26 crash loop (port-53 bind denied, restart counter 1645) caused by a second drop-in resetting the value to 80. Tests: new caddy_quadlet.bats seam; caddyfile/deployment_flow assertions repointed from the removed compose service to the quadlet; pihole.bats pins the sysctl drop-in and its deployment; test-changed.sh routes dankclaw/caddy/ and the pihole subtree to their seams. Docs: Caddy, Pi-hole, Dankclaw Stack, work log.
This commit is contained in:
1 parent
66b58a127b
commit
8660209c35
14 files changed
+248
-60
No files matched your search
@@ -9,6 +9,7 @@ Pi-hole is the LAN DNS server for the homelab. It runs as a quadlet container on
|
||||
| `pihole` quadlet | `dankclaw/pihole/quadlet/pihole.container` | Boot-persistent container unit |
|
||||
| FTL | `docker.io/pihole/pihole:latest` | DNS engine (a dnsmasq fork) + ad blocking |
|
||||
| `addn-hosts` | `dankclaw/pihole/addn-hosts` | One A record per Caddy vhost |
|
||||
| sysctl drop-in | `dankclaw/pihole/sysctl/99-dnsmasq.conf` (repo) → `/etc/sysctl.d/` | Rootless port-53 threshold, applied at boot |
|
||||
| env file | `/home/dank/Containers/pihole/env` (host) | `ServerIP`, `TZ`, `DNS1`, `DNS2`, `WEBPASSWORD` |
|
||||
| Web UI | `pihole.franksdank.cloud` (Caddy → 8083) | Dashboard + admin, family login |
|
||||
|
||||
@@ -49,7 +50,7 @@ The slirp netns has no useful `resolv.conf`. The env file pins the upstreams: `D
|
||||
|
||||
## Host prerequisites
|
||||
|
||||
1. `sysctl net.ipv4.ip_unprivileged_port_start=53` (persisted in `/etc/sysctl.d/99-dnsmasq.conf`) — rootless Podman may then publish port 53.
|
||||
1. `net.ipv4.ip_unprivileged_port_start=53`, persisted in `/etc/sysctl.d/99-dnsmasq.conf` — rootless Podman may then publish port 53. The repo file `dankclaw/pihole/sysctl/99-dnsmasq.conf` is the single source of truth: `deploy_pihole` installs it, stages any later-sorted drop-in that resets the value in the home trash, and applies it with `sysctl --system` (the same code path boot uses via systemd-sysctl). **Incident (2026-08-26):** a second drop-in (`99-rootless-ports.conf`, sorted after) reset the value to 80. The runtime override from an earlier manual `sysctl -w` died with a reboot, and `pihole.service` crash-looped on `bind: permission denied` for port 53 (restart counter 1645) until the conflict was removed.
|
||||
2. `DNSStubListener=no` in `/etc/systemd/resolved.conf` — the resolved stub would otherwise hold port 53 inside the container netns.
|
||||
|
||||
Both prerequisites survive the dnsmasq → Pi-hole swap. Do not remove them.
|
||||
@@ -62,6 +63,7 @@ Both prerequisites survive the dnsmasq → Pi-hole swap. Do not remove them.
|
||||
| A name does not resolve for a new client | The client's `resolv.conf` does not show `192.168.0.143` — the G36 hand-off is missing. See [[LAN-DNS]] |
|
||||
| The web UI asks for a password loop | `WEBPASSWORD` in the env file is the placeholder `changeme` — fill the real value, restart the unit |
|
||||
| Upstream queries fail (local names still answer) | `DNS1`/`DNS2` in the env file are missing or wrong |
|
||||
| Port 53 `bind: permission denied` crash loop after a reboot | sysctl conflict: exactly one file under `/etc/sysctl.d/` may set `ip_unprivileged_port_start`, and it must say 53. Redeploy pihole — `deploy_pihole` reinstalls the drop-in and neutralizes conflicts |
|
||||
| Single-label name (for example `dankclaw`) answers `127.0.1.1` | The rootless container `/etc/hosts` carries the host entry (`127.0.1.1 <host>`), and FTL serves it. Use the FQDN, or add an `/etc/hosts` entry on the client |
|
||||
|
||||
## See Also
|
||||
|
||||
Reference in new issue
Block a user