From a0f0bc087e67d135231830009d78f6f0baa2abbe Mon Sep 17 00:00:00 2001 From: librelad Date: Tue, 18 Aug 2026 19:55:32 +0100 Subject: [PATCH] fix(matrix,stoat): derive the public host without reading the compose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both hooks read their host (and matrix its database password) back out of the deployed docker-compose.yml. That cannot work: install_post_compose runs after the compose TEMPLATE is copied but before dockerConfigSetupFileWithData fills the tags, so at that point the file still holds raw placeholders. Matrix aborted with "Database password was not generated in the compose file" even though the password had been generated correctly — it just was not in the compose yet. Derive the host from port_subdomains[0] + domain_full instead, both already in scope from variables_init_app, applying the same empty/@/root rule as tagsProcessorPortSubdomains so the computed name and the Traefik rule generated later cannot drift apart. Matrix takes its database password from CFG_MATRIX_DB_PASSWORD_1, which is where the secret is generated and remembered and is the same variable the compose tag is filled from a step later. The error messages now name the actual missing thing — the domain — rather than blaming the compose file. Co-Authored-By: Claude Opus 5 --- .../matrix/scripts/matrix_install_hooks.sh | 24 +++++++-------- .../stoat/scripts/stoat_install_hooks.sh | 29 ++++++++++++++----- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/containers/matrix/scripts/matrix_install_hooks.sh b/containers/matrix/scripts/matrix_install_hooks.sh index e48e4a8..2196f0b 100644 --- a/containers/matrix/scripts/matrix_install_hooks.sh +++ b/containers/matrix/scripts/matrix_install_hooks.sh @@ -53,21 +53,21 @@ matrix_install_post_compose() echo "" local server_name - server_name=$(_matrixServerName "$app_name") + server_name=$(_matrixServerName) if [[ -z "$server_name" ]]; then - isError "Could not determine the homeserver name from the compose file — aborting Synapse configuration." - isNotice "Check that CFG_MATRIX_PORT_1 is public and Traefik-managed, then reinstall." + isError "No domain is configured — cannot determine the Matrix server_name." + isNotice "Set CFG_DOMAIN_${CFG_MATRIX_DOMAIN:-1} (General → Network), then reinstall." return 1 fi - # Must match the password the compose handed to Postgres. Read it back from - # the deployed compose rather than from CFG_MATRIX_DB_PASSWORD_1: this hook - # runs after templating, so the compose is the settled value, and it stays - # correct even on an install whose config still holds the placeholder. - local db_password - db_password=$(tagsManagerGetTagContent "$app_dir/docker-compose.yml" "MATRIX_DB_PASSWORD_1_TAG") - if [[ -z "$db_password" || "$db_password" == "MATRIX_DB_PASSWORD_1_DATA" ]]; then - isError "Database password was not generated in the compose file — aborting Synapse configuration." + # Same value the compose will hand to Postgres. Taken from the config rather + # than the compose because the compose is not substituted yet at this point; + # the config is where the secret is generated and remembered, and the + # #LIBREPORTAL|MATRIX_DB_PASSWORD_1_TAG| line is filled from this very + # variable a step later, so the two cannot disagree. + local db_password="$CFG_MATRIX_DB_PASSWORD_1" + if [[ -z "$db_password" || "$db_password" == RANDOMIZEDPASSWORD* ]]; then + isError "CFG_MATRIX_DB_PASSWORD_1 was not generated — aborting Synapse configuration." return 1 fi @@ -216,7 +216,7 @@ matrix_install_post() { local app_name="$1" local server_name - server_name=$(_matrixServerName "$app_name") + server_name=$(_matrixServerName) local admin_user="${CFG_MATRIX_ADMIN_USERNAME:-admin}" echo "" diff --git a/containers/stoat/scripts/stoat_install_hooks.sh b/containers/stoat/scripts/stoat_install_hooks.sh index 7ad50d1..b17b0b3 100644 --- a/containers/stoat/scripts/stoat_install_hooks.sh +++ b/containers/stoat/scripts/stoat_install_hooks.sh @@ -22,12 +22,25 @@ stoat_install_pre() fi } -# The public host, read back from the deployed compose once tag substitution has -# filled it in. Everything else in this file is derived from it. +# The public host every generated file is derived from. +# +# Computed from the port arrays and $domain_full that variables_init_app puts in +# scope, NOT read back from the deployed compose: install_post_compose runs +# before dockerConfigSetupFileWithData, so the compose still holds raw +# placeholders at this point. port_subdomains[0] is CFG_STOAT_PORT_1 (the Caddy +# router); the empty/@/root cases mirror tagsProcessorPortSubdomains so this and +# the Traefik rule generated later cannot drift apart. _stoatDomain() { - local app_name="$1" - tagsManagerGetTagContent "$containers_dir$app_name/docker-compose.yml" "DOMAINSUBNAME_TAG_1" + local sub="${port_subdomains[0]}" + [[ -z "$domain_full" ]] && return 1 + if [[ "$sub" == "@" || "$sub" == "root" ]]; then + echo "$domain_full" + elif [[ -n "$sub" ]]; then + echo "${sub}.${domain_full}" + else + echo "stoat.${domain_full}" + fi } # Generate secrets.env if it does not already exist. Returns without touching an @@ -83,10 +96,10 @@ stoat_install_post_compose() echo "" local domain - domain=$(_stoatDomain "$app_name") + domain=$(_stoatDomain) if [[ -z "$domain" ]]; then - isError "Could not determine the public host from the compose file — aborting Stoat configuration." - isNotice "Check that CFG_STOAT_PORT_1 is public and Traefik-managed, then reinstall." + isError "No domain is configured — cannot determine the public host for Stoat." + isNotice "Set CFG_DOMAIN_${CFG_STOAT_DOMAIN:-1} (General → Network), then reinstall." return 1 fi @@ -203,7 +216,7 @@ stoat_install_post() { local app_name="$1" local domain - domain=$(_stoatDomain "$app_name") + domain=$(_stoatDomain) echo "" isNotice "Stoat first run:"