# Development stack — boots all infra services plus the ACL and BFF. # # Consolidates infra/openzaak/, infra/opennotificaties/, infra/keycloak/, # and infra/flowable/ and adds the ACL and BFF services. # # Port map (host): # 8000 OpenZaak ZGW API (admin: admin / admin) # 8001 Open Notificaties (admin: admin / admin) # 8080 BFF GET /health → Healthy # 8090 Flowable REST http://localhost:8090/flowable-rest/service/ # 8100 ACL GET /health → Healthy POST /zaken # 8180 Keycloak (admin: admin / admin) # # docker compose -f infra/docker-compose.yml up -d --build --wait # # After first boot, seed the BIG catalogus and note the zaaktype URL: # python infra/openzaak/seed_catalogus.py # Then set ACL_ZAAKTYPE_URL in a .env file or your shell and re-up the acl # service: # export ACL_ZAAKTYPE_URL=http://openzaak:8000/catalogi/api/v1/zaaktypen/ # docker compose -f infra/docker-compose.yml up -d acl services: # ── OpenZaak (S-01) ────────────────────────────────────────────────────── oz-db: image: docker.io/postgis/postgis:17-3.5 environment: POSTGRES_USER: openzaak POSTGRES_PASSWORD: openzaak POSTGRES_DB: openzaak command: postgres -c max_connections=300 volumes: - oz-db:/var/lib/postgresql/data healthcheck: # pg_isready only checks TCP; the second clause verifies PostGIS is installed # so oz-init migrations can safely start (avoids race on cold container start). test: ["CMD-SHELL", "pg_isready -U openzaak -d openzaak && psql -U openzaak -d openzaak -c 'SELECT PostGIS_Version();' -q 2>/dev/null"] interval: 5s timeout: 5s retries: 30 start_period: 15s networks: [cg] oz-redis: image: docker.io/library/redis:7 networks: [cg] oz-init: build: context: ./openzaak dockerfile: Dockerfile args: OPENZAAK_TAG: ${OPENZAAK_TAG:-1.28.2} image: register-referentie/openzaak:dev environment: &oz-env DJANGO_SETTINGS_MODULE: openzaak.conf.docker SECRET_KEY: ${OZ_SECRET_KEY:-dev-only-not-for-production} DB_HOST: oz-db DB_NAME: openzaak DB_USER: openzaak DB_PASSWORD: openzaak IS_HTTPS: "no" ALLOWED_HOSTS: "*" CACHE_DEFAULT: oz-redis:6379/0 CACHE_AXES: oz-redis:6379/0 CELERY_BROKER_URL: redis://oz-redis:6379/1 CELERY_RESULT_BACKEND: redis://oz-redis:6379/1 DISABLE_2FA: "true" NOTIFICATIONS_DISABLED: "true" OPENZAAK_SUPERUSER_USERNAME: admin DJANGO_SUPERUSER_PASSWORD: admin OPENZAAK_SUPERUSER_EMAIL: admin@localhost RUN_SETUP_CONFIG: "true" command: /setup_configuration.sh depends_on: oz-db: condition: service_healthy oz-redis: condition: service_started networks: [cg] openzaak: image: register-referentie/openzaak:dev environment: *oz-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: - "8000:8000" depends_on: oz-init: condition: service_completed_successfully networks: [cg] oz-celery: image: register-referentie/openzaak:dev environment: *oz-env command: /celery_worker.sh depends_on: oz-init: condition: service_completed_successfully networks: [cg] # ── Open Notificaties / NRC (S-01-c) ───────────────────────────────────── 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: build: context: ./opennotificaties dockerfile: Dockerfile args: OPENNOTIFICATIES_TAG: ${OPENNOTIFICATIES_TAG:-1.16.1} image: register-referentie/opennotificaties:dev 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 # Migrations only for now. No setup_configuration steps are enabled yet (the # OZ<->NRC notification wiring lands in S-06), and NRC's `setup_configuration` # aborts with "No steps enabled" on the empty data.yaml — so we run `migrate` # directly instead of /setup_configuration.sh. See data.yaml and ADR-0002. command: ["sh", "-c", "/wait_for_db.sh && OTEL_SDK_DISABLED=True python src/manage.py migrate"] depends_on: nrc-db: condition: service_healthy nrc-redis: condition: service_started openzaak: condition: service_healthy networks: [cg] nrc-web: image: register-referentie/opennotificaties:dev 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: register-referentie/opennotificaties:dev environment: *nrc-env command: /celery_worker.sh depends_on: nrc-init: condition: service_completed_successfully networks: [cg] # ── Keycloak (S-02) ────────────────────────────────────────────────────── keycloak: build: context: ./keycloak dockerfile: Dockerfile image: register-referentie/keycloak:dev command: ["start-dev", "--import-realm"] environment: KC_BOOTSTRAP_ADMIN_USERNAME: admin KC_BOOTSTRAP_ADMIN_PASSWORD: admin KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin KC_HEALTH_ENABLED: "true" KC_HTTP_ENABLED: "true" ports: - "8180:8080" networks: [cg] # ── Flowable (S-03) ────────────────────────────────────────────────────── flowable-db: image: docker.io/library/postgres:16 environment: POSTGRES_USER: flowable POSTGRES_PASSWORD: flowable POSTGRES_DB: flowable volumes: - flowable-db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U flowable -d flowable"] interval: 5s timeout: 3s retries: 10 networks: [cg] flowable-rest: image: docker.io/flowable/flowable-rest:latest environment: SPRING_DATASOURCE_DRIVER-CLASS-NAME: org.postgresql.Driver SPRING_DATASOURCE_URL: jdbc:postgresql://flowable-db:5432/flowable SPRING_DATASOURCE_USERNAME: flowable SPRING_DATASOURCE_PASSWORD: flowable ports: - "8090:8080" depends_on: flowable-db: condition: service_healthy networks: [cg] flowable-init: # The BPMN is baked into a tiny curl image (build context = repo-root # workflows/) instead of bind-mounted, so the deploy works on Gitea's # containerized runner too. See docs/runbooks/gitea-actions-gotchas.md. build: context: ../workflows dockerfile_inline: | FROM docker.io/curlimages/curl:latest COPY registratie.bpmn /work/registratie.bpmn image: register-referentie/flowable-init:dev restart: "no" command: - sh - -c - | base=http://flowable-rest:8080/flowable-rest/service/repository/deployments until curl -sf -u rest-admin:test "$$base" >/dev/null 2>&1; do echo "waiting for flowable-rest..."; sleep 3; done if curl -s -u rest-admin:test "$$base?name=registratie" | grep -q '"name":"registratie"'; then echo "registratie already deployed; skip" else curl -sf -u rest-admin:test -F 'file=@/work/registratie.bpmn;filename=registratie.bpmn' "$$base" >/dev/null && echo "deployed registratie" fi depends_on: flowable-rest: condition: service_started networks: [cg] # ── ACL ────────────────────────────────────────────────────────────────── acl: build: context: ../services/acl dockerfile: Dockerfile image: register-referentie/acl:dev environment: Acl__OpenZaak__BaseUrl: http://openzaak:8000/ Acl__OpenZaak__ClientId: big-reference-seed Acl__OpenZaak__Secret: insecure-dev-secret-change-me Acl__Defaults__Bronorganisatie: "517439943" Acl__Defaults__VerantwoordelijkeOrganisatie: "517439943" Acl__Defaults__Vertrouwelijkheidaanduiding: openbaar # Override with the real zaaktype URL after running seed_catalogus.py. Acl__Defaults__ZaaktypeUrl: ${ACL_ZAAKTYPE_URL:-http://openzaak:8000/catalogi/api/v1/zaaktypen/00000000-0000-0000-0000-000000000000} ports: - "8100:8080" healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] interval: 5s timeout: 3s retries: 5 start_period: 10s depends_on: openzaak: condition: service_healthy networks: [cg] # ── BFF ────────────────────────────────────────────────────────────────── bff: build: context: ../services/bff dockerfile: Dockerfile image: register-referentie/bff:dev ports: - "8080:8080" healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] interval: 5s timeout: 3s retries: 5 start_period: 10s networks: [cg] volumes: oz-db: nrc-db: flowable-db: networks: cg: