Clearview stack: require env values (no defaults) + per-env naming

Remove silent defaults (every per-deploy value via ${VAR:?}), hardcode the
fixed structural constants in compose, and key container names + the Postgres
data dir off CLEARVIEW_ENV (dev/prod) so dev and prod stacks coexist. Image tag
stays CLEARVIEW_IMAGE_TAG (dev/latest).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ivo Oskamp 2026-06-19 13:19:33 +02:00
parent 335bfd9591
commit f144261a1a
3 changed files with 46 additions and 26 deletions

View File

@ -2,6 +2,13 @@
This file documents changes on the develop branch of this project. This file documents changes on the develop branch of this project.
## 2026-06-19 — Stack: no silent defaults + per-environment naming
### 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.
- **Per-environment naming**, driven by `CLEARVIEW_ENV`: container names become `clearview-<env>` / `clearview-postgres-<env>` / `clearview-adminer-<env>` and the Postgres data dir `/docker/appdata/clearview-<env>/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) ## 2026-06-19 — Path-prefix routing support (run behind the landing proxy)
### Added ### Added

View File

@ -1,15 +1,28 @@
# 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.
#
# 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-<env>, clearview-postgres-<env>, clearview-adminer-<env>) and
# the Postgres data dir (/docker/appdata/clearview-<env>/postgres), so a dev and
# a prod stack run side by side without clashing.
CLEARVIEW_IMAGE_TAG=dev CLEARVIEW_IMAGE_TAG=dev
CLEARVIEW_ENV=dev
CLEARVIEW_PORT=8080 CLEARVIEW_PORT=8080
TZ=Europe/Amsterdam
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=clearview
POSTGRES_USER=clearview
POSTGRES_PASSWORD=clearview
ADMINER_PORT=8081 ADMINER_PORT=8081
ONBOARDING_CLIENT_ID= # --- Required, NOT shipped here (set in Portainer's stack environment) -------
ONBOARDING_CLIENT_SECRET= # The stack will not start until POSTGRES_PASSWORD is provided.
ONBOARDING_REDIRECT_URI= # POSTGRES_PASSWORD=...
# --- Optional: Microsoft onboarding OAuth (leave unset if unused) ------------
# ONBOARDING_CLIENT_ID=...
# ONBOARDING_CLIENT_SECRET=...
# ONBOARDING_REDIRECT_URI=...

View File

@ -1,13 +1,13 @@
services: services:
clearview: clearview:
image: gitea.oskamp.info/ivooskamp/clearview:${CLEARVIEW_IMAGE_TAG} image: gitea.oskamp.info/ivooskamp/clearview:${CLEARVIEW_IMAGE_TAG:?set CLEARVIEW_IMAGE_TAG to dev or latest}
container_name: clearview container_name: clearview-${CLEARVIEW_ENV:?set CLEARVIEW_ENV to dev or prod}
restart: unless-stopped restart: unless-stopped
ports: ports:
- "${CLEARVIEW_PORT}:80" - "${CLEARVIEW_PORT:?set CLEARVIEW_PORT}:80"
environment: environment:
TZ: ${TZ} TZ: Europe/Amsterdam
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} DATABASE_URL: postgresql://clearview:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}@postgres:5432/clearview
ONBOARDING_CLIENT_ID: ${ONBOARDING_CLIENT_ID} ONBOARDING_CLIENT_ID: ${ONBOARDING_CLIENT_ID}
ONBOARDING_CLIENT_SECRET: ${ONBOARDING_CLIENT_SECRET} ONBOARDING_CLIENT_SECRET: ${ONBOARDING_CLIENT_SECRET}
ONBOARDING_REDIRECT_URI: ${ONBOARDING_REDIRECT_URI} ONBOARDING_REDIRECT_URI: ${ONBOARDING_REDIRECT_URI}
@ -17,17 +17,17 @@ services:
postgres: postgres:
image: postgres:16-alpine image: postgres:16-alpine
container_name: clearview-postgres container_name: clearview-postgres-${CLEARVIEW_ENV:?set CLEARVIEW_ENV to dev or prod}
restart: unless-stopped restart: unless-stopped
environment: environment:
POSTGRES_DB: ${POSTGRES_DB} POSTGRES_DB: clearview
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: clearview
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}
TZ: ${TZ} TZ: Europe/Amsterdam
volumes: volumes:
- /docker/appdata/clearview/postgres:/var/lib/postgresql/data - /docker/appdata/clearview-${CLEARVIEW_ENV}/postgres:/var/lib/postgresql/data
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] test: ["CMD-SHELL", "pg_isready -U clearview -d clearview"]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
@ -35,12 +35,12 @@ services:
adminer: adminer:
image: adminer:4-standalone image: adminer:4-standalone
container_name: clearview-adminer container_name: clearview-adminer-${CLEARVIEW_ENV:?set CLEARVIEW_ENV to dev or prod}
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
postgres: postgres:
condition: service_healthy condition: service_healthy
ports: ports:
- "${ADMINER_PORT}:8080" - "${ADMINER_PORT:?set ADMINER_PORT}:8080"
environment: environment:
ADMINER_DEFAULT_SERVER: ${POSTGRES_HOST} ADMINER_DEFAULT_SERVER: postgres