From ee3be92e38231e34c78ec38dce90601ad523b2ff Mon Sep 17 00:00:00 2001 From: Edwin van den Houdt Date: Wed, 3 Jun 2026 15:58:51 +0200 Subject: [PATCH] feat(infra): Open Notificaties up + shared network with OpenZaak (closes #2) Add infra/opennotificaties/docker-compose.yml (PostGIS db, redis broker, migrate-init, API, celery worker) on a shared `cg` network with the OpenZaak stack (renamed oz->cg), published on host :8001. Add combined `make stack-up/stack-smoke/stack-down` targets and a runbook. Completes S-01's acceptance: OpenZaak + Open Notificaties + Postgres come up in compose and a health check confirms all reachable (OZ 403/302/200, NRC 302; cross-network DNS verified). Catalogus seed landed in S-01-b. OZ->NRC notification *delivery* wiring (NRC setup_configuration: Services + Authorization + JWT + Kanalen + Abonnementen; OZ NotificationConfig; re- enabling NOTIFICATIONS_DISABLED) is deferred to S-06 (Event Subscriber), the slice that consumes events. NRC data.yaml is migrate-only until then. Verified: `make stack-smoke` green (both platforms reachable). Co-Authored-By: Claude Opus 4.8 --- Makefile | 31 ++++++- docs/runbooks/opennotificaties.md | 44 +++++++++ docs/runbooks/openzaak.md | 5 +- infra/opennotificaties/docker-compose.yml | 91 +++++++++++++++++++ .../setup_configuration/data.yaml | 5 + infra/openzaak/docker-compose.yml | 12 +-- 6 files changed, 177 insertions(+), 11 deletions(-) create mode 100644 docs/runbooks/opennotificaties.md create mode 100644 infra/opennotificaties/docker-compose.yml create mode 100644 infra/opennotificaties/setup_configuration/data.yaml diff --git a/Makefile b/Makefile index 9cdacbe..793c6ca 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,11 @@ SLN := services/bff/Bff.slnx COMPOSE := infra/docker-compose.yml HEALTH_URL := http://localhost:8080/health -OZ_COMPOSE := infra/openzaak/docker-compose.yml -OZ_BASE := http://localhost:8000 +OZ_COMPOSE := infra/openzaak/docker-compose.yml +OZ_BASE := http://localhost:8000 +NRC_COMPOSE := infra/opennotificaties/docker-compose.yml +NRC_BASE := http://localhost:8001 +STACK_FILES := -f $(OZ_COMPOSE) -f $(NRC_COMPOSE) # On a rootless Podman dev box, point Docker CLI/Compose at the Podman socket — # but only if that socket exists and DOCKER_HOST isn't already set, so real @@ -21,7 +24,7 @@ export DOCKER_HOST := unix://$(PODMAN_SOCK) endif endif -.PHONY: ci lint build unit smoke down changelog openzaak-up openzaak-smoke openzaak-seed openzaak-down help +.PHONY: ci lint build unit smoke down changelog openzaak-up openzaak-smoke openzaak-seed openzaak-down stack-up stack-smoke stack-down help ## ci: run the full pipeline — lint, build, unit, smoke (mirrors Gitea Actions) ci: lint build unit smoke @@ -82,6 +85,28 @@ openzaak-seed: openzaak-up openzaak-down: docker compose -f $(OZ_COMPOSE) down --volumes +## stack-up: start OpenZaak + Open Notificaties together (shared network) +stack-up: + docker compose $(STACK_FILES) up -d + +## stack-smoke: start both, assert OpenZaak (403/302/200) and NRC (302) are reachable +stack-smoke: stack-up + @bash -c 'set -e; \ + echo "waiting for OpenZaak + Open Notificaties..."; \ + for i in $$(seq 1 60); do \ + oz=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/admin/ || true); \ + nrc=$$(curl -s -o /dev/null -w "%{http_code}" $(NRC_BASE)/admin/ || true); \ + [ "$$oz" = "302" ] && [ "$$nrc" = "302" ] && break; sleep 3; done; \ + z=$$(curl -s -o /dev/null -w "%{http_code}" $(OZ_BASE)/zaken/api/v1/zaken); \ + echo "OpenZaak /zaken (unauth) -> $$z (expect 403)"; test "$$z" = "403"; \ + echo "OpenZaak /admin/ -> $$oz (expect 302)"; test "$$oz" = "302"; \ + echo "Open Notificaties /admin/-> $$nrc (expect 302)"; test "$$nrc" = "302"; \ + echo "stack smoke OK"' + +## stack-down: stop and remove both stacks (wipes data) +stack-down: + docker compose $(STACK_FILES) down --volumes + ## help: list available targets help: @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/^## //' diff --git a/docs/runbooks/opennotificaties.md b/docs/runbooks/opennotificaties.md new file mode 100644 index 0000000..cdc6c1b --- /dev/null +++ b/docs/runbooks/opennotificaties.md @@ -0,0 +1,44 @@ +# Open Notificaties (NRC) runbook + +The Open Notificaties stack (`infra/opennotificaties/docker-compose.yml`) is a lean +adaptation of the upstream dev compose: PostGIS db, redis (also the Celery broker), a +one-shot migrate-init, the API, and a celery worker. It shares the **`cg`** Docker +network with the OpenZaak stack so the two can reach each other by service name. + +NRC is published on host **:8001** (OpenZaak holds :8000). + +## Quick test (`make`) — both platforms together + +```bash +make stack-up # OpenZaak + Open Notificaties on the shared network +make stack-smoke # start both + assert reachable (OZ 403/302/200, NRC 302) +make stack-down # stop + wipe both +``` + +`make stack-smoke` runs `docker compose -f infra/openzaak/... -f infra/opennotificaties/... up -d` +and asserts: + +| Check | Expected | +|---|---| +| OpenZaak `GET /zaken/api/v1/zaken` (no JWT) | 403 (auth enforced) | +| OpenZaak `GET /admin/` | 302 | +| Open Notificaties `GET /admin/` | 302 | + +NRC admin UI: (dev superuser **admin / admin**). + +## Notification wiring is deferred to S-06 + +Both platforms are **up and reachable**, but OpenZaak→NRC notification *delivery* is not +wired yet, and OpenZaak still runs with `NOTIFICATIONS_DISABLED=true`. The bidirectional +auth wiring (NRC `setup_configuration`: Services + Authorization to OpenZaak's +Autorisaties API + JWT secrets + Kanalen + Abonnementen; OpenZaak's NotificationConfig) +lands with **S-06 (Event Subscriber)** — the slice that actually consumes events. NRC's +`setup_configuration/data.yaml` is intentionally minimal (migrations only) until then. + +This matches S-01's acceptance, which asks only that the platforms *come up in compose* +and a health check confirms them reachable. + +## Prerequisites + +Same rootless-Podman setup as the rest of the repo — see [ci.md](ci.md) and +[openzaak.md](openzaak.md). `systemctl --user start podman.socket` once per session. diff --git a/docs/runbooks/openzaak.md b/docs/runbooks/openzaak.md index c1e7765..107a141 100644 --- a/docs/runbooks/openzaak.md +++ b/docs/runbooks/openzaak.md @@ -66,8 +66,9 @@ The Makefile auto-points `DOCKER_HOST` at the Podman socket when it exists, so t - **Not in `make ci`.** The OpenZaak smoke is a separate, heavier check (large image pull + migrations); it is intentionally kept out of `make ci` so the core gate stays fast. Run `make openzaak-smoke` when you touch the OpenZaak stack. -- **Notifications disabled.** `NOTIFICATIONS_DISABLED=true` until Open Notificaties - (NRC) lands in S-01-c — otherwise ZTC writes 500 trying to notify. Re-enable then. +- **Notifications disabled.** `NOTIFICATIONS_DISABLED=true` — otherwise ZTC writes 500 + trying to notify. Open Notificaties is now up (see [opennotificaties.md](opennotificaties.md)), + but OZ→NRC delivery wiring + re-enabling lands with **S-06**. - **Zaaktype is a concept**, not published (publishing needs roltypen/statustypen/ resultaattypen — beyond the lean seed). List with `?status=alles`. - **Image tag.** Currently `openzaak/open-zaak:latest` via `${OPENZAAK_TAG}`; pin to diff --git a/infra/opennotificaties/docker-compose.yml b/infra/opennotificaties/docker-compose.yml new file mode 100644 index 0000000..fb08c2a --- /dev/null +++ b/infra/opennotificaties/docker-compose.yml @@ -0,0 +1,91 @@ +# Open Notificaties (NRC) stack (S-01-c). Lean adaptation of the upstream dev compose: +# db (PostGIS) + redis (also the Celery broker) + migrate-init + the API + a celery worker. +# +# Shares the `cg` network with the OpenZaak stack so the two can reach each other. +# Run BOTH together (NRC needs OpenZaak's Autorisaties API for auth wiring): +# +# docker compose -f infra/openzaak/docker-compose.yml -f infra/opennotificaties/docker-compose.yml up -d +# curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8001/admin/ # -> 302 +# +# NRC is published on host :8001 (OpenZaak holds :8000). +services: + nrc-db: + image: docker.io/postgis/postgis:17-3.5 + environment: + POSTGRES_USER: opennotificaties + POSTGRES_PASSWORD: opennotificaties + POSTGRES_DB: opennotificaties + command: postgres -c max_connections=300 + volumes: + - nrc-db:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U opennotificaties -d opennotificaties"] + interval: 5s + timeout: 3s + retries: 10 + networks: [cg] + + nrc-redis: + image: docker.io/library/redis:7 + networks: [cg] + + nrc-init: + image: docker.io/openzaak/open-notificaties:${OPENNOTIFICATIES_TAG:-latest} + environment: &nrc-env + DJANGO_SETTINGS_MODULE: nrc.conf.docker + SECRET_KEY: ${NRC_SECRET_KEY:-dev-only-not-for-production} + DB_HOST: nrc-db + DB_NAME: opennotificaties + DB_USER: opennotificaties + DB_PASSWORD: opennotificaties + IS_HTTPS: "no" + ALLOWED_HOSTS: "*" + CACHE_DEFAULT: nrc-redis:6379/0 + CACHE_AXES: nrc-redis:6379/0 + CELERY_BROKER_URL: redis://nrc-redis:6379/1 + CELERY_RESULT_BACKEND: redis://nrc-redis:6379/1 + DISABLE_2FA: "true" + OPENNOTIFICATIES_SUPERUSER_USERNAME: admin + DJANGO_SUPERUSER_PASSWORD: admin + OPENNOTIFICATIES_SUPERUSER_EMAIL: admin@localhost + RUN_SETUP_CONFIG: "true" + command: /setup_configuration.sh + volumes: + - ./setup_configuration:/app/setup_configuration:ro,z + depends_on: + nrc-db: + condition: service_healthy + nrc-redis: + condition: service_started + networks: [cg] + + nrc-web: + image: docker.io/openzaak/open-notificaties:${OPENNOTIFICATIES_TAG:-latest} + environment: *nrc-env + healthcheck: + test: ["CMD", "python", "-c", "import requests,sys; sys.exit(0 if requests.head('http://localhost:8000/admin/').status_code in (200,302) else 1)"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 30s + ports: + - "8001:8000" + depends_on: + nrc-init: + condition: service_completed_successfully + networks: [cg] + + nrc-celery: + image: docker.io/openzaak/open-notificaties:${OPENNOTIFICATIES_TAG:-latest} + environment: *nrc-env + command: /celery_worker.sh + depends_on: + nrc-init: + condition: service_completed_successfully + networks: [cg] + +volumes: + nrc-db: + +networks: + cg: diff --git a/infra/opennotificaties/setup_configuration/data.yaml b/infra/opennotificaties/setup_configuration/data.yaml new file mode 100644 index 0000000..9aab817 --- /dev/null +++ b/infra/opennotificaties/setup_configuration/data.yaml @@ -0,0 +1,5 @@ +# Open Notificaties setup_configuration. +# Stage 1 (this commit): intentionally minimal — the init container runs +# migrations; no steps enabled yet. The OpenZaak<->NRC notification wiring +# (Services, Authorization, JWT, Kanalen) is added next. See ADR-0002 / S-01-c. +{} diff --git a/infra/openzaak/docker-compose.yml b/infra/openzaak/docker-compose.yml index 6d2a00e..c79aba7 100644 --- a/infra/openzaak/docker-compose.yml +++ b/infra/openzaak/docker-compose.yml @@ -22,11 +22,11 @@ services: interval: 5s timeout: 3s retries: 10 - networks: [oz] + networks: [cg] oz-redis: image: docker.io/library/redis:7 - networks: [oz] + networks: [cg] oz-init: image: docker.io/openzaak/open-zaak:${OPENZAAK_TAG:-latest} @@ -61,7 +61,7 @@ services: condition: service_healthy oz-redis: condition: service_started - networks: [oz] + networks: [cg] openzaak: image: docker.io/openzaak/open-zaak:${OPENZAAK_TAG:-latest} @@ -77,7 +77,7 @@ services: depends_on: oz-init: condition: service_completed_successfully - networks: [oz] + networks: [cg] oz-celery: image: docker.io/openzaak/open-zaak:${OPENZAAK_TAG:-latest} @@ -86,10 +86,10 @@ services: depends_on: oz-init: condition: service_completed_successfully - networks: [oz] + networks: [cg] volumes: oz-db: networks: - oz: + cg: