the DOCKER-USER chain is the only thing gating docker-published ports from
the internet — docker writes its own DNAT/FORWARD rules and bypasses ufw, so
`ufw allow <port>` has no effect on a published container port. the allowlist
permitted only 80 and 443, so a machine provisioned from this template dropped
gitea ssh silently.
the failure is hard to spot: the port looks open locally and docker ps shows it
published, but external clients hang at TCP connect with no refusal. local tests
pass because they arrive via lo and match the loopback RETURN before reaching the
DROP. comments added so the next person recognises it faster.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
scripts/setup/ is now what the new installer is being built in — machine-setup/
for the box, officer-setup.sh for the platform on top — and everything being
replaced moved to scripts/setup-old/. It still works and is still what to run.
Three things the move broke, and what each needed:
starship.toml is not an old-setup artifact. os-user-shell.ts reads it at
RUNTIME to seed a member's ~/.config/starship.toml when their Linux account is
provisioned, and line 125 reads it inside a try whose catch returns
"could not read the shell templates" — so account provisioning would have
failed outright, not degraded. Moved back to scripts/setup/, which is where it
belongs anyway (one file, both audiences) and which leaves the code correct
with no edit.
package.json's `setup` script pointed at a path that no longer exists. It now
points at officer-setup.sh, where the installer is going, rather than at
setup-old/ which is temporary.
officer-setup.sh was created empty. An empty script exits 0, so `bun setup`
would have reported success while doing nothing — worse than the broken path
it replaced. It now explains that it is not written yet and exits 1, naming
the setup-old script to run meanwhile.
Also brought .tmux.conf and ufw-docker-rules.conf in beside machine-setup.sh,
which reads both from SCRIPT_DIR and had been silently skipping them since the
script was vendored. ssh-keys.zip deliberately stays out: it is key material,
and *.zip is ignored.
Comments in os-user-claude.ts, app-store/preflight.ts and two docs still name the
old scripts/setup/setup.sh path. Left alone on purpose — repointing them at
setup-old/ only to repoint them again when officer-setup.sh lands is churn.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>