Architecture
Design decisions
No inbound ports
All external traffic enters via Cloudflare Tunnel, and the Tailscale VPN dials out the same way. Every service here is published outbound-only; none of them needs a forwarded port or a public IP.
One hostname everywhere
Public DNS resolves to Cloudflare; AdGuard Home rewrites map the same names to internal IPs for LAN and VPN clients alike. Either way the request hits the same reverse proxy — same URLs, same TLS, same app logins, one bookmark.
Encrypted lookups
Lookups leave over DoH, so nothing on the path sees a plaintext hostname — the name resolution is encrypted, not just the request that follows it. AdGuard Home speaks DoH natively, with no second resolver bolted alongside.
Auth at the edge
Cloudflare Access enforces SSO/OAuth for humans, service tokens and mTLS for machines — every policy evaluated at the edge, not inside the apps. The apps keep their own logins behind that, and there is no public origin to go around it.
Least privilege on the VPN
VPN traffic reaches Traefik directly, skipping Cloudflare Access, so per-route allowlists carry it instead: family devices get only the public apps behind their own logins, and admin UIs answer to my devices alone.
Layered monitoring
Uptime Kuma covers container and HTTP liveness, Beszel covers resources, and Better Stack probes the public path from outside. Alerts converge on ntfy — and Better Stack also expects a heartbeat on a schedule, so a lab that goes dark entirely, ntfy included, still raises an alarm: the missing heartbeat is the alert.
Live status pageSecrets stay out of Git
Every stack is compose-as-code with `.env.example` templates. Runtime secrets live only in ignored env files; config is reproducible, credentials are not.
Stack
- ImmichPhoto / video library and phone backup
- OpenCloudFile sync and collaboration
- Plex / PlexampMedia (runs on the NAS; not in the repo)
- Home AssistantHome automation
- Cloudflare TunnelOutbound-only ingress, Access, mTLS
- TailscaleACL-scoped VPN for family devices and admin
- TraefikTLS termination, per-host routing and access lists
- AdGuard HomeDNS over HTTPS upstream, ad blocking, LAN hostname rewrites
- DockgeCompose stack manager
- Uptime KumaContainer and HTTP liveness probes
- BeszelCPU, RAM, disk, temperature metrics
- ntfyPush alert sink for every monitoring layer
Depth lives in the Homelab Infrastructure README — this page is the portfolio view.