Infrastructure: paldocs (Hetzner Edge, DNS, Traffic Routing)
Infrastructure: paldocs
How public traffic reaches paldocs on k3s. Covers the Hetzner edge proxy, DNS via godaddy-tofu, and internal Tailscale funnels.
Diagram
Components
| Component | Purpose | Notes |
|---|---|---|
| GoDaddy DNS | Maps public domains to Hetzner VPS IP | Managed via <code>godaddy-tofu</code> provider in <code>pal-e-platform/terraform/dns.tf</code>. TTL 600s. Currently serves palinks.app, landscaping-assistant.app, westsidekingsandqueens.com. |
| Hetzner VPS | Edge reverse proxy for public-facing services | CAX11 (Debian 12). Managed by <code>pal-e-platform/terraform/modules/hetzner-edge/</code>. Firewall allows TCP 22/80/443. Cloud-init installs Tailscale + Caddy. |
| Caddy | TLS termination + reverse proxy | Automatic HTTPS via Let's Encrypt. Each domain gets a Caddyfile block proxying to the Tailscale hostname (e.g., <code>paldocs.tail5b443a.ts.net:3000</code>). |
| Tailscale Agent (edge) | Connects VPS to the tailnet mesh | Hostname: <code>edge-proxy</code>. Ephemeral pre-authorized key with <code>tag:edge</code>. |
| Tailscale Funnel | Internal access to paldocs via tailnet | Created by <code>services.tf</code> when <code>funnel = true</code>. URL: <code>https://paldocs.tail5b443a.ts.net</code>. |
| paldocs Pod | Rails 8 / Puma on port 3000 | k8s Service <code>paldocs</code> routes to container port 3000. |
Key Decisions
- Hetzner edge instead of Cloudflare/ALB: A simple VPS running Caddy + Tailscale avoids cloud vendor lock-in. Caddy's automatic HTTPS eliminates cert management. Total cost: ~$4/month for the CAX11.
- DNS via Terraform (godaddy-tofu), not console clicks: All A records are IaC. Adding paldocs.app is a single
godaddy_dns_recordresource pointing atmodule.hetzner_edge.server_ipv4. - Dual access paths: Public users hit paldocs.app (via edge proxy). Internal users hit paldocs.tail5b443a.ts.net (direct Tailscale funnel). Both reach the same pod.
- paldocs.app already owned: Domain is purchased. Only the A record + Caddy block need to be created.
Related
arch-k8s-- Kubernetes deployment patterns for paldocsarch-keycloak-paldocs-- Keycloak integration (public domain affects redirect URIs)story-paldocs-ios-testflight-- iOS app requires a public domain (no Tailscale on App Store)- pal-e-platform #490 -- DNS + Caddy setup for paldocs.app
landscaping-assistant/docs/networking.md-- Reference: same edge proxy pattern already working