From f731efa2faed5290b65df829c8d7e963fc9a4cf3 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 17:08:55 +0000 Subject: [PATCH] Fix DB/admin password regeneration on rerun in 5 services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same bug class just fixed in mattermost.sh: immich, joplin, koha, mail-archiver, and nextcloud all generated a fresh random DB/admin password on every single run with no check for an existing one. Each backs its database with a persistent volume, so Postgres/MariaDB keeps the password from its first init while the freshly overwritten .env (or config-main.env for koha) no longer matches it — any rerun would have locked the app out of its own database. koha, mail-archiver, and nextcloud also regenerated an app-level admin login password the same way. Found by cross-referencing every service with a DB password against which ones actually guard reuse on rerun (only traccar.sh did, already correctly) rather than waiting to be told about each one individually. Fix mirrors traccar.sh's existing pattern: read the password back out of the existing .env/config file if present, only generate fresh when there's genuinely nothing there yet. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01NQkdAn3iG5A4WoqU9FHMaN --- services/immich.sh | 7 ++++++- services/joplin.sh | 8 ++++++-- services/koha.sh | 23 ++++++++++++++++++++--- services/mail-archiver.sh | 13 +++++++++++-- services/nextcloud.sh | 16 ++++++++++++---- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/services/immich.sh b/services/immich.sh index 46cbd06..2f2e1b6 100644 --- a/services/immich.sh +++ b/services/immich.sh @@ -286,8 +286,13 @@ install_immich() { cd "$IMMICH_DIR" || return 1 # ── Generate DB password ──────────────────────────────────────────────── + # Reused across reruns if already set — the Postgres volume keeps the + # password from its first init, so a fresh random one on every rerun + # would lock Immich out of its own database. local DB_PASS TZ_VAL - DB_PASS=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32) + DB_PASS="" + [ -f ".env" ] && DB_PASS="$(grep '^DB_PASSWORD=' .env | cut -d= -f2-)" + [ -n "$DB_PASS" ] || DB_PASS="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32)" TZ_VAL="${SITE_TZ:-$(cat /etc/timezone 2>/dev/null || echo UTC)}" # ── Write docker-compose.yml ──────────────────────────────────────────── diff --git a/services/joplin.sh b/services/joplin.sh index bae8650..b161743 100644 --- a/services/joplin.sh +++ b/services/joplin.sh @@ -197,8 +197,12 @@ install_joplin() { ensure_docker_dir_ownership "$JOPLIN_DIR" cd "$JOPLIN_DIR" || return 1 - local DB_PASS - DB_PASS="$(generate_password 32)" + # Reused across reruns if already set — the Postgres volume keeps the + # password from its first init, so a fresh random one on every rerun + # would lock Joplin out of its own database. + local DB_PASS="" + [ -f ".env" ] && DB_PASS="$(grep '^POSTGRES_PASSWORD=' .env | cut -d= -f2-)" + [ -n "$DB_PASS" ] || DB_PASS="$(generate_password 32)" local BASE_URL="https://joplin.${SITE_DOMAIN}" # Mirrors configure_caddy_for_service's own mode resolution (lib/common.sh): diff --git a/services/koha.sh b/services/koha.sh index 6b0b692..c68258e 100644 --- a/services/koha.sh +++ b/services/koha.sh @@ -336,10 +336,27 @@ install_koha() { fi # ── Passwords ───────────────────────────────────────────────────────────── + # Reused across reruns if already set — the MariaDB volume keeps + # DB_PASS/DB_ROOT_PASS from first init, and an already-created Koha admin + # account keeps its own KOHA_ADMIN_PASS; regenerating any of these on a + # rerun would lock the reinstall out of both the database and + # post-setup.sh's REST API login. local DB_PASS DB_ROOT_PASS RABBIT_PASS - DB_PASS="$(generate_password 24)" - DB_ROOT_PASS="$(generate_password 24)" - RABBIT_PASS="$(generate_password 24)" + local _existing_koha_conf="$KOHA_DIR/config-main.env" + if [ -f "$_existing_koha_conf" ]; then + DB_PASS="$(grep '^DB_PASS=' "$_existing_koha_conf" | cut -d= -f2-)" + DB_ROOT_PASS="$(grep '^DB_ROOT_PASS=' "$_existing_koha_conf" | cut -d= -f2-)" + RABBIT_PASS="$(grep '^RABBIT_PASS=' "$_existing_koha_conf" | cut -d= -f2-)" + local _existing_admin_pass + _existing_admin_pass="$(grep '^KOHA_ADMIN_PASS=' "$_existing_koha_conf" | cut -d= -f2-)" + if [ -n "$_existing_admin_pass" ]; then + KOHA_ADMIN_PASS="$_existing_admin_pass" + log_info "Existing install detected — reusing its DB/admin passwords instead of what was just entered above, so this rebuild doesn't lock out the already-initialized database and admin account." + fi + fi + [ -n "${DB_PASS:-}" ] || DB_PASS="$(generate_password 24)" + [ -n "${DB_ROOT_PASS:-}" ] || DB_ROOT_PASS="$(generate_password 24)" + [ -n "${RABBIT_PASS:-}" ] || RABBIT_PASS="$(generate_password 24)" # ── Create directories ──────────────────────────────────────────────────── mkdir -p "$KOHA_DIR/data" diff --git a/services/mail-archiver.sh b/services/mail-archiver.sh index 995c2f9..1101ec5 100644 --- a/services/mail-archiver.sh +++ b/services/mail-archiver.sh @@ -207,9 +207,18 @@ install_mail-archiver() { ensure_docker_dir_ownership "$MA_DIR" cd "$MA_DIR" || return 1 + # Reused across reruns if already set — the Postgres volume keeps + # DB_PASS from its first init, and an already-created admin account + # keeps ADMIN_PASS; regenerating either on a rerun would lock the + # reinstall out of the database and the app's own admin login. local DB_PASS ADMIN_PASS TZ_VAL - DB_PASS=$(generate_password 32) - ADMIN_PASS=$(generate_password 24) + DB_PASS="" ADMIN_PASS="" + if [ -f ".env" ]; then + DB_PASS="$(grep '^POSTGRES_PASSWORD=' .env | cut -d= -f2-)" + ADMIN_PASS="$(grep '^Authentication__Password=' .env | cut -d= -f2-)" + fi + [ -n "$DB_PASS" ] || DB_PASS="$(generate_password 32)" + [ -n "$ADMIN_PASS" ] || ADMIN_PASS="$(generate_password 24)" TZ_VAL="${SITE_TZ:-$(cat /etc/timezone 2>/dev/null || echo UTC)}" # Mirrors configure_caddy_for_service's own mode resolution (lib/common.sh): diff --git a/services/nextcloud.sh b/services/nextcloud.sh index fefbdcd..addd268 100644 --- a/services/nextcloud.sh +++ b/services/nextcloud.sh @@ -190,10 +190,18 @@ install_nextcloud() { ensure_docker_dir_ownership "$DIR" cd "$DIR" || return 1 - local DB_PASS - DB_PASS=$(generate_password 32) - local NC_ADMIN_PASS - NC_ADMIN_PASS=$(generate_password 16) + # Reused across reruns if already set — the MariaDB volume keeps DB_PASS + # from its first init (regenerating it would lock Nextcloud out of its + # own database), and NEXTCLOUD_ADMIN_USER/PASSWORD are only consulted by + # the container on its very first boot to create the admin account — + # printing a fresh NC_ADMIN_PASS on every rerun would silently show a + # password that was never actually applied to the existing account. + local DB_PASS="" + [ -f ".env" ] && DB_PASS="$(grep '^MYSQL_PASSWORD=' .env | cut -d= -f2-)" + [ -n "$DB_PASS" ] || DB_PASS="$(generate_password 32)" + local NC_ADMIN_PASS="" + [ -f ".env" ] && NC_ADMIN_PASS="$(grep '^NEXTCLOUD_ADMIN_PASSWORD=' .env | cut -d= -f2-)" + [ -n "$NC_ADMIN_PASS" ] || NC_ADMIN_PASS="$(generate_password 16)" local TZ_VAL="${SITE_TZ:-UTC}" # ── Dockerfile ──────────────────────────────────────────────────────────