From ec7841a07bc6338925e3940a1a64142997d703d6 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 29 Apr 2026 05:12:05 -0400 Subject: [PATCH] fix: inject placeholder listener for pre-validation upstream blocks When pre-validating a custom nginx.conf.sigil before the build phase, no app listeners exist yet on first deploys. Templates that emit `proxy_pass http://app-port` while gating the matching upstream block on `DOKKU_APP_WEB_LISTENERS` render an undefined upstream, causing `nginx -t` to fail with "host not found in upstream". Pre-validation now passes a `127.0.0.1:5000` placeholder for `DOKKU_APP_WEB_LISTENERS` so the upstream block emits a static server entry and the template can be validated for syntax without depending on live listeners. --- docs/appendices/file-formats/nginx-conf-sigil.md | 2 +- plugins/nginx-vhosts/functions | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/appendices/file-formats/nginx-conf-sigil.md b/docs/appendices/file-formats/nginx-conf-sigil.md index eeabfce3f..3cb67eecf 100644 --- a/docs/appendices/file-formats/nginx-conf-sigil.md +++ b/docs/appendices/file-formats/nginx-conf-sigil.md @@ -4,6 +4,6 @@ The `nginx.conf.sigil` file is used to configure the nginx server for an applica ## Validation -A custom `nginx.conf.sigil` is pre-validated at the start of every deploy, immediately after it is extracted from the source tree and before the build phase runs. Pre-validation renders the template via sigil with the same parameters used at deploy time (using empty `DOKKU_APP_WEB_LISTENERS` for first deploys), wraps the rendered config in a minimal `events`/`http` scaffold, and runs `nginx -t` against the result. The deploy is aborted if either the sigil render or the `nginx -t` check fails, so build work is not wasted on a syntactically invalid template. +A custom `nginx.conf.sigil` is pre-validated at the start of every deploy, immediately after it is extracted from the source tree and before the build phase runs. Pre-validation renders the template via sigil with the same parameters used at deploy time, wraps the rendered config in a minimal `events`/`http` scaffold, and runs `nginx -t` against the result. The deploy is aborted if either the sigil render or the `nginx -t` check fails, so build work is not wasted on a syntactically invalid template. When no app listeners exist yet (typical for first deploys), pre-validation injects a placeholder `127.0.0.1:5000` listener for `DOKKU_APP_WEB_LISTENERS` so that the rendered upstream block has a static server entry and `nginx -t` does not bail out on "host not found in upstream". Pre-validation is skipped when the proxy type is not `nginx` or when `disable-custom-config` is set to `true` for the app. diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 01d0de72d..f15556cbf 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -197,6 +197,7 @@ fn-nginx-vhosts-render-template() { declare desc="renders an nginx.conf.sigil template via sigil to an output path" declare APP="$1" NGINX_TEMPLATE="$2" OUTPUT_PATH="$3" declare DOKKU_APP_LISTEN_PORT="$4" DOKKU_APP_LISTEN_IP="$5" + declare PRE_VALIDATE="${6:-false}" local VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls" local DOKKU_APP_LISTENERS PASSED_LISTEN_IP_PORT @@ -361,6 +362,11 @@ fn-nginx-vhosts-render-template() { UPP_PROC_TYPE="${UPP_PROC_TYPE//-/_}" SIGIL_PARAMS+=("DOKKU_APP_${UPP_PROC_TYPE}_LISTENERS=$LISTENERS") done < <(plugn trigger ps-current-scale "$APP") + elif [[ "$PRE_VALIDATE" == "true" ]]; then + # During pre-validation no listeners exist yet; supply a placeholder so + # any upstream block in the template renders with a static server entry + # and nginx -t does not bail out on "host not found in upstream". + SIGIL_PARAMS+=(DOKKU_APP_WEB_LISTENERS="127.0.0.1:5000") else SIGIL_PARAMS+=(DOKKU_APP_WEB_LISTENERS="") fi @@ -412,7 +418,7 @@ fn-nginx-vhosts-pre-validate-custom-template() { dokku_log_info1 "Pre-validating custom nginx.conf.sigil" - if ! fn-nginx-vhosts-render-template "$APP" "$PID_TEMPLATE" "$TMP_RENDERED" >/dev/null; then + if ! fn-nginx-vhosts-render-template "$APP" "$PID_TEMPLATE" "$TMP_RENDERED" "" "" "true" >/dev/null; then dokku_log_warn "Failed to render custom nginx.conf.sigil. Contents below..." cat "$PID_TEMPLATE" dokku_log_fail "Custom nginx.conf.sigil failed to render via sigil"