feat(compose): publish on every interface, so the host's own address answers
All checks were successful
PR checks / checks (pull_request) Successful in 9m56s
All checks were successful
PR checks / checks (pull_request) Successful in 9m56s
D55 bound the published port to 127.0.0.1, on the reasoning that TLS terminates
at a proxy on the same host and nothing else has business reaching the container.
That is right for the host this ends up on and wrong for every step before it: a
loopback binding cannot be opened from a browser on another machine, which is the
first thing an operator wants to do — look at the site on the VM's own address,
before DNS exists, before the proxy exists, from a desktop or a phone.
The port line is now "${SITE_BIND_ADDR:-0.0.0.0}:${SITE_HOST_PORT:-4321}:4321",
so http://<vm-ip>:4321 answers out of the box, the way a normal bridge publish
behaves. Which addresses it answers on is a variable rather than an edit:
SITE_BIND_ADDR narrows it to one interface, or back to loopback, without touching
a file that `docker compose pull` replaces. That also retires the "change the port
line yourself" instruction DEPLOY.md had to give a proxy running in another
container or on another machine.
What is given up, said plainly in DEPLOY.md §3.1: on a host with a public address
the default answers on port 4321 from the internet, plain HTTP beside the proxy's
443, with no proxy in the path to set X-Forwarded-For — so signups arriving that
way share one rate-limit bucket. There is no login and no secret behind it, so it
is untidy rather than dangerous, and both remedies are named (firewall the port,
or narrow the binding).
Verified by running it, not only by reading it: `docker compose config` accepts
both bindings and resolves host_ip 0.0.0.0 and 127.0.0.1 respectively; the stack
came up healthy, `docker compose port site 4321` reported 0.0.0.0:4321, and the
site answered 200 on both 127.0.0.1 and the machine's LAN address, still carrying
its own per-page CSP.
Recorded as D59, amending D55. Count of record fifty-nine.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -59,16 +59,26 @@ services:
|
||||
# DEPLOY.md has the two commands.
|
||||
- ./data:/app/data
|
||||
|
||||
# Bound to loopback, because TLS terminates at a reverse proxy on this host
|
||||
# and nothing else has any business reaching the container directly.
|
||||
# Published on ALL interfaces by default, so the site answers on the host's
|
||||
# own address — `http://<vm-ip>:4321` — and not only on its loopback. That is
|
||||
# what makes it reachable from the rest of the network: a proxy in another
|
||||
# container or on another machine, a browser on the LAN, a phone on the same
|
||||
# wifi checking the mobile layout.
|
||||
#
|
||||
# CHANGE THIS if your proxy runs in its own container or on another machine:
|
||||
# it then cannot reach 127.0.0.1 of the host, and the binding must become
|
||||
# `"${SITE_HOST_PORT:-4321}:4321"` (all interfaces) with a firewall in front,
|
||||
# or the proxy must join a shared Docker network and address the service by
|
||||
# name instead of by port. DEPLOY.md, "Putting a proxy in front of it".
|
||||
# It is deliberately a variable rather than a fixed address, because the safe
|
||||
# binding depends on where this host sits. Set SITE_BIND_ADDR in .env to
|
||||
# narrow it without touching this file:
|
||||
#
|
||||
# SITE_BIND_ADDR=127.0.0.1 loopback only — a proxy on THIS host, nothing else
|
||||
# SITE_BIND_ADDR=192.168.1.10 one interface — the LAN, but not a public NIC
|
||||
# SITE_BIND_ADDR=0.0.0.0 every interface (the default)
|
||||
#
|
||||
# On a host with a public address, `0.0.0.0` means port 4321 answers from the
|
||||
# internet directly, beside whatever the proxy serves on 443 — plain HTTP, no
|
||||
# TLS. Firewall the port, or narrow the binding. DEPLOY.md, "Putting a proxy
|
||||
# in front of it".
|
||||
ports:
|
||||
- "127.0.0.1:${SITE_HOST_PORT:-4321}:4321"
|
||||
- "${SITE_BIND_ADDR:-0.0.0.0}:${SITE_HOST_PORT:-4321}:4321"
|
||||
|
||||
# Repeats the image's own HEALTHCHECK so `docker compose ps` reports it even
|
||||
# when the image is pinned to an older tag that predates it. It watches an
|
||||
|
||||
Reference in New Issue
Block a user