fix: forward every environment-overridable dokku variable

`DOKKU_INIT_SYSTEM` reaches the `dokku` user only through the environment while the Docker image is being built, so narrowing the forwarded set left `nginx:reload` taking the systemd branch during `debian/postinst` and blocking on a sudo password prompt until the build timed out. The forwarded set now covers every variable `dokku` honours from the environment, and `DOKKU_PRESERVE_ENV` still carries anything beyond it.
This commit is contained in:
Jose Diaz-Gonzalez
2026-09-20 16:25:34 -04:00
parent 6b1b7bc6f6
commit 63e4b92a52
3 changed files with 38 additions and 3 deletions

View File

@@ -165,6 +165,11 @@ named explicitly and forwarded:
| `DOKKU_DISABLE_TTY`, `DOKKU_FORCE_TTY` | the `dokku run` tty flags, or the environment |
| `DOKKU_PRESERVE_ENV` | the list below |
| `SSH_USER`, `SSH_NAME`, `NAME`, `FINGERPRINT`, `SSH_ORIGINAL_COMMAND` | the ssh session the command arrived on |
| `DOCKER_BIN`, `DOKKU_CNB_BUILDER`, `DOKKU_EVENTS_LOGFILE`, `DOKKU_HOST_ROOT`, `DOKKU_IMAGE`, `DOKKU_LIB_PATH`, `DOKKU_LOGS_DIR`, `DOKKU_LOGS_HOST_DIR`, `DOKKU_ROOT`, `DOKKU_SYSTEM_GROUP`, `DOKKU_SYSTEM_USER`, `PLUGIN_PATH`, `PLUGIN_AVAILABLE_PATH`, `PLUGIN_ENABLED_PATH`, `PLUGIN_CORE_PATH`, `PLUGIN_CORE_AVAILABLE_PATH`, `PLUGIN_CORE_ENABLED_PATH` | the environment, so the re-executed process derives the same paths as the caller |
| `DOKKU_INIT_SYSTEM`, `DOKKU_LIB_HOST_ROOT` | the environment, which is where they live while a Docker image is being built |
`DOKKU_PID` is deliberately not forwarded: it is unset before the privilege drop so the re-executed
process gets its own.
To forward anything else - a variable read by a third-party plugin, or a one-off override of a
setting that normally lives in `/etc/default/dokku` - name it in `DOKKU_PRESERVE_ENV`:

View File

@@ -479,11 +479,18 @@ is_abs_path() {
fn-cli-preserved-env-names() {
declare desc="names the environment variables the re-exec as the dokku user must carry"
# anything sourced from /etc/default/dokku or ~dokku/.dokkurc/* is re-read by the
# child and does not belong here; DOKKU_PRESERVE_ENV carries anything else
# every variable dokku honours from the environment has to be listed, or the child
# derives different values than the parent - during the docker image build these only
# ever exist in the environment. DOKKU_PID is the one exclusion: it is unset above so
# the child gets its own. DOKKU_PRESERVE_ENV carries anything else
echo "DOKKU_APP_NAME DOKKU_APPS_FORCE_DELETE DOKKU_DISABLE_TTY DOKKU_FORCE_TTY" \
"DOKKU_GLOBAL_FLAGS DOKKU_PRESERVE_ENV DOKKU_QUIET_OUTPUT DOKKU_TRACE" \
"FINGERPRINT NAME SSH_NAME SSH_ORIGINAL_COMMAND SSH_USER"
"FINGERPRINT NAME SSH_NAME SSH_ORIGINAL_COMMAND SSH_USER" \
"DOCKER_BIN DOKKU_CNB_BUILDER DOKKU_EVENTS_LOGFILE DOKKU_HOST_ROOT DOKKU_IMAGE" \
"DOKKU_INIT_SYSTEM DOKKU_LIB_HOST_ROOT DOKKU_LIB_PATH DOKKU_LOGS_DIR" \
"DOKKU_LOGS_HOST_DIR DOKKU_ROOT DOKKU_SYSTEM_GROUP DOKKU_SYSTEM_USER" \
"PLUGIN_AVAILABLE_PATH PLUGIN_CORE_AVAILABLE_PATH PLUGIN_CORE_ENABLED_PATH" \
"PLUGIN_CORE_PATH PLUGIN_ENABLED_PATH PLUGIN_PATH"
}
fn-sudo-preserve-env-flag() {

View File

@@ -164,6 +164,29 @@ teardown() {
assert_output "7"
}
@test "(common) [preserve-env] fn-cli-preserved-env-names covers the docker image build variables" {
# neither is read by the dokku script itself, so the derivation test below does not
# catch them. both exist only in the environment while the docker image is built
run /bin/bash -c "source '$PLUGIN_CORE_AVAILABLE_PATH/common/functions'; fn-cli-preserved-env-names | tr ' ' '\\n' | grep -cxE 'DOKKU_INIT_SYSTEM|DOKKU_LIB_HOST_ROOT'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "2"
}
@test "(common) [preserve-env] every environment-overridable dokku variable is preserved" {
# test_helper leaves these unexported, so the single-quoted script below cannot see
# them without this
export PLUGIN_CORE_AVAILABLE_PATH
export DOKKU_SOURCE="${BATS_TEST_DIRNAME}/../../dokku"
run /bin/bash -c 'source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"; comm -23 <(grep -oE "[{][A-Z_]+:=" "$DOKKU_SOURCE" | tr -cd "A-Z_\n" | sort -u | grep -vx DOKKU_PID) <(fn-cli-preserved-env-names | tr " " "\n" | sort -u)'
echo "output: $output"
echo "status: $status"
assert_success
assert_output ""
unset DOKKU_SOURCE
}
@test "(common) [preserve-env] parse_args records global flags for replay" {
run /bin/bash -c "source '$PLUGIN_CORE_AVAILABLE_PATH/common/functions'; parse_args --label=a=b run foo env; echo \"\$DOKKU_GLOBAL_FLAGS\""
echo "output: $output"