Repository navigation
Conversation
Making the server reachable from a phone was left to the reader: bring your own reverse proxy, or set up Tailscale on every device. For a server with a public IP and a domain it is now two lines in .env: COMPOSE_FILE=docker-compose.yml:deploy/https/caddy.yml DOMAIN=loopback.example.com The add-on file runs Caddy, which obtains and renews a Let's Encrypt certificate and proxies to the app. It also binds plain-HTTP port 8001 to the host's loopback, and sets FORWARDED_ALLOW_IPS so the server takes the client address from X-Forwarded-For. That last part fixes something any proxy setup had: every client looked like the proxy, so the login rate limit was one bucket shared by everyone (one client hammering the login locked everybody out) and the audit trail recorded the proxy's address on every event. FORWARDED_ALLOW_IPS now also passes through from .env for installs behind their own proxy. Caddy deliberately does not share the app's network namespace. That would make the API see a loopback peer with no trust configuration, but when the app container restarts on its own the sidecar is stranded in a dead namespace and the site stays down until it is restarted by hand.
This was referenced Nov 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Making the server reachable from a phone was left to the reader: bring your own reverse proxy, or set up Tailscale on every device. For a server with a public IP and a domain it is now two lines in
.env:What changes
deploy/https/caddy.yml. An add-on compose file, same pattern asdeploy/demo/docker-compose.public.yml. It runs Caddy, which obtains and renews a Let's Encrypt certificate and proxies to the app, and binds plain-HTTP port 8001 to the host's loopback.FORWARDED_ALLOW_IPS, and the variable now passes through from.envfor installs behind their own proxy. No application code changed; uvicorn does the rewriting.A default install is unchanged: nothing here is loaded unless
COMPOSE_FILEnames it.Worth reviewing
FORWARDED_ALLOW_IPS=*in the Caddy file. It trusts the header from any peer, which is sound only because the same file makes port 8001 loopback-only. The two settings have to stay together; the file says so.appservice's ports, so it could not close 8001.Checked
Against the demo stack with
DOMAIN=localhost(Caddy's internal certificate) on remapped ports:/mcpall answer over HTTPS; HTTP redirects to HTTPS.X-Forwarded-Forsent through Caddy is ignored.docker restartof the app, a kill and start, recreating only the app, and restarting Caddy.Not checked: issuing a real Let's Encrypt certificate, which needs a public host. That part is stock Caddy behaviour.
Not in this PR
A Tailscale Funnel add-on for home servers without a domain. It is drafted, but it needs a tailnet auth key to test.