diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 59bd432..dd9321c 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -180,11 +180,13 @@ RUN apk update && \ ENV PGTARGET=${PGTARGET} # Copy across the post-upgrade shell script -COPY pgautoupgrade-postupgrade.sh /usr/local/bin/ +COPY pgautoupgrade-postupgrade.sh pgautoupgrade-healthcheck.sh /usr/local/bin/ # Set up the script run by the container when it starts WORKDIR /var/lib/postgresql COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +HEALTHCHECK CMD /usr/local/bin/pgautoupgrade-healthcheck.sh + CMD ["postgres"] diff --git a/Dockerfile.bookworm b/Dockerfile.bookworm index 4e7aecb..842f9cd 100644 --- a/Dockerfile.bookworm +++ b/Dockerfile.bookworm @@ -175,11 +175,13 @@ RUN apt update && \ ENV PGTARGET=${PGTARGET} # Copy across the post-upgrade shell script -COPY pgautoupgrade-postupgrade.sh /usr/local/bin/ +COPY pgautoupgrade-postupgrade.sh pgautoupgrade-healthcheck.sh /usr/local/bin/ # Set up the script run by the container when it starts WORKDIR /var/lib/postgresql COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +HEALTHCHECK CMD /usr/local/bin/pgautoupgrade-healthcheck.sh + CMD ["postgres"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 538ad9f..f35936c 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,6 +2,9 @@ set -Eeo pipefail # TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) +# Define the path to the upgrade lock file using PGDATA if set, otherwise default +UPGRADE_LOCK_FILE="${PGDATA:-/var/lib/postgresql/data}/upgrade_in_progress.lock" + # usage: file_env VAR [DEFAULT] # ie: file_env 'XYZ_DB_PASSWORD' 'example' # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of @@ -308,6 +311,18 @@ get_bin_path() { fi } +# Function to create the upgrade lock file +create_upgrade_lock_file() { + echo "Creating upgrade lock file at $UPGRADE_LOCK_FILE" + touch "$UPGRADE_LOCK_FILE" +} + +# Function to remove the upgrade lock file +remove_upgrade_lock_file() { + echo "Removing upgrade lock file at $UPGRADE_LOCK_FILE" + rm -f "$UPGRADE_LOCK_FILE" +} + _main() { # if first arg looks like a flag, assume we want to run postgres server if [ "${1:0:1}" = '-' ]; then @@ -382,6 +397,7 @@ _main() { # If the version of PostgreSQL data files doesn't match our desired version, then upgrade them if [ "${PGVER}" != "${PGTARGET}" ]; then + create_upgrade_lock_file # Ensure the database files are a version we can upgrade local RECOGNISED=0 local OLDPATH=unset @@ -581,6 +597,7 @@ _main() { echo "The database has not yet been reindexed nor updated the query planner stats. Those " echo "will be done by a background task shortly. " echo "***************************************************************************************" + remove_upgrade_lock_file fi ### The main pgautoupgrade scripting ends here ### @@ -625,6 +642,12 @@ _main() { sync } +# Check if an upgrade lock file exists at script start and exit if it does +if [ -f "$UPGRADE_LOCK_FILE" ]; then + echo "Upgrade lock file already exists, indicating an incomplete previous upgrade. Exiting." + exit 1 +fi + if ! _is_sourced; then _main "$@" fi diff --git a/pgautoupgrade-healthcheck.sh b/pgautoupgrade-healthcheck.sh new file mode 100755 index 0000000..aed354e --- /dev/null +++ b/pgautoupgrade-healthcheck.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Define the path to the upgrade lock file using PGDATA if set, otherwise default +UPGRADE_LOCK_FILE="${PGDATA:-/var/lib/postgresql/data}/upgrade_in_progress.lock" + +# Check if an upgrade is in progress and keep the container alive +if [ -f "$UPGRADE_LOCK_FILE" ]; then + exit 0 +fi + +pg_isready -d "${POSTGRES_DB}" -U "${POSTGRES_USER}" + +# Capture the exit status of pg_isready +PG_ISREADY_STATUS=$? + +if [ $PG_ISREADY_STATUS -eq 0 ]; then + exit 0 +else + # Exit with the status of pg_isready + exit $PG_ISREADY_STATUS +fi