From 2093fc048132bfc5fea986024bbe73852b21bbfe Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 11 May 2026 17:12:09 +0200 Subject: [PATCH] fix(caddy): wrap actuator block in `handle` so it takes precedence over catch-all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #512. The previous `(block_actuator)` snippet emitted `respond @actuator 404` at the top level of each archive vhost. But each vhost also has a catch-all `handle { reverse_proxy ... }` that matches /actuator/* too. Caddy's `handle` blocks are mutually exclusive — once one matches, the request never reaches a top-level `respond`. So /actuator/health was being proxied to the backend, which 302s to /login. Wrap the actuator response in its own `handle /actuator/*` block. Caddy sorts `handle` blocks by path specificity, so /actuator/* wins over the catch-all and the 404 is actually returned. Verified with `caddy validate` against the caddy:2 image. Also unblocks the nightly.yml smoke test's `/actuator/health → 404` assertion, which has been failing since the first staging deploy. Co-Authored-By: Claude Opus 4.7 --- infra/caddy/Caddyfile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/infra/caddy/Caddyfile b/infra/caddy/Caddyfile index fc6b02bb..2c0c0757 100644 --- a/infra/caddy/Caddyfile +++ b/infra/caddy/Caddyfile @@ -31,8 +31,16 @@ # in application.yaml, /actuator/* is unreachable externally. The internal # Prometheus scrape (future) talks to the backend directly on the docker # network, not via Caddy. - @actuator path /actuator/* - respond @actuator 404 + # + # Why a `handle` block and not a top-level `respond @matcher`: each archive + # vhost has a catch-all `handle { reverse_proxy ... }` that matches every + # path including /actuator/*, and Caddy's `handle` blocks are mutually + # exclusive. Without our own `handle /actuator/*` the catch-all wins, the + # request is proxied to the backend, and Spring Security 302s to /login + # instead of Caddy returning 404. See #512. + handle /actuator/* { + respond 404 + } } (access_log) {