fix: add proxy health checks from app.json readiness

The caddy, haproxy, openresty, and traefik docs stated that requests are only routed to containers passing healthchecks, but these proxies route to a new container as soon as it starts. The first `web` readiness healthcheck in `app.json` is now also turned into health checks and retries for caddy and openresty, as it already was for traefik, so requests are routed away from containers that are not yet ready, and the docs now describe how each proxy actually behaves.
This commit is contained in:
Jose Diaz-Gonzalez
2026-09-26 01:01:41 -04:00
parent 1910c3fb68
commit 83c9c4d72e
15 changed files with 694 additions and 39 deletions

View File

@@ -127,6 +127,10 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_http_port }}\""
fi
if [[ "$output" == *"caddy.reverse_proxy="* ]]; then
output="$output$(fn-caddy-healthcheck-labels "$APP" "$app_domains")"
fi
fi
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "caddy" "$APP")
@@ -140,4 +144,43 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
echo -n "$STDIN $output"
}
fn-caddy-healthcheck-labels() {
declare desc="outputs caddy reverse_proxy health check and retry labels derived from the app's web readiness healthcheck"
declare APP="$1" APP_DOMAINS="$2"
local healthcheck hc_path hc_port hc_timeout hc_interval hc_host domain
local -a domains
healthcheck="$(fn-proxy-get-readiness-healthcheck "$APP")"
if [[ -z "$healthcheck" ]]; then
return
fi
hc_path="$(echo "$healthcheck" | jq -r ".path // empty")"
hc_port="$(echo "$healthcheck" | jq -r ".port // empty")"
hc_timeout="$(echo "$healthcheck" | jq -r ".timeout // 5")"
hc_interval="$(echo "$healthcheck" | jq -r ".wait // 5")"
if ! fn-proxy-healthcheck-path-is-valid "$hc_path"; then
dokku_log_fail "Invalid app.json healthcheck path for caddy: path must start with a / and must not contain whitespace, control characters, quotes, or backslashes"
fi
read -r -d '' -a domains <<<"$APP_DOMAINS" || true
for domain in "${domains[@]}"; do
if [[ "$domain" == "localhost" ]] || [[ "$domain" == '*' ]]; then
continue
fi
hc_host="$domain"
break
done
echo -n " --label \"caddy.reverse_proxy.health_uri=$hc_path\""
[[ -n "$hc_port" ]] && echo -n " --label caddy.reverse_proxy.health_port=$hc_port"
echo -n " --label caddy.reverse_proxy.health_interval=${hc_interval}s"
echo -n " --label caddy.reverse_proxy.health_timeout=${hc_timeout}s"
[[ -n "$hc_host" ]] && echo -n " --label caddy.reverse_proxy.health_headers.Host=$hc_host"
echo -n " --label caddy.reverse_proxy.lb_try_duration=5s"
echo -n " --label caddy.reverse_proxy.lb_try_interval=250ms"
}
trigger-caddy-vhosts-docker-args-process-deploy "$@"