From 1823336f893073d594d529bada9552c253b19a6e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 14:26:08 +0000 Subject: [PATCH] Pin exact postgres/windmill versions, add auto pg_upgrade, extend healthcheck Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/505f902b-a447-4fcc-9203-f11119207409 Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com> --- Containers/windmill/Dockerfile | 28 ++++++++--- Containers/windmill/healthcheck.sh | 5 ++ Containers/windmill/start.sh | 78 ++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/Containers/windmill/Dockerfile b/Containers/windmill/Dockerfile index d21115bb..7d54eb7a 100644 --- a/Containers/windmill/Dockerfile +++ b/Containers/windmill/Dockerfile @@ -1,10 +1,16 @@ # syntax=docker/dockerfile:latest -# Stage 1: PostgreSQL server from the official Debian bookworm image +# Stage 1: Previous PostgreSQL major version – binaries are copied into the +# final image so that start.sh can run pg_upgrade when the data directory was +# created by an older major version. +FROM postgres:16.13-bookworm AS postgres-prev + +# Stage 2: Current PostgreSQL server – version is pinned to a full patch +# release so builds are reproducible and the exact version is auditable. # (matches the Debian bookworm base used by windmill-labs/windmill) -FROM postgres:17-bookworm AS postgres-base +FROM postgres:17.9-bookworm AS postgres-base # Final stage: derive from the official Windmill image and bundle PostgreSQL -FROM ghcr.io/windmill-labs/windmill:main +FROM ghcr.io/windmill-labs/windmill:1.691.1 USER root @@ -18,6 +24,10 @@ COPY --from=postgres-base /usr/bin/pg_dump \ /usr/bin/pg_restore \ /usr/bin/ +# Copy previous PostgreSQL major version binaries for automatic pg_upgrade +COPY --from=postgres-prev /usr/lib/postgresql /usr/lib/postgresql +COPY --from=postgres-prev /usr/share/postgresql /usr/share/postgresql + # Install supervisor from standard Debian repos (remove broken external sources first) # hadolint ignore=DL3008 RUN set -ex; \ @@ -60,9 +70,15 @@ RUN set -ex; \ /var/run/supervisord; \ \ # Create symlinks so postgres tools are on PATH - ln -sf /usr/lib/postgresql/17/bin/postgres /usr/local/bin/postgres; \ - ln -sf /usr/lib/postgresql/17/bin/initdb /usr/local/bin/initdb; \ - ln -sf /usr/lib/postgresql/17/bin/pg_ctl /usr/local/bin/pg_ctl; \ + ln -sf /usr/lib/postgresql/17/bin/postgres /usr/local/bin/postgres; \ + ln -sf /usr/lib/postgresql/17/bin/initdb /usr/local/bin/initdb; \ + ln -sf /usr/lib/postgresql/17/bin/pg_ctl /usr/local/bin/pg_ctl; \ + ln -sf /usr/lib/postgresql/17/bin/pg_isready /usr/local/bin/pg_isready; \ + ln -sf /usr/lib/postgresql/17/bin/pg_upgrade /usr/local/bin/pg_upgrade; \ + \ + # Record the current PostgreSQL major version so start.sh can detect when + # the bundled major version has changed and trigger an automatic pg_upgrade. + echo "17" > /etc/postgres-major-version; \ \ # Write a build-time marker so start.sh can detect image updates and # clear the cache volume when a new image version is deployed. diff --git a/Containers/windmill/healthcheck.sh b/Containers/windmill/healthcheck.sh index 41f50d66..4f196b88 100644 --- a/Containers/windmill/healthcheck.sh +++ b/Containers/windmill/healthcheck.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Check if PostgreSQL is accepting connections on the Unix socket +if ! pg_isready -h /var/run/postgresql -q 2>/dev/null; then + exit 1 +fi + # Check if Windmill is accepting connections on port 8000 if ! nc -z localhost 8000; then exit 1 diff --git a/Containers/windmill/start.sh b/Containers/windmill/start.sh index f1641242..90fd0e79 100644 --- a/Containers/windmill/start.sh +++ b/Containers/windmill/start.sh @@ -30,6 +30,84 @@ fi PGDATA="/var/lib/postgresql/data" +# ── Automatic PostgreSQL major-version upgrade ──────────────────────────────── +# The image records the current PG major version in /etc/postgres-major-version +# at build time. On each start we compare that against the version stored in +# $PGDATA/PG_VERSION (written by initdb). When the image ships a newer major +# version we run pg_upgrade automatically; the old binaries are kept in the +# image for exactly this purpose. +CURRENT_PG_MAJOR=$(cat /etc/postgres-major-version 2>/dev/null || postgres --version | grep -oP '\d+' | head -1) + +if [ -f "$PGDATA/PG_VERSION" ]; then + DATA_PG_MAJOR=$(cat "$PGDATA/PG_VERSION") + + if [ "$DATA_PG_MAJOR" -gt "$CURRENT_PG_MAJOR" ]; then + echo "ERROR: Data directory was created by PostgreSQL $DATA_PG_MAJOR but this image ships $CURRENT_PG_MAJOR." + echo "Downgrade is not supported. Please use a newer image version." + exit 1 + fi + + if [ "$DATA_PG_MAJOR" -lt "$CURRENT_PG_MAJOR" ]; then + echo "PostgreSQL major-version upgrade required: $DATA_PG_MAJOR → $CURRENT_PG_MAJOR" + + OLD_BIN="/usr/lib/postgresql/${DATA_PG_MAJOR}/bin" + NEW_BIN="/usr/lib/postgresql/${CURRENT_PG_MAJOR}/bin" + PGDATA_NEW="/var/lib/postgresql/data_new" + + if [ ! -d "$OLD_BIN" ]; then + echo "ERROR: Old PostgreSQL $DATA_PG_MAJOR binaries not found at $OLD_BIN." + echo "Cannot upgrade automatically. Data is preserved at $PGDATA." + exit 1 + fi + + # Remove any leftover working directory from a previous failed attempt + rm -rf "$PGDATA_NEW" + + echo "Initializing new PostgreSQL $CURRENT_PG_MAJOR cluster..." + "$NEW_BIN/initdb" -D "$PGDATA_NEW" \ + --username=windmill \ + --auth-local=trust \ + --auth-host=trust \ + --no-instructions + + echo "Running pg_upgrade (this may take a moment)..." + # pg_upgrade writes log files to its working directory; use the volume + # root so they persist for post-upgrade inspection if needed. + cd /var/lib/postgresql + if ! "$NEW_BIN/pg_upgrade" \ + --old-bindir="$OLD_BIN" \ + --new-bindir="$NEW_BIN" \ + --old-datadir="$PGDATA" \ + --new-datadir="$PGDATA_NEW"; then + echo "ERROR: pg_upgrade failed. Old data is preserved at $PGDATA." + echo "Check /var/lib/postgresql/pg_upgrade_output.d/ for details." + rm -rf "$PGDATA_NEW" + exit 1 + fi + + # Swap data directories: current → backup, upgraded → active + mv "$PGDATA" "${PGDATA}_old_v${DATA_PG_MAJOR}" + mv "$PGDATA_NEW" "$PGDATA" + + # Restore the custom connection settings that a fresh initdb does not set + cat > "$PGDATA/pg_hba.conf" << 'HBAEOF' +# TYPE DATABASE USER ADDRESS METHOD +local all all trust +host all all 127.0.0.1/32 trust +host all all ::1/128 trust +HBAEOF + + echo "listen_addresses = 'localhost'" >> "$PGDATA/postgresql.conf" + + # Remove pg_upgrade artefacts from the working directory + rm -rf /var/lib/postgresql/pg_upgrade_output.d + + echo "PostgreSQL upgrade to $CURRENT_PG_MAJOR complete." + echo "Old data backed up at ${PGDATA}_old_v${DATA_PG_MAJOR} – safe to remove once verified." + fi +fi +# ── End of automatic upgrade section ───────────────────────────────────────── + # Initialize PostgreSQL data directory on first run. # No su/chown needed — we already own PGDATA (the windmill user owns the volume). if [ -z "$(ls -A "$PGDATA" 2>/dev/null)" ]; then