Fly.io Proxy

Public reverse proxy on Fly.io that exposes selected BlumeOps services to the internet via a Tailscale tunnel back to the homelab.

Quick Reference

PropertyValue
Appblumeops-proxy
Regionsjc (San Jose)
Fly.io URLblumeops-proxy.fly.dev
Configfly/ directory in repo
IaCfly/fly.toml (app), Pulumi (DNS + auth key)

Exposed Services

Public domainBackendService
docs.eblu.medocs.tail8d86e.ts.netdocs

Architecture

Internet traffic hits Fly.io’s Anycast edge, terminates TLS with a Let’s Encrypt certificate, and is proxied by nginx to the backend service over a Tailscale WireGuard tunnel. See expose-service-publicly for the full architecture diagram.

Key Files

FilePurpose
fly/fly.tomlApp configuration
fly/Dockerfilenginx + Tailscale container
fly/nginx.confReverse proxy, caching, rate limiting
fly/start.shEntrypoint: start Tailscale, then nginx
pulumi/tailscale/__main__.pyAuth key (tag:flyio-proxy)
pulumi/tailscale/policy.hujsonACL grants for proxy
pulumi/gandi/__main__.pyDNS CNAMEs

Networking

Fly.io runs Firecracker microVMs which support TUN devices natively. Tailscale runs with a real TUN interface (not userspace networking), so MagicDNS and direct Tailscale IP routing work normally.

The Tailscale auth key is preauthorized=True to avoid device approval hangs on container restarts.

Secrets

SecretSourceDescription
TS_AUTHKEYPulumi state → fly secretsTailscale auth key for joining tailnet
FLY_DEPLOY_TOKENFly.io → 1PasswordDeploy token for CI