From 72f210c0e1656cd195bcef53c84db65a74a3e2c9 Mon Sep 17 00:00:00 2001 From: Sebastian Danielsson Date: Fri, 21 Aug 2026 00:30:27 +0200 Subject: [PATCH] fix: write the generated secret key to DATA_DIR start.sh cd's to its own directory, so the generated .webui_secret_key lands in an image layer instead of the mounted volume. It is therefore lost on every container recreate, signing all users out, and the directory is not writable when the container does not run as root, which aborts the boot outright: start.sh: line 46: .webui_secret_key: Permission denied Resolve to WEBUI_SECRET_KEY_FILE, then an existing ./.webui_secret_key, then DATA_DIR. Regeneration triggers on missing or empty rather than absent, since an empty key now persists; an unreadable one is left alone, as it may belong to another UID and also encrypts OAuth sessions and valves. Closes #26662 Co-Authored-By: Claude Opus 5 (1M context) --- .dockerignore | 1 + backend/start.sh | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 2b4f7b5fcf..f1d748f778 100644 --- a/.dockerignore +++ b/.dockerignore @@ -18,3 +18,4 @@ uploads **/*.db _test backend/data/* +backend/.webui_secret_key diff --git a/backend/start.sh b/backend/start.sh index 0846273b89..4f21a3c035 100755 --- a/backend/start.sh +++ b/backend/start.sh @@ -29,7 +29,16 @@ fi # ── Secret key setup ───────────────────────────────────────────────────────── -KEY_FILE="${WEBUI_SECRET_KEY_FILE:-.webui_secret_key}" +# The script cd's to its own directory, which lives in the image: a key written +# there is lost on every container recreate and is not writable when the +# container does not run as root. Fall back to DATA_DIR instead. +if [[ -n "${WEBUI_SECRET_KEY_FILE:-}" ]]; then + KEY_FILE="$WEBUI_SECRET_KEY_FILE" +elif [[ -f .webui_secret_key && -s .webui_secret_key ]]; then + KEY_FILE=".webui_secret_key" +else + KEY_FILE="${DATA_DIR:-./data}/.webui_secret_key" +fi WEBUI_SECRET_KEY_LENGTH="${WEBUI_SECRET_KEY_LENGTH:-24}" PORT="${PORT:-8080}" HOST="${HOST:-0.0.0.0}" @@ -37,13 +46,20 @@ HOST="${HOST:-0.0.0.0}" if [[ -z "${WEBUI_SECRET_KEY:-}" && -z "${WEBUI_JWT_SECRET_KEY:-}" ]]; then echo "No WEBUI_SECRET_KEY environment variable set, loading from file." - if [[ ! -f "$KEY_FILE" ]]; then + # Regenerate when missing or empty, never when merely unreadable: such a key may + # belong to another UID, and it also encrypts OAuth sessions and valves. + if [[ ! -s "$KEY_FILE" ]]; then echo "Generating new WEBUI_SECRET_KEY..." if ! [[ "$WEBUI_SECRET_KEY_LENGTH" =~ ^[1-9][0-9]*$ ]]; then echo "WEBUI_SECRET_KEY_LENGTH must be a positive integer." >&2 exit 1 fi - head -c "$WEBUI_SECRET_KEY_LENGTH" /dev/random | base64 > "$KEY_FILE" + # 0640/0750: a volume remounted under a different arbitrary UID keeps group 0. + ( + umask 027 + mkdir -p -- "$(dirname -- "$KEY_FILE")" + head -c "$WEBUI_SECRET_KEY_LENGTH" /dev/random | base64 > "$KEY_FILE" + ) fi echo "Loading WEBUI_SECRET_KEY from ${KEY_FILE}"