DEPLOYMENT: the Portainer variable list was missing two entries

Asked whether MICRON_DB_URL could live in Portainer rather than .env. It can -
for a Git-based stack it is the only route, since Portainer does not read a
local .env and every ${VAR} in the compose file resolves from the stack's
Environment variables.

But the note listing what to set there named POSTGRES_*, AUTH_SECRET_KEY,
BACKUP_ENC_PASSPHRASE and SMTP_PASSWORD only. MICRON_DB_URL was missing and has
been since it was added, and LDAP_REQUIRED_GROUP was missing because I added the
variable and never updated this list. That list is what someone follows when
standing the stack up.

Replaced with a table of every variable the compose file references, and what an
empty one actually costs. LDAP_REQUIRED_GROUP is the one worth reading twice:
unset means no group gate, so every account in the domain may sign in, and it is
SILENT - sign-in works, nothing looks wrong. That was observed first-hand today,
where a group had been configured, sign-in succeeded, and the group check had
never run.

Two encoding rules that pull in opposite directions, now stated together because
getting them the wrong way round is easy: MICRON_DB_URL is a connection URL and
must be percent-encoded; LDAP_REQUIRED_GROUP is a distinguished name and must NOT
be - its spaces and commas are legal as they stand. Neither takes quotes; a form
field is not a shell, and quotes become part of the value.

Also corrected the closing line, which claimed those were "the only credentials
in the system" while omitting the password embedded in MICRON_DB_URL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-24 11:51:47 -05:00
parent c6a100405d
commit 60b5b0c1f2

View File

@@ -91,13 +91,34 @@ ignored whenever the three `POSTGRES_*` values are present.
Generate a strong password with `openssl rand -base64 32`. Generate a strong password with `openssl rand -base64 32`.
> **Portainer note:** for a Git-based stack these go in the stack's > **Portainer note:** for a Git-based stack the stack's **Environment variables**
> **Environment variables** section (Portainer doesn't read a local `.env`). > section is not merely an alternative to `.env` — it is the ONLY route, because
> Set `POSTGRES_DB` / `POSTGRES_USER` / `POSTGRES_PASSWORD` / `AUTH_SECRET_KEY` / > Portainer does not read a local `.env` at all. Every value the compose file
> `BACKUP_ENC_PASSPHRASE` (and `SMTP_PASSWORD`, if you enable email) there. > references as `${VAR}` has to be set there or it arrives empty.
>
> The full list, and what an empty one costs you:
>
> | Variable | Required? | If unset |
> |---|---|---|
> | `POSTGRES_DB` / `POSTGRES_USER` / `POSTGRES_PASSWORD` | **yes** | the stack will not start |
> | `AUTH_SECRET_KEY` | **yes** | compose fails fast; the API refuses to start |
> | `LDAP_REQUIRED_GROUP` | **effectively yes** | no group gate — **every account in the domain may sign in**. Silent: sign-in works, so nothing looks wrong. |
> | `BACKUP_ENC_PASSPHRASE` | before real data | dumps are written unencrypted |
> | `SMTP_PASSWORD` | only with email on | notifications are recorded and never sent |
> | `MICRON_DB_URL` | optional | the asset picker degrades to manual entry |
>
> Paste values raw — it is a form field, not a shell, so no surrounding quotes.
> Quotes are not stripped and become part of the value: a quoted
> `LDAP_REQUIRED_GROUP` will not resolve, and a quoted `MICRON_DB_URL` will not
> parse.
>
> **`MICRON_DB_URL` must be URL-encoded** (`@` → `%40`, `#` → `%23`, `/` → `%2F`)
> because it is a full connection URL. `LDAP_REQUIRED_GROUP` must NOT be encoded —
> it is an LDAP distinguished name, and its spaces and commas are legal as they are.
These are the only credentials in the system, and they never appear in the `POSTGRES_PASSWORD`, `AUTH_SECRET_KEY`, `BACKUP_ENC_PASSPHRASE`, `SMTP_PASSWORD` and
compose file or in git. the password inside `MICRON_DB_URL` are the only credentials in the system, and none
of them appears in the compose file or in git.
## 3. Point your reverse proxy at the nginx container ## 3. Point your reverse proxy at the nginx container