From 00985e0a4dc76f4e53956c16809984e4d487e18a Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 11:29:04 +0100 Subject: [PATCH 1/3] Fix mainnet variant so users of the legacy web3signer package can migrate - mainnet: build postgres from Dockerfile.debian. Existing mainnet postgres_data volumes are owned by the Debian postgres uid (999); the Alpine image (uid 70) cannot read them, which is what broke 2.0.10 in Nov 2024. - flyway: migrate ${POSTGRES_DB} instead of the hardcoded "web3signer" database, and connect as ${POSTGRES_USER}. The migrate path was dormant (schema has been at V12) but would fail for mainnet and gnosis on the next slashing-protection migration. - web3signer: --http-host-allowlist=* to match the legacy mainnet package (changed there in 2.0.12). - postgres: add the pg_isready healthcheck the legacy package had. - mainnet manifest: restore the legacy warnings. Co-Authored-By: Claude Opus 5.5 --- docker-compose.yml | 5 +++++ package_variants/mainnet/dappnode_package.json | 6 +++++- package_variants/mainnet/docker-compose.yml | 6 +++++- services/flyway/entrypoint.sh | 4 ++-- services/web3signer/entrypoint.sh | 5 +---- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2260c50..d643cd0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,6 +46,11 @@ services: WEB3SIGNER_VERSION: 26.10.0 DATA_DIR: /var/lib/postgresql/data POSTGRES_USER: postgres + healthcheck: + test: pg_isready -U postgres + interval: 5s + timeout: 5s + retries: 5 user: postgres volumes: - postgres_data:/var/lib/postgresql/data diff --git a/package_variants/mainnet/dappnode_package.json b/package_variants/mainnet/dappnode_package.json index 1d5f48a..a1e0753 100644 --- a/package_variants/mainnet/dappnode_package.json +++ b/package_variants/mainnet/dappnode_package.json @@ -19,5 +19,9 @@ "envs": ["CONSENSUS_CLIENT_MAINNET"], "services": ["web3signer"] } - ] + ], + "warnings": { + "onMajorUpdate": "This update will do a migration, it is recommended to have a backup of your keystores (http://my.dappnode/#/packages/web3signer.dnp.dappnode.eth/backup)", + "onRemove": "Make sure your web3signer does not have this client selected or you will stop validating! (Packages > web3signer > config > client)" + } } diff --git a/package_variants/mainnet/docker-compose.yml b/package_variants/mainnet/docker-compose.yml index cddf285..833ff7c 100644 --- a/package_variants/mainnet/docker-compose.yml +++ b/package_variants/mainnet/docker-compose.yml @@ -30,7 +30,11 @@ services: postgres: build: - dockerfile: Dockerfile.alpine + # Must stay on Debian: existing mainnet postgres_data volumes are owned by + # the Debian postgres uid (999). The Alpine image runs postgres as uid 70 + # and cannot read them (postgres crash-loops with "Permission denied" on + # /var/lib/postgresql/data), so flyway and web3signer never start. + dockerfile: Dockerfile.debian args: POSTGRES_PASSWORD: mainnet PGPASSWORD: mainnet diff --git a/services/flyway/entrypoint.sh b/services/flyway/entrypoint.sh index 9550adb..2b7c71a 100755 --- a/services/flyway/entrypoint.sh +++ b/services/flyway/entrypoint.sh @@ -17,7 +17,7 @@ set -e # Get postgresql database version and trim whitespaces # PGPASSWORD=${PGPASSWORD} -DATABASE_VERSION=$(psql -U postgres -h "${POSTGRES_DOMAIN}" -p 5432 -d "${POSTGRES_DB}" -t -A -c "SELECT version FROM database_version WHERE id=1;") +DATABASE_VERSION=$(psql -U "${POSTGRES_USER}" -h "${POSTGRES_DOMAIN}" -p 5432 -d "${POSTGRES_DB}" -t -A -c "SELECT version FROM database_version WHERE id=1;") # Get the latest migration file version (ending in .sql) and trim whitespaces LATEST_MIGRATION_VERSION=$(ls -1 /flyway/sql/ | grep -E "V[0-9]+__.*.sql$" | tail -n 1 | cut -d'_' -f1 | cut -d'V' -f2 | sed 's/^0*//' | tr -d '[:space:]') @@ -36,7 +36,7 @@ if [ "$DATABASE_VERSION" -ge "$LATEST_MIGRATION_VERSION" ]; then exit 0 else echo "[INFO - entrypoint] Database version is less than the latest migration file version. Migrating..." - flyway -baselineOnMigrate="true" -baselineVersion="${DATABASE_VERSION}" -url="jdbc:postgresql://${POSTGRES_DOMAIN}:5432/web3signer" -user="${POSTGRES_USER}" -password="${PGPASSWORD}" -connectRetries=60 migrate + flyway -baselineOnMigrate="true" -baselineVersion="${DATABASE_VERSION}" -url="jdbc:postgresql://${POSTGRES_DOMAIN}:5432/${POSTGRES_DB}" -user="${POSTGRES_USER}" -password="${PGPASSWORD}" -connectRetries=60 migrate echo "[INFO - entrypoint] Migration completed" exit 0 fi diff --git a/services/web3signer/entrypoint.sh b/services/web3signer/entrypoint.sh index ecbd2c0..23e7a84 100755 --- a/services/web3signer/entrypoint.sh +++ b/services/web3signer/entrypoint.sh @@ -9,7 +9,6 @@ KEYFILES_DIR="/data/keyfiles" WEB3SIGNER_DOMAIN=$(get_web3signer_domain "${NETWORK}" "${SUPPORTED_NETWORKS}") generate_cors_settings() { - CORS_ALLOWLIST="web3signer.${WEB3SIGNER_DOMAIN},brain.${WEB3SIGNER_DOMAIN},signer.${NETWORK}.dncore.dappnode,signer.${NETWORK}.staker.dappnode" CORS_ORIGINS="http://web3signer.${WEB3SIGNER_DOMAIN},http://brain.${WEB3SIGNER_DOMAIN},http://signer.${NETWORK}.dncore.dappnode,http://signer.${NETWORK}.staker.dappnode" consensus_dnp=$(get_value_from_global_env "CONSENSUS_CLIENT" "${NETWORK}") @@ -17,11 +16,9 @@ generate_cors_settings() { consensus_domain=$(get_client_network_alias "${consensus_dnp}") if [ -n "${consensus_domain}" ]; then - CORS_ALLOWLIST="${CORS_ALLOWLIST},validator.${consensus_domain}" CORS_ORIGINS="${CORS_ORIGINS},http://validator.${consensus_domain}" fi - echo "[INFO - entrypoint] Generated CORS_ALLOWLIST: ${CORS_ALLOWLIST}" echo "[INFO - entrypoint] Generated CORS_ORIGINS: ${CORS_ORIGINS}" } @@ -38,7 +35,7 @@ run_web3signer() { FLAGS="--key-store-path=$KEYFILES_DIR \ --http-listen-port=9000 \ --http-listen-host=0.0.0.0 \ - --http-host-allowlist=$CORS_ALLOWLIST \ + --http-host-allowlist=* \ --http-cors-origins=$CORS_ORIGINS \ --metrics-enabled=true \ --metrics-host 0.0.0.0 \ From 2d65679acdd96b94f3f766d12a204337a6d1dc6b Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 11:31:44 +0100 Subject: [PATCH 2/3] Drop legacy warnings from mainnet manifest Co-Authored-By: Claude Opus 5.5 --- package_variants/mainnet/dappnode_package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/package_variants/mainnet/dappnode_package.json b/package_variants/mainnet/dappnode_package.json index a1e0753..1d5f48a 100644 --- a/package_variants/mainnet/dappnode_package.json +++ b/package_variants/mainnet/dappnode_package.json @@ -19,9 +19,5 @@ "envs": ["CONSENSUS_CLIENT_MAINNET"], "services": ["web3signer"] } - ], - "warnings": { - "onMajorUpdate": "This update will do a migration, it is recommended to have a backup of your keystores (http://my.dappnode/#/packages/web3signer.dnp.dappnode.eth/backup)", - "onRemove": "Make sure your web3signer does not have this client selected or you will stop validating! (Packages > web3signer > config > client)" - } + ] } From 527a1141554b4dd72a390094e5d2dcc8c1587f55 Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 16:26:31 +0100 Subject: [PATCH 3/3] flyway: wait for postgres instead of exiting while it starts web3signer depends on flyway completing successfully. Exiting 1 while postgres is still starting relies on docker compose waiting through the restart policy; compose versions that abort `up` on the first non-zero exit make the DAppManager roll the update back. Wait up to 10 minutes (below the DAppManager's 15 minute compose timeout) for pg_isready. Co-Authored-By: Claude Opus 5.5 --- services/flyway/entrypoint.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/services/flyway/entrypoint.sh b/services/flyway/entrypoint.sh index 2b7c71a..98a9046 100755 --- a/services/flyway/entrypoint.sh +++ b/services/flyway/entrypoint.sh @@ -13,6 +13,22 @@ else POSTGRES_DOMAIN="postgres.web3signer-${NETWORK}.dappnode" fi +# Wait for postgres to accept connections instead of exiting early: web3signer only starts once +# flyway completes successfully, and some docker compose versions abort `up` (making the +# DAppManager roll back the update) on the first non-zero exit of a dependency, even with a +# restart policy. Postgres can take a while to start, e.g. on first start or during an upgrade. +POSTGRES_WAIT_SECONDS=600 +waited=0 +until pg_isready -q -h "${POSTGRES_DOMAIN}" -p 5432 -U "${POSTGRES_USER}" -d "${POSTGRES_DB}"; do + if [ "$waited" -ge "$POSTGRES_WAIT_SECONDS" ]; then + echo "[ERROR - entrypoint] Postgres at ${POSTGRES_DOMAIN} not ready after ${POSTGRES_WAIT_SECONDS}s. Exiting..." + exit 1 + fi + [ $((waited % 30)) -eq 0 ] && echo "[INFO - entrypoint] Waiting for postgres at ${POSTGRES_DOMAIN}..." + sleep 2 + waited=$((waited + 2)) +done + set -e # Get postgresql database version and trim whitespaces