Fix review findings from the browser relocation (#46)

Compose merges `networks:` across override files rather than replacing them,
so the prod override's claim that it must re-name every network was false —
and the rationale built on it ("proxy carries the poller's egress") was false
too. Verified against `docker compose config`: the API renders on db, default
and proxy with only `proxy` named here. Egress comes from `default`, which is
now the thing a maintainer must not tidy away.

chrome/.env.example shipped BROWSER_BIND_ADDR=100.x.y.z as a live value, so
`cp .env.example .env && docker compose up` failed with Docker rejecting an
invalid IP instead of the guard message both troubleshooting tables promise.
Commented out, so the promised message is what you actually get.

DEPLOY §7 gains the two steps that were asserted but never instructed: a
Tailscale ACL, without which "Tailscale identity is the access control" is
aspirational and 9222 is open to every device on the tailnet; and a VPS
`free -m` reading before and after, without which the memory this move
reclaims cannot be shown.

Also drops a change-narration comment and three restatements of measured facts
that already have a canonical home.
This commit is contained in:
2026-08-09 15:24:22 +07:00
parent e4a313e626
commit 15382eb603
6 changed files with 48 additions and 34 deletions
+31 -10
View File
@@ -273,6 +273,17 @@ above.
Do this after §2, on the second machine. Both machines must already be on the
same tailnet.
First, on the VPS, record what you are reclaiming — this is the whole point of
the move and there is no way to measure it afterwards:
```bash
free -m | awk '/^Mem:/ {print "available before:", $NF, "MiB"}'
```
Take it again after §7 is finished and the old sidecar is gone. Expect roughly
the sidecar's former footprint back (measured at 471 MiB working set, 595 MiB
cgroup).
**On the home machine:**
```bash
@@ -280,7 +291,7 @@ git clone <this repo> ~/mangaBookmark && cd ~/mangaBookmark/chrome
tailscale ip -4 # -> 100.x.y.z, this machine's tailnet IP
cp .env.example .env
sed -i "s|^BROWSER_BIND_ADDR=.*|BROWSER_BIND_ADDR=$(tailscale ip -4)|" .env
echo "BROWSER_BIND_ADDR=$(tailscale ip -4)" >> .env
docker compose up -d --build
```
@@ -296,6 +307,21 @@ On the VPS that job was done by Docker network membership; this machine has a
real LAN, so `0.0.0.0` would be a hole punched into your home network. Compose
refuses to start rather than guess.
**Narrow it to the one device that needs it.** The bind address keeps CDP off
your LAN; it still leaves port 9222 open to every device on the tailnet, and
CDP has no login. Add a rule in the Tailscale admin console's access controls
so only the VPS can reach it — tag the two machines, then:
```jsonc
// tailnet policy file
"acls": [
{ "action": "accept", "src": ["tag:bookmark-api"], "dst": ["tag:bookmark-browser:9222"] },
]
```
Without a rule the tailnet default is allow-all, so this step is what makes
"Tailscale identity is the access control" true rather than aspirational.
Prove the bind is tight, from the home machine itself:
```bash
@@ -337,16 +363,11 @@ a cover is stored it is served from Postgres forever after, so the browser being
asleep, unreachable, or mid-power-outage costs chapter freshness and nothing
visible.
**Updating the browser** is independent of the API stack:
Finally, take the VPS `free -m` reading again and compare it against the one
from the top of this section.
```bash
cd ~/mangaBookmark/chrome && git pull && docker compose up -d --build
```
Rebuild is the Chrome upgrade path — the image installs `google-chrome-stable`
unpinned on purpose, because a stale browser is exactly what Cloudflare turns
away. The `chrome-profile` volume survives the rebuild, so the clearance cookies
are reused instead of re-solved.
**Updating the browser** is independent of the API stack and has its own
runbook — `REDEPLOY.md` §8.
---