How to bring up the TripleA Forums stack — NodeBB plus Postgres — on your own
machine, and how to connect to the local database. This mirrors production,
which runs NodeBB on Postgres 18 (the forums role in
triplea-game/infrastructure); it does not touch production.
The local stack is just the docker-compose.yml in this repo, driven by a
justfile. Production is deployed by CI on push to master (just deploy) —
nothing here is involved in that.
- Docker, or rootless Podman with the
dockershim and Compose (what these recipes were validated against). just.
just up
The first run builds the NodeBB image, starts Postgres, sets up the database
schema and an admin account, then starts NodeBB. When it finishes it prints the
URL and the admin credentials. Open http://localhost:4567 and log in with
admin / admin-local-123.
Later runs are the same command — it detects the database is already set up and skips straight to starting the stack.
| Command | What it does |
|---|---|
just up |
Build, start Postgres + NodeBB, set up the DB on first run. |
just down |
Stop the stack, keeping the database and uploads. |
just reset |
Stop and wipe everything — Postgres data, uploads, and the local config. Next just up is a fresh install. |
just logs |
Follow the NodeBB logs. |
just psql |
Open a psql shell on the local database. |
Override the admin account inline on the first run, eg:
ADMIN_USER=me ADMIN_PASSWORD=super-secret-123 ADMIN_EMAIL=me@example.com just up
The password must satisfy NodeBB's rules (at least 8 characters and not trivially weak), or setup drops to an interactive prompt and hangs.
From the stack:
just psql
Or from a host client (psql, a GUI) — Postgres is published on localhost:
- host
127.0.0.1, port5432 - database
nodebb, usernodebb, passwordnodebb
The password is a throwaway local default; production's is a vaulted secret and lives only in the infrastructure repo.
- Config. NodeBB reads
/opt/config/config.json.just upseeds a gitignorednode-bb/config.local.jsonfrom the trackednode-bb/example/config.jsonand bind-mounts it in. NodeBB rewrites this file during setup and on boot, so it is intentionally not:roand not tracked. - First-run setup. With an empty database,
just upruns NodeBB's non-interactive setup, feeding the admin account in through theNODEBB_ADMIN_*environment variables and taking the database connection from the config file. It decides whether setup is needed by probing for thelegacy_objecttable (NodeBB's core Postgres table); once that exists, setup is skipped. - Container user. The local NodeBB service runs as container-root
(
user: "0:0"), unlike production's uid 1001. Under rootless Podman, container-root maps to your host user — the owner of the bind-mountedconfig.json— so NodeBB can write it. Pinning uid 1001 locally maps to a subuid that cannot, and setup/boot then crash withEACCESonconfig.json.
A healthy local boot still logs a few warnings that are expected off-nginx and
do not block startup — 🎉 NodeBB Ready follows them:
Setting 'trust proxy' to false— correct locally; production sets it to 1 because it sits behind nginx.nodebb-plugin-web-push … Vapid subject is not an https: or mailto: URL— the push plugin dislikes the plainhttp://localhostURL; web push simply doesn't work locally.[cache-buster] could not read cache buster … ENOENT— a missing build artifact on the very first boot; it is regenerated.
The prod config is generated by the infrastructure forums role, not from this
repo, so the two cannot cross by accident — but for the record, everything that
makes local work differs deliberately from prod: user: "0:0" (prod pins 1001),
the plaintext nodebb database password (prod vaults it), and the
http://localhost:4567 URL with no trust_proxy (prod is https behind nginx
with trust_proxy: 1).
EACCES: permission denied … config.json— the container can't write the bind-mounted config. Confirm the NodeBB service has nouser:override forcing uid 1001; local dev must run as container-root (see How it works).EROFS— the config is mounted read-only. The local mount must be writable.address already in useon 4567 or 5432 — another process (often a stray earlier NodeBB or Postgres container) holds the port. Free it, orjust downthe leftover stack.- Setup hangs — the admin password was rejected as too short or too weak and
NodeBB fell back to an interactive prompt.
just reset, thenjust upwith a strongerADMIN_PASSWORD. - Start over —
just resetwipes the database, uploads, and local config for a clean install.