feat: mark proxy-originated errors and pin container DNS
Build Admin / Build image (push) Successful in 28s
Build Admin / Build image (push) Successful in 28s
- handle_errors sets X-Proxy-Error (dial|upstream) and X-Proxy-Error-Detail so clients with several proxies can fail over when the upstream was never reached, instead of treating the proxy's 502 as the upstream's - explicit dns in compose: the container no longer inherits a host resolver that may disappear (systemd-resolved was switched off on the VM and every lookup failed until a restart) - strip X-Proxy-Token from Caddy logs (it was logged in clear text) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e84b79dda0
commit
4fccfb9089
3 files changed
+50
-1
No files matched your search
@@ -5,6 +5,18 @@
|
||||
{
|
||||
email {$ACME_EMAIL}
|
||||
admin off
|
||||
|
||||
# The error log dumps request headers, and Caddy redacts only
|
||||
# Authorization/Cookie on its own: X-Proxy-Token used to land in
|
||||
# `docker logs` in clear text on every failed upstream call.
|
||||
log default {
|
||||
format filter {
|
||||
wrap json
|
||||
fields {
|
||||
request>headers>X-Proxy-Token delete
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Access control (generated by docker-entrypoint.sh from env) ---
|
||||
@@ -44,8 +56,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
# --- Proxy-originated errors ---
|
||||
# Errors produced by the proxy itself (the upstream answered nothing) are
|
||||
# marked with X-Proxy-Error so that a client with several proxies can tell
|
||||
# them apart from an upstream's own 5xx and fail over:
|
||||
# dial — the upstream was never reached (DNS, connect, no route): the
|
||||
# request did not leave this host, retrying elsewhere is safe
|
||||
# even for non-idempotent calls
|
||||
# upstream — anything else (timeouts, broken responses): the upstream may
|
||||
# have processed the request
|
||||
# X-Proxy-Error-Detail carries the reason. Only clients that passed the
|
||||
# guards ever get here (the guards respond directly, without an error).
|
||||
# Note: handled errors are logged by Caddy at DEBUG level only — the reason
|
||||
# is visible to the client via X-Proxy-Error-Detail.
|
||||
(proxy_errors) {
|
||||
handle_errors {
|
||||
@dial `{err.message}.startsWith("dial ")`
|
||||
handle @dial {
|
||||
header X-Proxy-Error dial
|
||||
header X-Proxy-Error-Detail "{err.message}"
|
||||
respond `{"error":"proxy_dial_failed"}` {err.status_code}
|
||||
}
|
||||
handle {
|
||||
header X-Proxy-Error upstream
|
||||
header X-Proxy-Error-Detail "{err.message}"
|
||||
respond `{"error":"proxy_upstream_failed"}` {err.status_code}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(routes) {
|
||||
import /etc/caddy/matchers.caddy
|
||||
import proxy_errors
|
||||
|
||||
route {
|
||||
# Health check — no auth, evaluated before the guards
|
||||
|
||||
Reference in new issue
Block a user