Files
register-referentie/docs/runbooks/openzaak.md
Niek Otten b349dff496
All checks were successful
CI / lint (pull_request) Successful in 49s
CI / build (pull_request) Successful in 44s
CI / unit (pull_request) Successful in 44s
CI / compose-smoke (pull_request) Successful in 4m15s
refactor(infra): use upstream images verbatim, seed config via docker cp (refs #30)
Drops the inline-build images for the upstream services. The compose now
references the published images directly (openzaak/open-zaak,
openzaak/open-notificaties, keycloak, curl, flowable-rest) with no build for
them, and the config they need is streamed into external named volumes by
infra/seed-config.sh:

  rr-oz-config  -> oz-init     /app/setup_configuration   (data.yaml)
  rr-kc-realms  -> keycloak    /opt/keycloak/data/import   (realm exports)
  rr-fl-bpmn    -> flowable-init /work                     (registratie.bpmn)

How: the seeder creates each volume, `docker create`s a throwaway helper that
mounts it, `docker cp`s the files in, and removes it. docker cp streams over the
Docker API, so it works in Docker-in-Docker (the CI runner) where bind mounts
mount empty. It uses plain `docker create`/`cp` — NOT `docker compose create`,
which podman-compose (local dev) lacks. `external: true` fixed names keep the
volumes identical across docker compose and podman-compose.

Consequence: bare `docker compose up` no longer self-seeds, so use `make up`
(seeds then starts). Every `*-up` target seeds first; `*-down` removes the
external volume. acl/bff are still built (they're our apps, not upstream images).

Verified end-to-end on podman-compose: `make keycloak-up` seeds rr-kc-realms,
the upstream Keycloak mounts it, and --import-realm imports all four realms
(digid realm returns 200). Seeder runs in ~2s.

Docs updated: gitea-actions-gotchas.md, ci.md, openzaak.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:22:14 +02:00

3.5 KiB

OpenZaak runbook

The OpenZaak stack (infra/openzaak/docker-compose.yml) is a lean adaptation of the upstream open-zaak dev compose: PostGIS db, redis, a one-shot init that runs migrations, the OpenZaak API, and a celery worker.

Quick test (make)

make openzaak-up       # start the stack (first run pulls images + migrates: 1-3 min)
make openzaak-smoke    # start + assert it's up with auth enforced (403/302/200)
make openzaak-seed     # start + seed the BIG catalogus (idempotent)
make openzaak-down     # stop and wipe data

Seed the BIG catalogus

make openzaak-seed brings the stack up and runs infra/openzaak/seed_catalogus.py, which creates (idempotently, via the ZTC API):

  • catalogus BIG
  • a lean BIG-REGISTRATIE zaaktype (concept; only schema-mandatory fields)
  • a bsn eigenschap on it

then confirms the JWT client can list it. See ADR-0002 for the design (why the zaaktype stays a concept, why notifications are disabled, why the API not a fixture).

JWT client (provisioned declaratively by setup_configuration/data.yaml, dev only):

client_id big-reference-seed
secret insecure-dev-secret-change-me
authorizations heeft_alle_autorisaties (all)

The seed mints a ZGW JWT (HS256) from these and calls /catalogi/api/v1/....

make openzaak-smoke polls until the API responds, then asserts:

Check Expected
GET /zaken/api/v1/zaken (no JWT) 403PermissionDenied ZGW fout (auth enforced)
GET /admin/ 302 — admin login redirect
GET /zaken/api/v1/ 200 — ZGW API schema root

403, not 401. OpenZaak's ZGW APIs return 403 PermissionDenied for a missing or invalid JWT. The S-01 acceptance text says "401" — that's inaccurate; 403 is the correct auth-enforced response.

The admin UI is at http://localhost:8000/admin/; the dev superuser is admin / admin (from the compose env — dev only).

Prerequisites (rootless Podman)

Same setup as the rest of the repo (see ci.md):

systemctl --user start podman.socket    # the Docker-API socket the shim talks to

The Makefile auto-points DOCKER_HOST at the Podman socket when it exists, so the make openzaak-* targets work without extra env.

Notes

  • 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 — otherwise ZTC writes 500 trying to notify. Open Notificaties is now up (see 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. Pinned to openzaak/open-zaak:1.28.2 via ${OPENZAAK_TAG} (bump deliberately, not via :latest).
  • Config arrives via a volume, not a bind mount. setup_configuration/data.yaml is streamed into the external rr-oz-config volume by infra/seed-config.sh (docker cp) and mounted at /app/setup_configuration, so the init container finds it on Gitea's containerized CI runner too (bind mounts don't reach sibling containers there). The image is the upstream openzaak/open-zaak verbatim — no build. Run via make openzaak-up (seeds first). See gitea-actions-gotchas.md.