See proxies "future optimization" sections for the motivation, here.
burrowd is my own custom service which mirrors the reverse-proxy configuration (resource/target mappings) from the remote Pangolin VPS instance to a local Pangolin instance. This avoids "trombone routing" — where LAN traffic destined for a local service would otherwise egress to the VPS and tunnel back — while keeping the same *.rileys.house domain names working seamlessly.
The stack runs on a dedicated LXC (burrowd, at 192.168.0.26) and consists of three Docker Compose services:
*.rileys.house traffic on the LAN. Uses mirrored Let's Encrypt certificates via a file provider (hot-reload, no ACME).acme.json from the VPS via read-only SSH/SFTP and extracts PEM files so Traefik can serve the real wildcard certificate.routes.yml into Traefik's file-provider directory, creating direct routes from each *.rileys.house hostname to its LAN IP:port — bypassing the VPS entirely.Local DNS (PiHole) resolves *.rileys.house → 192.168.0.26, so LAN clients hit burrowd's Traefik directly instead of routing through the VPS.
The previous iteration used Caddy as the local proxy because it has a friendlier management API than Traefik. The new approach avoids needing a proxy management API at all — burrowd writes static route files that Traefik hot-reloads via its file provider. This also means we're using the same proxy Pangolin was designed for, which simplifies TLS and plugin compatibility (the badger auth plugin is already present, though disabled locally).
The project is up at Rileybrains/burrowd. But it's currently private and I'm shy. Should consider open-sourcing at some stage.
Targets under rileys.house that do not flow through local Pangolin — such as pangolin.rileys.house and api.rileys.house (the VPS itself) — would be incorrectly intercepted by the PiHole wildcard rule. The fix is to override those specific hostnames to use upstream DNS:
server=/pangolin.rileys.house/8.8.8.8
server=/api.rileys.house/8.8.8.8
This tells dnsmasq to resolve those names via Google's DNS (getting the real VPS IP) rather than using the local address=/rileys.house/192.168.0.26 catch-all.
In general, any *.rileys.house DNS record added directly to Route53 (not via Pangolin) will need a corresponding exception here.
TCP/UDP stream targets are not yet supported. Traefik can handle TCP passthrough, but burrowd currently only writes HTTP routes. This would require extending routes.yml generation to include Traefik's tcp: stanza.
Previously, certificates had to be manually copied from the VPS and the stack restarted. This is now fully automated:
burrowd system user on the VPS has SFTP-only access to /srv/burrowd/certs/acme.json (the Traefik ACME store).certs.yml that Traefik hot-reloads — no restart required.acme.json on its next check.The daemon is fully configured via environment variables (.env file). No manual API calls or config editing required after initial setup.
burrowd Docker LXC to auto-start the docker compose as a systemd service or CRON