ADR: Caddy serves the portals, replacing nginx #166
Closed
opened 2026-09-04 15:23:44 +00:00 by not
·
0 comments
No Branch/Tag Specified
main
ci/175-deploy-on-merge
feat/177-public-tls-edge
ci/168-helm-chart-ci-gate
docs/169-mkdocs-nav
feat/25-helm-kubernetes-caddy
fix/161-e2e-bounded-and-diagnosable
feat/162-werkbak-live-refresh
feat/132-medewerker-mfa
fix/156-tempo-ingester-healthcheck
feat/153-projection-sourced-from-objecten
feat/152-objecten-publishes-to-nrc
feat/149-acl-writes-registerrecord
feat/141-registerrecord-objecttype
perf/verify-stack-uwsgi-oz-nrc
fix/144-verify-stack-uwsgi
feat/140-objecten-up
feat/139-objecttypen-up
feat/131-default-fill-crud
chore/136-ci-job-summaries
fix/134-verify-stack-scheduling
feat/130-beheer-catalogi
feat/124-metrics-dashboards
ci/127-parallel-jobs
feat/123-distributed-traces
feat/111-self-service-resume
feat/113-acl-zaaktype-by-identificatie
fix/110-compose-local-flow
fix/115-e2e-single-worker
docs/111-backlog-s26
feat/106-close-zaak-on-timeout
feat/103-diploma-upload-documenten
feat/102-document-wait-timeout
feat/14-dmn-diploma-eligibility
feat/15-beoordeling-escalation
fix/portal-nginx-resolver
fix/local-eventsubscriber-acl
feat/12-withdrawal-portal
fix/91-local-compose-parity
feat/12-withdrawal-bff
feat/12-withdrawal-workflow
feat/12-withdrawal
feat/13-behandel-portal
feat/13-behandel-decide
feat/13-behandel-bff-auth-werkbak
feat/13-workflow-user-tasks
feat/13-behandel-decision-model
chore/release-2026.07.0
feat/78-reference-correlation
feat/75-approval-flow
feat/10-openbaar-portal
chore/73-ci-speedups
feat/68-e2e
feat/67-self-service-form
feat/66-api-client
feat/65-nx-workspace
feat/8-bff
feat/6-domain-service
feat/7-event-subscriber-projection
feat/56-nrc-notification-wiring
test/46-acl-openzaak-integration
feat/47-acl-mutation-baseline
ci/30-gitea-actions-ci
feat/5-acl-open-zaak
feat/4-flowable
feat/3-keycloak
feat/2-opennotificaties
feat/2-catalogus-seed
feat/10-openzaak-compose
feat/32-docs-scaffold
feat/31-contributor-workflow
feat/30-gitea-actions-ci
feat/29-bff-docker-compose
chore/remove-bootstrap-scripts
feat/28-bff-health
docs/split-s00
v2026.07.0
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Assignees
eho (Edwin van den Houdt)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: eho/register-referentie#166
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Decision to record: serve the four portals with Caddy instead of nginx.
Context
Each portal image serves the built Angular app and reverse-proxies its own BFF endpoint
group, so the browser stays on one origin (no CORS, the token rides along — ADR-0010).
Two workarounds had accumulated around nginx's resolver, both for one root cause: nginx
resolves a variable
proxy_passupstream itself, using only theresolverdirective andnever the search domains in
/etc/resolv.conf.resolver 127.0.0.11is Docker-specific, soapps/portal-nginx-resolver.shrewrote itat container start for rootless podman (aardvark).
bffname cannot resolve without thesvc.cluster.localsearchdomain, so that same script gained a
BFF_HOSToverride set per portal by the Helmchart (#25).
Proposal
Replace the nginx runtime stage and the four
nginx.conffiles withcaddy:2-alpineand aCaddyfileper app. Caddy dials upstreams through the system resolver, which reads/etc/resolv.conf— nameserver and search domains — soreverse_proxy bff:8080resolvesunder Docker, rootless podman and Kubernetes with no per-engine configuration, and still
starts before the BFF exists. Both workarounds and the chart's
BFF_HOSTenv are deleted.Routing uses mutually-exclusive
handleblocks rather than a baretry_files: Caddy'sdefault directive order sorts rewrites before
reverse_proxy, so a top-level SPAfallback would rewrite every API path to
/index.htmlbefore the proxy saw it.Alternatives
Scope
apps/*/Dockerfile,apps/*/Caddyfile(new),apps/*/nginx.conf(deleted),apps/portal-nginx-resolver.sh(deleted), the compose files'config.jsonmount paths,the Helm chart, and the docs that name nginx. A contract test
(
infra/test_portal_caddyfiles.py, inmake unit) asserts each portal proxies exactly itsown endpoint groups and keeps the SPA fallback.