compose: say which of the three deployment shapes you're in
The operator asked why `THOUGHTSYNC_BIND` isn't just defaulted to the safe value. Fair question, and the answer exposed that my own advice was incomplete: I told them to set it to 127.0.0.1 without asking where their proxy runs, and for a proxy inside Docker that is the wrong fix. There are three shapes, not two: 1. **LAN, no proxy** — the default. Binds every interface so a phone and a desktop can reach the server. This is why the default is NOT the locked-down value: a server reachable only from the machine it runs on isn't hardened, it's broken, and that is the primary documented use of this app. 2. **Proxy in Docker** — delete the `ports:` block entirely. The proxy reaches the app over the compose network; publishing a host port is a second, unauthenticated way in that bypasses whatever the proxy does about TLS. Safer than 127.0.0.1, because there is no host port to reach even from the host. 3. **Proxy on the host** — `THOUGHTSYNC_BIND=127.0.0.1`. The compose file now spells out all three where the decision is made, and `docs/public-hosting.md` item 4 asks where your proxy runs before telling you what to do, plus how to check: `curl http://<lan-ip>:5000/api/health` from another machine should NOT answer once you're proxied. No default changed. Changing it would silently break every LAN install on the next `docker compose pull` — the phone would just stop syncing, with nothing saying why.
This commit is contained in:
+16
-6
@@ -54,13 +54,23 @@ number of proxies you actually run means a forged prefix can never be selected.
|
||||
too HIGH and it starts trusting entries no proxy of yours wrote; too low and several
|
||||
callers share one rate-limit bucket, which is merely inconvenient.
|
||||
|
||||
**4. Stop publishing the app port.** The default compose binds `0.0.0.0:5000` so LAN
|
||||
clients can reach it directly. Behind a proxy that is a second, unprotected front
|
||||
door. In `.env`:
|
||||
**4. Stop reaching the app except through the proxy.** The default compose binds
|
||||
`0.0.0.0:5000` so LAN clients can reach it directly — which is right for a LAN install
|
||||
and wrong the moment there is a proxy in front, because it leaves a second way in that
|
||||
bypasses everything the proxy does.
|
||||
|
||||
```
|
||||
THOUGHTSYNC_BIND=127.0.0.1
|
||||
```
|
||||
Which fix depends on where your proxy runs:
|
||||
|
||||
- **Proxy in Docker** (Traefik discovering the container, an nginx container): delete
|
||||
the `ports:` block from `docker-compose.yml`. The proxy reaches the app over the
|
||||
compose network; no published port is needed at all, and this is the safest of the
|
||||
two because there is no host port to reach even from the host.
|
||||
- **Proxy on the host**: set `THOUGHTSYNC_BIND=127.0.0.1` in `.env`, so the port
|
||||
exists but only the host itself can use it.
|
||||
|
||||
To check which you have: `docker compose ps` shows the published ports, and
|
||||
`curl http://<your-lan-ip>:5000/api/health` from another machine tells you whether the
|
||||
app is still answering around the proxy. It should not be.
|
||||
|
||||
**5. Have a backup that includes the files.** Attachments are files on the
|
||||
`thoughtsync-data` volume, not rows — a `pg_dump` restores notes whose images are all
|
||||
|
||||
Reference in New Issue
Block a user