Author SHA1 Message Date
mayel 863538311d avoid postgres config clobber 2026-10-22 15:42:13 +01:00
4 changed files with 33 additions and 7 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ export PG_BACKUP_VERSION=v6
export MEILI_BACKUP_VERSION=v4
export SONIC_CFG_VERSION=v2
export SONIC_ENTRYPOINT_VERSION=v1
export POSTGRES_ENTRYPOINT_VERSION=v6
export POSTGRES_ENTRYPOINT_VERSION=v7
export POSTGRES_TUNE_VERSION=v2
export POSTGRES_CONF_TMPL_VERSION=v3
export BASH_ENVSUBST_VERSION=v1
+1 -1
View File
@@ -5,7 +5,7 @@ version: "3.8"
services:
static:
image: nginx:1.31.8-alpine
image: nginx:1.29.0-alpine
networks:
- proxy
volumes:
+1 -1
View File
@@ -39,7 +39,7 @@ services:
configs:
postgres_entrypoint:
name: ${STACK_NAME}_postgres_entrypoint_${POSTGRES_ENTRYPOINT_VERSION:-v6}
name: ${STACK_NAME}_postgres_entrypoint_${POSTGRES_ENTRYPOINT_VERSION:-v7}
file: postgres/postgres-entrypoint.sh
postgres_tune:
name: ${STACK_NAME}_postgres_tune_${POSTGRES_TUNE_VERSION:-v2}
+30 -4
View File
@@ -8,8 +8,12 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[[ "$SCRIPT_DIR" == "/" ]] && SCRIPT_DIR=""
# Configuration via environment variables
POSTGRES_CONF_PATH="${POSTGRES_CONF_PATH:-/var/lib/postgresql/data/postgresql.auto.conf}"
POSTGRES_START_CMD="${POSTGRES_START_CMD:-docker-entrypoint.sh postgres}"
# The tuned config is a standalone config_file OUTSIDE the data dir, so it never shares postgresql.auto.conf with `ALTER SYSTEM`. Bonfire's InstanceTuning clears its own ALTER SYSTEM writes on every app boot (`ALTER SYSTEM RESET`), which wiped the tuner's values when both lived in auto.conf. Now RESET falls back to this file, and admin ALTER SYSTEM values survive restarts. Outside the data dir also keeps a fresh volume empty for initdb.
# POSTGRES_CONF_PATH="${POSTGRES_CONF_PATH:-/var/lib/postgresql/data/postgresql.auto.conf}"
POSTGRES_CONF_PATH="${POSTGRES_CONF_PATH:-/etc/postgresql/bonfire.conf}"
# NOT `-c name=value` per setting: command-line values outrank postgresql.auto.conf and would silently disable InstanceTuning
POSTGRES_START_CMD="${POSTGRES_START_CMD:-docker-entrypoint.sh postgres -c config_file=${POSTGRES_CONF_PATH}}"
PGDATA="${PGDATA:-/var/lib/postgresql/data}"
# Check if envsubst is available, if not, load our bash implementation
if ! command -v envsubst &> /dev/null; then
@@ -45,10 +49,32 @@ if mkdir -p "${CONF_DIR}" 2>/dev/null; then
# Write the processed config
echo "$config" > "${POSTGRES_CONF_PATH}"
echo "PostgreSQL: Configuration generated at ${POSTGRES_CONF_PATH}"
# One-time cleanup for volumes created when this script wrote the tuned config INTO postgresql.auto.conf: those stale lines override the config_file above (and shared_buffers, max_connections etc. are not InstanceTuning knobs, so nothing else would ever clear them). Runs once per volume (marker file), so later admin ALTER SYSTEM values persist.
AUTO_CONF="${PGDATA}/postgresql.auto.conf"
TUNE_MARKER="${PGDATA}/.bonfire_tune_v2"
if [[ -f "${PGDATA}/PG_VERSION" && -f "${AUTO_CONF}" && ! -f "${TUNE_MARKER}" ]]; then
echo "PostgreSQL: removing keys the tuner now sets from ${AUTO_CONF} (one-time migration)"
tmp_conf="$(mktemp)"
# first input = the generated config (collect its keys), second = auto.conf (drop those keys, keep the rest)
awk 'NR==FNR { k=$0; sub(/[[:space:]]*=.*/, "", k); keys[k]=1; next }
{ k=$0; sub(/[[:space:]]*=.*/, "", k); if (!(k in keys)) print }' \
<(echo "$config") "${AUTO_CONF}" > "${tmp_conf}"
# write in place (not mv) so the file keeps its postgres ownership
cat "${tmp_conf}" > "${AUTO_CONF}"
rm -f "${tmp_conf}"
touch "${TUNE_MARKER}"
elif [[ ! -f "${PGDATA}/PG_VERSION" && ! -f "${TUNE_MARKER}" ]]; then
# Fresh volume: nothing to clean, but the marker can't be written yet (initdb needs an empty data dir). Write it once initdb is done, or the next boot would wrongly run the cleanup and drop admin ALTER SYSTEM values. The loop survives the exec below as an orphan and gives up after 10 minutes.
( for _ in $(seq 1 600); do
if [[ -f "${PGDATA}/PG_VERSION" ]]; then touch "${TUNE_MARKER}"; break; fi
sleep 1
done ) >/dev/null 2>&1 &
fi
# Check if we should start postgres
if [[ -n "${POSTGRES_START_CMD}" && "${POSTGRES_START_CMD}" != "none" ]]; then
# Start PostgreSQL - postgresql.auto.conf is automatically loaded from data dir
# Start PostgreSQL with the tuned config_file. postgresql.auto.conf (ALTER SYSTEM) is still loaded from the data dir and layered on top
exec ${POSTGRES_START_CMD}
else
echo "PostgreSQL: Skipping startup (POSTGRES_START_CMD is '${POSTGRES_START_CMD}')"