From 60e09d5050919e32c7dc02efcf753dbe6c7ca8dd Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Mon, 17 Aug 2026 15:54:30 +0200 Subject: [PATCH] chore: wire oidc environment configuration --- .env.example | 3 +++ README.md | 16 +++++++++++++++- compose.yml | 7 +++++++ docker/edge.Dockerfile | 8 ++++++++ docs/architecture/deployment.md | 8 ++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 785e27f..f51f6f1 100644 --- a/.env.example +++ b/.env.example @@ -13,3 +13,6 @@ TEAMCITY_BUILD_NUMBER=local SOURCE_REVISION=local TLS_CERT_FILE=/etc/travel-planner/tls/tls.crt TLS_KEY_FILE=/etc/travel-planner/tls/tls.key +OIDC_ISSUER=https://idp.example.invalid/realms/travel-planner +OIDC_AUDIENCE=travel-planner-api +OIDC_CLIENT_ID=travel-planner-web diff --git a/README.md b/README.md index 83355c1..4362861 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,24 @@ docs/ Specs, plans, and architecture documentation ```bash pnpm install pnpm dev:infra -DATABASE_URL=postgresql://travel_planner:travel_planner_dev@localhost:5432/travel_planner REDIS_URL=redis://localhost:6379 pnpm --filter backend start:api +DATABASE_URL=postgresql://travel_planner:travel_planner_dev@localhost:5432/travel_planner \ +REDIS_URL=redis://localhost:6379 \ +OIDC_ISSUER=https://idp.example.invalid/realms/travel-planner \ +OIDC_AUDIENCE=travel-planner-api \ + pnpm --filter backend start:api pnpm --filter frontend start ``` +Run pending migrations against the dev database before starting the API for the first time: + +```bash +export DATABASE_URL=postgresql://travel_planner:travel_planner_dev@localhost:5432/travel_planner +export REDIS_URL=redis://localhost:6379 +export OIDC_ISSUER=https://idp.example.invalid/realms/travel-planner +export OIDC_AUDIENCE=travel-planner-api +pnpm --filter backend build:api && node backend/dist/apps/api/src/migration.js +``` + `pnpm dev:infra` starts local PostgreSQL/Redis (see `compose.dev.yml`); `pnpm dev:infra:down` stops them. ## Quality gates diff --git a/compose.yml b/compose.yml index 3c9e928..2f8d556 100644 --- a/compose.yml +++ b/compose.yml @@ -4,6 +4,9 @@ services: build: context: . dockerfile: docker/edge.Dockerfile + args: + OIDC_ISSUER: "${OIDC_ISSUER}" + OIDC_CLIENT_ID: "${OIDC_CLIENT_ID}" ports: - "${APP_HTTPS_PORT:-443}:443" volumes: @@ -25,6 +28,8 @@ services: environment: DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" REDIS_URL: "redis://redis:6379" + OIDC_ISSUER: "${OIDC_ISSUER}" + OIDC_AUDIENCE: "${OIDC_AUDIENCE}" APP_VERSION: "${APP_VERSION:-dev}" TEAMCITY_BUILD_NUMBER: "${TEAMCITY_BUILD_NUMBER:-local}" SOURCE_REVISION: "${SOURCE_REVISION:-local}" @@ -50,6 +55,8 @@ services: environment: DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" REDIS_URL: "redis://redis:6379" + OIDC_ISSUER: "${OIDC_ISSUER}" + OIDC_AUDIENCE: "${OIDC_AUDIENCE}" APP_VERSION: "${APP_VERSION:-dev}" TEAMCITY_BUILD_NUMBER: "${TEAMCITY_BUILD_NUMBER:-local}" SOURCE_REVISION: "${SOURCE_REVISION:-local}" diff --git a/docker/edge.Dockerfile b/docker/edge.Dockerfile index e005ac2..a2b7665 100644 --- a/docker/edge.Dockerfile +++ b/docker/edge.Dockerfile @@ -6,6 +6,14 @@ COPY frontend/package.json frontend/package.json COPY backend/package.json backend/package.json RUN pnpm install --frozen-lockfile COPY frontend frontend + +ARG OIDC_ISSUER=https://idp.example.invalid/realms/travel-planner +ARG OIDC_CLIENT_ID=travel-planner-web +RUN sed -i \ + -e "s#issuer: '.*',#issuer: '${OIDC_ISSUER}',#" \ + -e "s#clientId: '.*',#clientId: '${OIDC_CLIENT_ID}',#" \ + frontend/src/environments/environment.production.ts + RUN pnpm --filter frontend build FROM nginx:1.29.8-alpine diff --git a/docs/architecture/deployment.md b/docs/architecture/deployment.md index e816a46..9163a87 100644 --- a/docs/architecture/deployment.md +++ b/docs/architecture/deployment.md @@ -30,3 +30,11 @@ TeamCity supplies immutable `IMAGE_TAG` values (see `scripts/teamcity/build-imag | Rollback | `scripts/teamcity/rollback.sh` | The existing TeamCity project configures these as command-line/SSH build steps; all deployment logic stays in version control, not in TeamCity step configuration. + +## OIDC configuration (Phase 02+) + +`api` and `worker` both require `OIDC_ISSUER` and `OIDC_AUDIENCE` at startup (validated fail-fast by `loadEnvironment`, same as `DATABASE_URL`/`REDIS_URL`). Neither is a secret — this is a public PKCE client with no client secret. The Angular production bundle bakes `OIDC_ISSUER`/`OIDC_CLIENT_ID` in at **image build time** via `docker/edge.Dockerfile` build args (sourced from the `OIDC_ISSUER`/`OIDC_CLIENT_ID` environment variables passed to `docker compose build`), not at container runtime, since static frontend assets cannot read server-side environment variables after the fact. + +## Migrations (Phase 02+) + +`backend/apps/api/src/migration.ts` now runs real, versioned `node-pg-migrate` migrations from `backend/migrations/`; the Phase 01 no-op body has been replaced. The container command contract (`node backend/dist/apps/api/src/migration.js`) is unchanged, so `scripts/teamcity/deploy.sh` required no changes. Migrations are copied into the `travel-api` image so `docker compose run --rm --no-deps api node backend/dist/apps/api/src/migration.js` has everything it needs.