From ee66a8cfc36f072a323b2d7716d4ca63a8e10391 Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Fri, 19 Jun 2026 13:34:24 +0200 Subject: [PATCH] Clearview stack: Postgres config + TZ in env, only pin Postgres image Revert the over-hardcoding: Postgres connection settings (host/port/db/user/ password) and TZ are env vars again. The only value fixed in the compose is the Postgres image version (functional dependency). No silent defaults remain (${VAR:?}); POSTGRES_PASSWORD ships empty and must be set in Portainer. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/changelog-develop.md | 2 +- stack/.env | 39 +++++++++++++++++++++------------------ stack/docker-compose.yml | 14 +++++++------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/docs/changelog-develop.md b/docs/changelog-develop.md index 5223139..e2a3830 100644 --- a/docs/changelog-develop.md +++ b/docs/changelog-develop.md @@ -6,7 +6,7 @@ This file documents changes on the develop branch of this project. ### Changed - Reworked `stack/docker-compose.yml` + `.env` so the stack has **no baked default values**: every per-deployment value is required via `${VAR:?...}`, so `docker compose`/Portainer refuses to start when one is missing instead of falling back to an insecure default (the old `.env` shipped `POSTGRES_PASSWORD=clearview`). Verified: rendering fails with `required variable POSTGRES_PASSWORD is missing a value` when unset. -- Fixed structural constants are now hardcoded in the compose file (DB name/user `clearview`, internal host `postgres`, port `5432`, `TZ`), not env vars. The committed `.env` only carries the per-deploy values: `CLEARVIEW_IMAGE_TAG` (dev|latest), `CLEARVIEW_ENV` (dev|prod) and the host ports. Secrets (`POSTGRES_PASSWORD`, optional `ONBOARDING_*`) are documented but intentionally not shipped — they must be set in Portainer's stack environment. +- All configurable values stay in the env (referenced via `${VAR:?}`); the **only** thing pinned in the compose is the Postgres image version (`postgres:16-alpine`), since the app's migrations depend on it. Postgres config (`POSTGRES_HOST`/`PORT`/`DB`/`USER`/`PASSWORD`) and `TZ` are env vars. The committed `.env` is the dev baseline (image tag, env, ports, TZ, Postgres host/port/db/user); `POSTGRES_PASSWORD` ships empty (no default — set in Portainer, else the stack won't start) and `ONBOARDING_*` are optional. - **Per-environment naming**, driven by `CLEARVIEW_ENV`: container names become `clearview-` / `clearview-postgres-` / `clearview-adminer-` and the Postgres data dir `/docker/appdata/clearview-/postgres`, so a dev and a prod stack run side by side without name/volume clashes. The image tag stays its own variable (`CLEARVIEW_IMAGE_TAG`); Compose can't map `latest`→`prod` from a single value, so tag and env are two variables (chosen over `-latest` naming). DB DNS still uses the `postgres` service name, so `DATABASE_URL` is unaffected by the container rename. ## 2026-06-19 — Path-prefix routing support (run behind the landing proxy) diff --git a/stack/.env b/stack/.env index 4ce8514..9f6b2cf 100644 --- a/stack/.env +++ b/stack/.env @@ -1,28 +1,31 @@ # Clearview stack environment. # -# Only the values that genuinely differ per deployment live here; everything -# structural (DB name/user, internal host/port, TZ) is fixed in the compose -# file. The compose uses ${VAR:?...} for required values, so the stack REFUSES -# to start when a required variable is missing — there are no silent defaults. +# All per-deployment values live here. The compose references them with +# ${VAR:?...}, so the stack refuses to start when a required value is missing — +# there are no silent defaults. The only thing pinned in the compose itself is +# the Postgres image version (postgres:16-alpine), because the app's migrations +# depend on it. # -# This file is the dev baseline. For the prod stack, override CLEARVIEW_IMAGE_TAG -# (latest), CLEARVIEW_ENV (prod) and the ports in Portainer's stack environment. -# -# CLEARVIEW_IMAGE_TAG drives the image tag; CLEARVIEW_ENV drives the container -# names (clearview-, clearview-postgres-, clearview-adminer-) and -# the Postgres data dir (/docker/appdata/clearview-/postgres), so a dev and -# a prod stack run side by side without clashing. +# This is the dev baseline. For the prod stack, override CLEARVIEW_IMAGE_TAG +# (latest), CLEARVIEW_ENV (prod) and the host ports in Portainer's stack +# environment. CLEARVIEW_ENV drives the container names (clearview-, …) and +# the Postgres data dir (/docker/appdata/clearview-/postgres) so dev and +# prod run side by side. CLEARVIEW_IMAGE_TAG=dev CLEARVIEW_ENV=dev CLEARVIEW_PORT=8080 ADMINER_PORT=8081 +TZ=Europe/Amsterdam -# --- Required, NOT shipped here (set in Portainer's stack environment) ------- -# The stack will not start until POSTGRES_PASSWORD is provided. -# POSTGRES_PASSWORD=... +POSTGRES_HOST=postgres +POSTGRES_PORT=5432 +POSTGRES_DB=clearview +POSTGRES_USER=clearview +# No default — set this in Portainer's stack environment, or the stack won't start. +POSTGRES_PASSWORD= -# --- Optional: Microsoft onboarding OAuth (leave unset if unused) ------------ -# ONBOARDING_CLIENT_ID=... -# ONBOARDING_CLIENT_SECRET=... -# ONBOARDING_REDIRECT_URI=... +# Optional: Microsoft onboarding OAuth (leave blank if unused). +ONBOARDING_CLIENT_ID= +ONBOARDING_CLIENT_SECRET= +ONBOARDING_REDIRECT_URI= diff --git a/stack/docker-compose.yml b/stack/docker-compose.yml index 4206cfe..69d98f1 100644 --- a/stack/docker-compose.yml +++ b/stack/docker-compose.yml @@ -6,8 +6,8 @@ services: ports: - "${CLEARVIEW_PORT:?set CLEARVIEW_PORT}:80" environment: - TZ: Europe/Amsterdam - DATABASE_URL: postgresql://clearview:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}@postgres:5432/clearview + TZ: ${TZ:?set TZ} + DATABASE_URL: postgresql://${POSTGRES_USER:?set POSTGRES_USER}:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}@${POSTGRES_HOST:?set POSTGRES_HOST}:${POSTGRES_PORT:?set POSTGRES_PORT}/${POSTGRES_DB:?set POSTGRES_DB} ONBOARDING_CLIENT_ID: ${ONBOARDING_CLIENT_ID} ONBOARDING_CLIENT_SECRET: ${ONBOARDING_CLIENT_SECRET} ONBOARDING_REDIRECT_URI: ${ONBOARDING_REDIRECT_URI} @@ -20,14 +20,14 @@ services: container_name: clearview-postgres-${CLEARVIEW_ENV:?set CLEARVIEW_ENV to dev or prod} restart: unless-stopped environment: - POSTGRES_DB: clearview - POSTGRES_USER: clearview + POSTGRES_DB: ${POSTGRES_DB:?set POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER:?set POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD} - TZ: Europe/Amsterdam + TZ: ${TZ:?set TZ} volumes: - /docker/appdata/clearview-${CLEARVIEW_ENV}/postgres:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U clearview -d clearview"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 @@ -43,4 +43,4 @@ services: ports: - "${ADMINER_PORT:?set ADMINER_PORT}:8080" environment: - ADMINER_DEFAULT_SERVER: postgres + ADMINER_DEFAULT_SERVER: ${POSTGRES_HOST:?set POSTGRES_HOST}