Configuration (.env)
Optional: every setting already has a default in
docker-compose.yml, so the stack comes up with no
.env at all. In practice it holds three groups:
- Always relevant —
OPENCODE_SERVER_PASSWORD(shared by the opencode server and openchamber's client; opencode v2 401s without it),CODE_SERVER_PASSWORDor argon2CODE_SERVER_HASHED_PASSWORD,OPENCHAMBER_UI_PASSWORD. - Only when you select that service —
TTYD_CREDENTIALS(user:password; optional: without it theterminalservice starts anonymous and warns in its logs),OBSIDIAN_USER+OBSIDIAN_PASSWORD(the obsidian image has no auth without them),PORT_TTYD/PORT_OBSIDIAN/PORT_T3CODE(t3codetakes no secret — clients pair with a one-time link from its logs). - Only with
--tunnel—DOMAIN(base domain for the routes, e.g.example.com),TUNNEL_TOKEN, and optionallyCOMPOSE_PROFILES=tunnel. AINV_SERVICES— comma-separated list that pre-fills the chooser checkboxes, defaulting tocode-server. It is not what runs:setup.shre-asks each time and turns your answer into--profileflags.
See .env.example for the full list; it also carries the
PORT_* overrides (PORT_CODE_SERVER, PORT_OPENCODE, PORT_OPENCHAMBER,
PORT_TTYD, PORT_OBSIDIAN, PORT_T3CODE).
Leave both code-server password vars empty and it generates one on first boot:
Generate values with:
Hygiene note: secrets are no longer passed as CLI flags, which in
nanocode.sh leaked them into shell history, the resume unit and ps aux.
The tunnel token now arrives as a container env var — anyone with docker
access can still read it via docker inspect, so keep that group small.
Next: Storage — what is mounted where.