diff --git a/13/alpine3.21/docker-ensure-initdb.sh b/13/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/13/alpine3.21/docker-ensure-initdb.sh +++ b/13/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/alpine3.21/docker-entrypoint.sh b/13/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/13/alpine3.21/docker-entrypoint.sh +++ b/13/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/alpine3.22/docker-ensure-initdb.sh b/13/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/13/alpine3.22/docker-ensure-initdb.sh +++ b/13/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/alpine3.22/docker-entrypoint.sh b/13/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/13/alpine3.22/docker-entrypoint.sh +++ b/13/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/bookworm/docker-ensure-initdb.sh b/13/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/13/bookworm/docker-ensure-initdb.sh +++ b/13/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/bookworm/docker-entrypoint.sh b/13/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/13/bookworm/docker-entrypoint.sh +++ b/13/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/bullseye/docker-ensure-initdb.sh b/13/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/13/bullseye/docker-ensure-initdb.sh +++ b/13/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/13/bullseye/docker-entrypoint.sh b/13/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/13/bullseye/docker-entrypoint.sh +++ b/13/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/alpine3.21/docker-ensure-initdb.sh b/14/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/14/alpine3.21/docker-ensure-initdb.sh +++ b/14/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/alpine3.21/docker-entrypoint.sh b/14/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/14/alpine3.21/docker-entrypoint.sh +++ b/14/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/alpine3.22/docker-ensure-initdb.sh b/14/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/14/alpine3.22/docker-ensure-initdb.sh +++ b/14/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/alpine3.22/docker-entrypoint.sh b/14/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/14/alpine3.22/docker-entrypoint.sh +++ b/14/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/bookworm/docker-ensure-initdb.sh b/14/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/14/bookworm/docker-ensure-initdb.sh +++ b/14/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/bookworm/docker-entrypoint.sh b/14/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/14/bookworm/docker-entrypoint.sh +++ b/14/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/bullseye/docker-ensure-initdb.sh b/14/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/14/bullseye/docker-ensure-initdb.sh +++ b/14/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/14/bullseye/docker-entrypoint.sh b/14/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/14/bullseye/docker-entrypoint.sh +++ b/14/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/alpine3.21/docker-ensure-initdb.sh b/15/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/15/alpine3.21/docker-ensure-initdb.sh +++ b/15/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/alpine3.21/docker-entrypoint.sh b/15/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/15/alpine3.21/docker-entrypoint.sh +++ b/15/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/alpine3.22/docker-ensure-initdb.sh b/15/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/15/alpine3.22/docker-ensure-initdb.sh +++ b/15/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/alpine3.22/docker-entrypoint.sh b/15/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/15/alpine3.22/docker-entrypoint.sh +++ b/15/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/bookworm/docker-ensure-initdb.sh b/15/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/15/bookworm/docker-ensure-initdb.sh +++ b/15/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/bookworm/docker-entrypoint.sh b/15/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/15/bookworm/docker-entrypoint.sh +++ b/15/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/bullseye/docker-ensure-initdb.sh b/15/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/15/bullseye/docker-ensure-initdb.sh +++ b/15/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/15/bullseye/docker-entrypoint.sh b/15/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/15/bullseye/docker-entrypoint.sh +++ b/15/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/alpine3.21/docker-ensure-initdb.sh b/16/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/16/alpine3.21/docker-ensure-initdb.sh +++ b/16/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/alpine3.21/docker-entrypoint.sh b/16/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/16/alpine3.21/docker-entrypoint.sh +++ b/16/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/alpine3.22/docker-ensure-initdb.sh b/16/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/16/alpine3.22/docker-ensure-initdb.sh +++ b/16/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/alpine3.22/docker-entrypoint.sh b/16/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/16/alpine3.22/docker-entrypoint.sh +++ b/16/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/bookworm/docker-ensure-initdb.sh b/16/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/16/bookworm/docker-ensure-initdb.sh +++ b/16/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/bookworm/docker-entrypoint.sh b/16/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/16/bookworm/docker-entrypoint.sh +++ b/16/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/bullseye/docker-ensure-initdb.sh b/16/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/16/bullseye/docker-ensure-initdb.sh +++ b/16/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/16/bullseye/docker-entrypoint.sh b/16/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/16/bullseye/docker-entrypoint.sh +++ b/16/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/alpine3.21/docker-ensure-initdb.sh b/17/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/17/alpine3.21/docker-ensure-initdb.sh +++ b/17/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/alpine3.21/docker-entrypoint.sh b/17/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/17/alpine3.21/docker-entrypoint.sh +++ b/17/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/alpine3.22/docker-ensure-initdb.sh b/17/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/17/alpine3.22/docker-ensure-initdb.sh +++ b/17/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/alpine3.22/docker-entrypoint.sh b/17/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/17/alpine3.22/docker-entrypoint.sh +++ b/17/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/bookworm/docker-ensure-initdb.sh b/17/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/17/bookworm/docker-ensure-initdb.sh +++ b/17/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/bookworm/docker-entrypoint.sh b/17/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/17/bookworm/docker-entrypoint.sh +++ b/17/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/bullseye/docker-ensure-initdb.sh b/17/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/17/bullseye/docker-ensure-initdb.sh +++ b/17/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/17/bullseye/docker-entrypoint.sh b/17/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/17/bullseye/docker-entrypoint.sh +++ b/17/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/alpine3.21/Dockerfile b/18/alpine3.21/Dockerfile index 86aad693fd..e9eff8d01f 100644 --- a/18/alpine3.21/Dockerfile +++ b/18/alpine3.21/Dockerfile @@ -190,10 +190,13 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql -ENV PGDATA /var/lib/postgresql/data -# this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) -RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" -VOLUME /var/lib/postgresql/data +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/18/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/18/alpine3.21/docker-ensure-initdb.sh b/18/alpine3.21/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/18/alpine3.21/docker-ensure-initdb.sh +++ b/18/alpine3.21/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/alpine3.21/docker-entrypoint.sh b/18/alpine3.21/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/18/alpine3.21/docker-entrypoint.sh +++ b/18/alpine3.21/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/alpine3.22/Dockerfile b/18/alpine3.22/Dockerfile index c4cc148dde..248d5cb987 100644 --- a/18/alpine3.22/Dockerfile +++ b/18/alpine3.22/Dockerfile @@ -190,10 +190,13 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql -ENV PGDATA /var/lib/postgresql/data -# this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) -RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" -VOLUME /var/lib/postgresql/data +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/18/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/18/alpine3.22/docker-ensure-initdb.sh b/18/alpine3.22/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/18/alpine3.22/docker-ensure-initdb.sh +++ b/18/alpine3.22/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/alpine3.22/docker-entrypoint.sh b/18/alpine3.22/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/18/alpine3.22/docker-entrypoint.sh +++ b/18/alpine3.22/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/bookworm/Dockerfile b/18/bookworm/Dockerfile index f71b81b9f3..88e36344e0 100644 --- a/18/bookworm/Dockerfile +++ b/18/bookworm/Dockerfile @@ -183,10 +183,13 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql -ENV PGDATA /var/lib/postgresql/data -# this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) -RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" -VOLUME /var/lib/postgresql/data +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/18/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/18/bookworm/docker-ensure-initdb.sh b/18/bookworm/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/18/bookworm/docker-ensure-initdb.sh +++ b/18/bookworm/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/bookworm/docker-entrypoint.sh b/18/bookworm/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/18/bookworm/docker-entrypoint.sh +++ b/18/bookworm/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/bullseye/Dockerfile b/18/bullseye/Dockerfile index c0e3724400..b2ec63d5b9 100644 --- a/18/bullseye/Dockerfile +++ b/18/bullseye/Dockerfile @@ -183,10 +183,13 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql -ENV PGDATA /var/lib/postgresql/data -# this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) -RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" -VOLUME /var/lib/postgresql/data +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/18/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/18/bullseye/docker-ensure-initdb.sh b/18/bullseye/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/18/bullseye/docker-ensure-initdb.sh +++ b/18/bullseye/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/18/bullseye/docker-entrypoint.sh b/18/bullseye/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/18/bullseye/docker-entrypoint.sh +++ b/18/bullseye/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index 29be5edb24..e64ad2fc2f 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -212,10 +212,20 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql +{{ if .major >= 18 then ( -}} +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/{{ .major | tostring }}/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) +{{ ) else ( -}} ENV PGDATA /var/lib/postgresql/data # this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" VOLUME /var/lib/postgresql/data +{{ ) end -}} COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template index 340047f611..de0ea03974 100644 --- a/Dockerfile-debian.template +++ b/Dockerfile-debian.template @@ -183,10 +183,20 @@ RUN set -eux; \ RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql +{{ if .major >= 18 then ( -}} +# +# NOTE: in 18+, PGDATA has changed to match the pg_ctlcluster standard directory structure, and the VOLUME has moved from /var/lib/postgresql/data to /var/lib/postgresql +# +ENV PGDATA /var/lib/postgresql/{{ .major | tostring }}/docker +RUN ln -svT . /var/lib/postgresql/data # https://github.com/docker-library/postgres/pull/1259#issuecomment-2215477494 +VOLUME /var/lib/postgresql +# ("/var/lib/postgresql" is already pre-created with suitably usable permissions above) +{{ ) else ( -}} ENV PGDATA /var/lib/postgresql/data # this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values) RUN install --verbose --directory --owner postgres --group postgres --mode 1777 "$PGDATA" VOLUME /var/lib/postgresql/data +{{ ) end -}} COPY docker-entrypoint.sh docker-ensure-initdb.sh /usr/local/bin/ RUN ln -sT docker-ensure-initdb.sh /usr/local/bin/docker-enforce-initdb.sh diff --git a/docker-ensure-initdb.sh b/docker-ensure-initdb.sh index ae1f6b6b90..e9b15ef77d 100755 --- a/docker-ensure-initdb.sh +++ b/docker-ensure-initdb.sh @@ -33,6 +33,7 @@ fi # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index ae40666ca1..5a62870b50 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -154,6 +154,29 @@ docker_verify_minimum_env() { EOWARN fi } +# similar to the above, but errors if there are any "old" databases detected (usually due to upgrades without pg_upgrade) +docker_error_old_databases() { + if [ -n "${OLD_DATABASES[0]:-}" ]; then + cat >&2 <<-EOE + Error: in 18+, these Docker images are configured to store database data in a + format which is compatible with "pg_ctlcluster" (specifically, using + major-version-specific directory names). This better reflects how + PostgreSQL itself works, and how upgrades are to be performed. + + See also https://github.com/docker-library/postgres/pull/1259 + + Counter to that, there appears to be PostgreSQL data in: + ${OLD_DATABASES[*]} + + This is usually the result of upgrading the Docker image without upgrading + the underlying database using "pg_upgrade" (which requires both versions). + + See https://github.com/docker-library/postgres/issues/37 for a (long) + discussion around this process, and suggestions for how to do so. + EOE + exit 1 + fi +} # usage: docker_process_init_files [file [file [...]]] # ie: docker_process_init_files /always-initdb.d/* @@ -230,9 +253,17 @@ docker_setup_env() { declare -g DATABASE_ALREADY_EXISTS : "${DATABASE_ALREADY_EXISTS:=}" + declare -ag OLD_DATABASES=() # look specifically for PG_VERSION, as it is expected in the DB dir if [ -s "$PGDATA/PG_VERSION" ]; then DATABASE_ALREADY_EXISTS='true' + elif [ "$PGDATA" = "/var/lib/postgresql/$PG_MAJOR/docker" ]; then + # https://github.com/docker-library/postgres/pull/1259 + for d in /var/lib/postgresql /var/lib/postgresql/data /var/lib/postgresql/*/docker; do + if [ -s "$d/PG_VERSION" ]; then + OLD_DATABASES+=( "$d" ) + fi + done fi } @@ -319,6 +350,7 @@ _main() { # only run initialization on an empty data directory if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env + docker_error_old_databases # check dir permissions to reduce likelihood of half-initialized database ls /docker-entrypoint-initdb.d/ > /dev/null