3.6 KiB
3.6 KiB
name, description
| name | description |
|---|---|
| dankclaw-expose-service | Expose a new service at *.franksdank.cloud on Dankclaw: quadlet container, Caddy site block, Pi-hole LAN record (custom.list), Porkbun public record; includes API vhost/volume gotchas proven on the ntfy deploy. |
Expose a service on Dankclaw (franksdank.cloud)
Proven end-to-end 2026-10-11 with ntfy. Four layers, each with a known trap.
0. Survey first
ssh dankclaw 'ls ~/.config/containers/systemd/; grep -nE "franksdank|anubis" /home/dank/Containers/caddy/Caddyfile'
- Caddy runs as quadlet
caddy.container; config at/home/dank/Containers/caddy/Caddyfile(NOT/etc/caddyon host). - Sites fronted by
anubis:8923get bot-challenge. CLI/API publishers (ntfy, webhooks, git) MUST bypass anubis — use thegitea/aipattern (directreverse_proxy).
1. Quadlet container (user dank)
Write ~/.config/containers/systemd/<name>.container:
[Unit]
Description=<name>
After=network-online.target
Wants=network-online.target
[Container]
ContainerName=<name>
Image=<image>
Network=dankclaw_default
Volume=<name>-cache:/var/lib/<name>
[Service]
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
Network=dankclaw_default ⇒ Caddy reaches it as <name>:<port>. Then systemctl --user daemon-reload && systemctl --user start <name>.service.
Rootless podman: bare containers never boot-persist — quadlet is mandatory.
2. Caddy route
Append site block (wildcard *.franksdank.cloud cert already issued via Porkbun DNS-01; no new cert work):
<name>.franksdank.cloud {
reverse_proxy <name>:<port>
}
Validate, then reload in-place:
podman exec caddy caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
podman exec caddy caddy reload --config /etc/caddy/Caddyfile
3. LAN DNS (Pi-hole v6, container pihole)
Traps, in order of wasted turns:
- API is NOT at
127.0.0.1:8083/apion the host port path — requests need-H "Host: pi.hole". [[dns.records]]in pihole.toml andgravity.dbdomaintable: absent/unused on this box.- Working location:
/home/dank/Containers/pihole/etc-pihole/hosts/custom.list(dnsmasq addn-hosts), formatIP FQDN:
echo "192.168.0.143 <name>.franksdank.cloud" | sudo tee -a /home/dank/Containers/pihole/etc-pihole/hosts/custom.list >/dev/null
podman exec pihole pihole restartdns
4. Public DNS (Porkbun, for off-LAN clients)
Keys: /home/dank/Containers/caddy/env (PORKBUN_API_KEY, PORKBUN_API_SECRET_KEY).
curl -sL -X POST https://api.porkbun.com/api/json3/domain/api/create/franksdank.cloud \
-H "Content-Type: application/json" \
-d "{\"apikey\":\"$K\",\"secretapi\":\"$S\",\"name\":\"<name>\",\"type\":\"A\",\"content\":\"71.227.227.172\",\"ttl\":\"600\"}"
json3path +-L(302-redirects to v3). Public IP: 71.227.227.172 (router forwards 443 → Dankclaw).- Porkbun edge throws intermittent 503s; retry later or do it in the UI. LAN path works without this record.
5. Verify
# from Dankclaw (host): getent hosts <name>.franksdank.cloud → 192.168.0.143
# workstation w/ stale resolved negative cache: use curl --resolve <name>.franksdank.cloud:443:192.168.0.143
# workstation's own `sudo resolvectl flush-caches` needs a terminal (no passwordless sudo) — negative cache expires on its own
curl -sf --resolve <name>.franksdank.cloud:443:192.168.0.143 https://<name>.franksdank.cloud/
Publish-style test for ntfy inside container (CLI flags vary by version; raw HTTP is version-proof):
podman exec <name> wget -qO- --header="Title: smoke" --post-data="up" http://localhost:<port>/<topic>