style: order environment variables by how much the service needs them

environment: blocks were in no particular order. They now run must-have ->
should-have -> optional, with related variables kept adjacent as a group that
takes the tier of its most important member: PUID/PGID, PASSWORD with
SUDO_PASSWORD, DOCKER_MODS ahead of the INSTALL_PACKAGES and
NODEJS_MOD_VERSION that configure it, the four GIT_* entries, the PASEO_*
daemon settings.

Each .env.example is reordered to match its compose file. The names do not map
one to one -- PASSWORD feeds both PASSWORD and SUDO_PASSWORD, SERVICE_HOSTNAME
feeds HOST -- so an entry sits where the first compose entry reading it sits.

The HOST comment in both compose files is dropped; the READMEs already carry
that explanation in full. CLAUDE.md records the ordering convention.

alloy and gitea-mirror-local are untouched: every variable there is required,
so the tiers collapse and the existing grouping is the better one.
This commit is contained in:
tiennm99 committed 2026-09-18 10:47:56 +07:00
1 parent ea46992e64
commit ac00eb9674
6 files changed
+53 -25

No files matched your search

+30
View File
@@ -41,6 +41,36 @@ links out to each service. Per-service detail (variables, ports, storage)
belongs in that service's README, not the root one. Adding a service means
adding its README and a row to the root table.
## Environment variable order
`environment:` entries are ordered by how badly the service needs them — not
alphabetically, and not by when they were added:
1. **Must have** — without it the service does not do its job, or is exposed.
Auth secrets, the uid/gid its files belong to, host allow-lists, proxy
trust, and the mod list that supplies the toolchain.
2. **Should have** — it starts without these, but behaves wrongly for this
setup: timezone, default workspace, shell, git identity, pinned tool
versions, extra packages.
3. **Optional** — cosmetics and conveniences; dropping one changes nothing
functional. Window titles, prompt labels.
Grouping wins over the tiers. Variables that belong together stay on adjacent
lines — `PUID`/`PGID`, `PASSWORD`/`SUDO_PASSWORD`, the four `GIT_*` entries,
the `PASEO_*` daemon settings, `DOCKER_MODS` with the `INSTALL_PACKAGES` and
`NODEJS_MOD_VERSION` that configure it — and the whole group sits at the tier
of its most important member, even when a member on its own would rank lower.
Within a group, the variable others configure comes first.
Do not write the tier into the file as a comment — the order is the
documentation. Where every variable is required, as in `alloy`, the tiers
collapse and the existing grouping stands.
`.env.example` follows its compose file's order. The names differ — one
`PASSWORD` can feed several container variables, and `SERVICE_HOSTNAME` feeds
`HOST` — so each entry sits where the first compose entry that reads it sits.
Reordering a compose file means reordering the `.env.example` with it.
## Deployment target
Services are deployed through Coolify and Dokploy, not plain `docker compose`
+2 -2
View File
@@ -4,11 +4,11 @@ services:
environment:
- PUID=1000
- PGID=1000
- PASSWORD=${PASSWORD}
- SUDO_PASSWORD=${PASSWORD}
- TZ=Asia/Ho_Chi_Minh
- DEFAULT_WORKSPACE=/config/workspace
- PWA_APPNAME=code-server
- PASSWORD=${PASSWORD}
- SUDO_PASSWORD=${PASSWORD}
volumes:
- 'code-server-config:/config'
volumes:
+4 -4
View File
@@ -2,10 +2,6 @@
#
# cp .env.example .env
# Container hostname, also passed in as HOST -- the name zsh's prompt shows.
# Not named HOSTNAME: the deploying shell's own HOSTNAME would override it.
SERVICE_HOSTNAME=code-server
# Web UI login password. MUST NOT be blank -- the LinuxServer image serves
# code-server without authentication when PASSWORD is empty.
# Also used for SUDO_PASSWORD inside the container.
@@ -15,3 +11,7 @@ PASSWORD=
# Git identity baked into the container (author + committer).
GIT_NAME=
GIT_EMAIL=
# Container hostname, also passed in as HOST -- the name zsh's prompt shows.
# Not named HOSTNAME: the deploying shell's own HOSTNAME would override it.
SERVICE_HOSTNAME=code-server
+6 -7
View File
@@ -5,20 +5,19 @@ services:
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Ho_Chi_Minh
# Hostname zsh's prompt reads, overriding the one Coolify injects.
- HOST=${SERVICE_HOSTNAME}
- DEFAULT_WORKSPACE=/config/workspace
- PWA_APPNAME=code-server
- PASSWORD=${PASSWORD}
- SUDO_PASSWORD=${PASSWORD}
- 'DOCKER_MODS=linuxserver/mods:universal-package-install|linuxserver/mods:universal-docker|linuxserver/mods:code-server-golang|linuxserver/mods:code-server-nodejs|linuxserver/mods:code-server-npmglobal|linuxserver/mods:code-server-python3|linuxserver/mods:code-server-zsh'
- INSTALL_PACKAGES=gh|git|glab|unzip|zip
- NODEJS_MOD_VERSION=24
- PASSWORD=${PASSWORD}
- SUDO_PASSWORD=${PASSWORD}
- TZ=Asia/Ho_Chi_Minh
- DEFAULT_WORKSPACE=/config/workspace
- GIT_AUTHOR_NAME=${GIT_NAME}
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
- GIT_COMMITTER_NAME=${GIT_NAME}
- GIT_COMMITTER_EMAIL=${GIT_EMAIL}
- HOST=${SERVICE_HOSTNAME}
- PWA_APPNAME=code-server
volumes:
- 'code-server-config:/config'
- '/var/run/docker.sock:/var/run/docker.sock'
+8 -8
View File
@@ -17,11 +17,9 @@ PASEO_HOSTNAMES=
# `uniquelocal` covers the private ranges Docker bridge networks use.
PASEO_TRUSTED_PROXIES=uniquelocal
# Container hostname, shown as the host label in the web UI. Without it the
# label is a random container ID. Also passed in as HOST -- the name zsh's
# prompt shows. Not named HOSTNAME: the deploying shell's own HOSTNAME would
# override it.
SERVICE_HOSTNAME=paseo
# Shell for Paseo's terminals. Paseo reads $SHELL and otherwise falls back to
# /bin/sh (dash); it ignores the user's login shell, so `chsh` has no effect.
SHELL=/bin/zsh
# Agent CLIs to install on start, if not already present. Space- or
# comma-separated, from: claude codex opencode copilot omp pi. Leave empty to
@@ -37,6 +35,8 @@ TZ=Asia/Ho_Chi_Minh
GIT_NAME=
GIT_EMAIL=
# Shell for Paseo's terminals. Paseo reads $SHELL and otherwise falls back to
# /bin/sh (dash); it ignores the user's login shell, so `chsh` has no effect.
SHELL=/bin/zsh
# Container hostname, shown as the host label in the web UI. Without it the
# label is a random container ID. Also passed in as HOST -- the name zsh's
# prompt shows. Not named HOSTNAME: the deploying shell's own HOSTNAME would
# override it.
SERVICE_HOSTNAME=paseo
+3 -4
View File
@@ -3,18 +3,17 @@ services:
build: .
hostname: ${SERVICE_HOSTNAME}
environment:
- TZ=${TZ}
# Hostname zsh's prompt reads, overriding the one Coolify injects.
- HOST=${SERVICE_HOSTNAME}
- SHELL=${SHELL}
- PASEO_PASSWORD=${PASEO_PASSWORD}
- PASEO_HOSTNAMES=${PASEO_HOSTNAMES}
- PASEO_TRUSTED_PROXIES=${PASEO_TRUSTED_PROXIES}
- SHELL=${SHELL}
- AGENT_CLIS=${AGENT_CLIS}
- TZ=${TZ}
- GIT_AUTHOR_NAME=${GIT_NAME}
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
- GIT_COMMITTER_NAME=${GIT_NAME}
- GIT_COMMITTER_EMAIL=${GIT_EMAIL}
- HOST=${SERVICE_HOSTNAME}
volumes:
- 'paseo-home:/home/paseo'
- 'paseo-workspace:/workspace'