The guide was static-site-specific. Update to cover dynamic,
authenticated services (e.g., Forgejo):
- Add dynamic service nginx example with no blanket cache, proxy
headers, WebSocket support, selective static asset caching
- Expand DDoS section: explain why dynamic services are more vulnerable
(no cache absorbing traffic) and what mitigations exist
- Rewrite fail2ban section: irrelevant for static, essential for
dynamic services; runs on indri watching service logs, needs
forwarded IP headers
- Add comparison table: static vs dynamic across caching, sessions,
rate limits, proxy headers, fail2ban, DDoS exposure
- Add pre-exposure checklist for dynamic services
- Note Tailscale ACL differences for non-k8s services (e.g., Forgejo
on indri needs tag:homelab grant, not tag:k8s)
- Add inline comments in nginx.conf marking static-only directives
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add frontmatter aliases and id fields
- Wrap long lines for readability
- Note that non-k8s services (forgejo, zot) work via tailscale serve
- Clarify that private *.ops.eblu.me access continues in parallel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the Cloudflare Tunnel plan with a Fly.io reverse proxy
architecture that tunnels back to indri over Tailscale. Covers:
- Full architecture with nginx proxy cache + rate limiting
- One-time setup vs per-service steps
- Fly.io container (Dockerfile, fly.toml, nginx.conf, start.sh)
- Pulumi IaC for Tailscale auth key + DNS CNAMEs
- Forgejo CI workflow for automated deploys
- Security model, DDoS considerations, break-glass shutoff
- Mise tasks: fly-deploy, fly-setup, fly-shutoff
Also fix docs-check-links to handle in-page anchor links
([[#Heading]]) and cross-file anchors ([[file#Heading]]).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>