From 3fc60d46e72dd2551df7946cd71abde851a30d7e Mon Sep 17 00:00:00 2001 From: mazano Date: Fri, 29 Apr 2022 16:05:31 +0200 Subject: [PATCH] fix lock file mounts (#369) * fix lock file mounts --- README.md | 31 +++++++++++++++++++++++++++++++ scripts/env-data.sh | 25 ++++++++++++++++++++++--- scripts/setup-conf.sh | 14 +++++++++----- scripts/setup-database.sh | 14 +++----------- scripts/setup-pg_hba.sh | 2 +- scripts/setup-ssl.sh | 2 +- 6 files changed, 67 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index db9852b..a5276b1 100644 --- a/README.md +++ b/README.md @@ -370,6 +370,15 @@ You can alternatively mount an extra config file into the setting's folder i.e ```shell docker run --name "postgis" -v /data/extra.conf:/settings/extra.conf -p 25432:5432 -d -t kartoza/postgis ``` +The `/setting` folder stores the extra configuration and is copied to the proper directory + on runtime. The environment variable `EXTRA_CONF_DIR` controls the location of the mounted + folder. + +Then proceed to run the following: + +```shell + docker run --name "postgis" -e EXTRA_CONF_DIR=/etc/conf_settings -v /data:/etc/conf_settings -p 25432:5432 -d -t kartoza/postgis +``` If you want to reinitialize the data directory from scratch, you need to do: @@ -377,6 +386,20 @@ If you want to reinitialize the data directory from scratch, you need to do: 2. Set environment variables `RECREATE_DATADIR=TRUE`. Restart the service 3. The service will delete your `DATADIR` directory and start reinitializing your data directory from scratch. +### Lockfile + + During container startup, some lockfile are generated which prevent reinitialisation of some + settings. These lockfile are by default stored in the `/settings` folder, but a user can control + where to store these files using the environment variable `CONF_LOCKFILE_DIR` Example + + ``` + -e CONF_LOCKFILE_DIR=/opt/conf_lockfiles \ + -v /data/lock_files:/opt/conf_lockfiles + ``` + + **Note** If you change the environment variable to point to another location when you restart the container + the settings are reinitialized again. + ## Docker secrets To avoid passing sensitive information in environment variables, `_FILE` can be appended to @@ -458,6 +481,14 @@ The SQL script will be executed against the `gis` database. Additionally, a lock `/docker-entrypoint-initdb.d`, which will prevent the scripts from getting executed after the first container startup. Provide `IGNORE_INIT_HOOK_LOCKFILE=true` to execute the scripts on _every_ container start. +By default, the lockfile is generated in `/docker-entrypoint-initdb.d` but it can be overwritten by + passing the environment variable `SCRIPTS_LOCKFILE_DIR` which can point to another location i.e + + ```shell + -e SCRIPTS_LOCKFILE_DIR=/data/ \ + -v /data:/data + ``` + Currently, you can pass `.sql`, `.sql.gz` and `.sh` files as mounted volumes. ```shell diff --git a/scripts/env-data.sh b/scripts/env-data.sh index 733ed79..bc79b61 100644 --- a/scripts/env-data.sh +++ b/scripts/env-data.sh @@ -6,10 +6,13 @@ DEFAULT_DATADIR="/var/lib/postgresql/${POSTGRES_MAJOR_VERSION}/main" # Commented for documentation. You can specify the location of # pg_wal directory/volume using the following environment variable: # POSTGRES_INITDB_WALDIR (default value is unset) +DEFAULT_SCRIPTS_LOCKFILE_DIR="/docker-entrypoint.initdb.d" +DEFAULT_CONF_LOCKFILE_DIR="/settings" +DEFAULT_EXTRA_CONF_DIR="/settings" ROOT_CONF="/etc/postgresql/${POSTGRES_MAJOR_VERSION}/main" PG_ENV="$ROOT_CONF/environment" CONF="$ROOT_CONF/postgresql.conf" -WAL_ARCHIVE="/opt/archivedir" +DEFAULT_WAL_ARCHIVE="/opt/archivedir" RECOVERY_CONF="$ROOT_CONF/recovery.conf" POSTGRES="/usr/lib/postgresql/${POSTGRES_MAJOR_VERSION}/bin/postgres" INITDB="/usr/lib/postgresql/${POSTGRES_MAJOR_VERSION}/bin/initdb" @@ -113,6 +116,22 @@ if [ -z "${SSL_DIR}" ]; then SSL_DIR="/ssl_certificates" fi +if [ -z "${WAL_ARCHIVE}" ]; then + WAL_ARCHIVE=${DEFAULT_WAL_ARCHIVE} +fi + +if [ -z "${SCRIPTS_LOCKFILE_DIR}" ]; then + SCRIPTS_LOCKFILE_DIR=${DEFAULT_SCRIPTS_LOCKFILE_DIR} +fi + +if [ -z "${CONF_LOCKFILE_DIR}" ]; then + CONF_LOCKFILE_DIR=${DEFAULT_CONF_LOCKFILE_DIR} +fi + +if [ -z "${EXTRA_CONF_DIR}" ]; then + EXTRA_CONF_DIR=${DEFAULT_EXTRA_CONF_DIR} +fi + # SSL mode if [ -z "${PGSSLMODE}" ]; then PGSSLMODE=require @@ -371,9 +390,9 @@ function restart_postgres { # Useful for people who extends the image. function entry_point_script { - SETUP_LOCKFILE="/docker-entrypoint-initdb.d/.entry_point.lock" + SETUP_LOCKFILE="${SCRIPTS_LOCKFILE_DIR}/.entry_point.lock" # If lockfile doesn't exists, proceed. - if [[ ! -f "${SETUP_LOCKFILE}" ]] || [ "${IGNORE_INIT_HOOK_LOCKFILE}" == true ]; then + if [[ ! -f "${SETUP_LOCKFILE}" ]] || [ "${IGNORE_INIT_HOOK_LOCKFILE}" =~ [Tt][Rr][Uu][Ee] ]; then if find "/docker-entrypoint-initdb.d" -mindepth 1 -print -quit 2>/dev/null | grep -q .; then for f in /docker-entrypoint-initdb.d/*; do export PGPASSWORD=${POSTGRES_PASS} diff --git a/scripts/setup-conf.sh b/scripts/setup-conf.sh index 0b00e48..e552a34 100644 --- a/scripts/setup-conf.sh +++ b/scripts/setup-conf.sh @@ -2,8 +2,12 @@ source /scripts/env-data.sh -SETUP_LOCKFILE="${ROOT_CONF}/.postgresql.conf.lock" -create_dir /settings +create_dir ${EXTRA_CONF_DIR} +create_dir ${CONF_LOCKFILE_DIR} +create_dir ${SCRIPTS_LOCKFILE_DIR} + +SETUP_LOCKFILE="${CONF_LOCKFILE_DIR}/.postgresql.conf.lock" + if [ -f "${SETUP_LOCKFILE}" ]; then return 0 fi @@ -77,9 +81,9 @@ echo "include 'streaming_replication.conf'" >> $CONF fi if [[ ! -f ${ROOT_CONF}/extra.conf ]]; then - # If it doesn't exists, copy from /settings directory if exists - if [[ -f /settings/extra.conf ]]; then - cp -f /settings/extra.conf ${ROOT_CONF}/extra.conf + # If it doesn't exists, copy from ${EXTRA_CONF_DIR} directory if exists + if [[ -f ${EXTRA_CONF_DIR}/extra.conf ]]; then + cp -f ${EXTRA_CONF_DIR}/extra.conf ${ROOT_CONF}/extra.conf echo "include 'extra.conf'" >> $CONF else # default value diff --git a/scripts/setup-database.sh b/scripts/setup-database.sh index 79142a6..01aed39 100644 --- a/scripts/setup-database.sh +++ b/scripts/setup-database.sh @@ -92,7 +92,7 @@ echo "postgres ready" source /scripts/setup-user.sh # enable extensions in template1 if env variable set to true -if [[ "$(boolean ${POSTGRES_TEMPLATE_EXTENSIONS})" == TRUE ]] ; then +if [[ "$(boolean ${POSTGRES_TEMPLATE_EXTENSIONS})" =~ [Tt][Rr][Uu][Ee] ]] ; then for ext in $(echo ${POSTGRES_MULTIPLE_EXTENSIONS} | tr ',' ' '); do echo "Enabling \"${ext}\" in the database template1" su - postgres -c "psql -c 'CREATE EXTENSION IF NOT EXISTS \"${ext}\" cascade;' template1" @@ -110,11 +110,10 @@ for db in $(echo ${POSTGRES_DBNAME} | tr ',' ' '); do if [[ ${RESULT} -eq 0 ]]; then echo "Create db ${db}" su - postgres -c "createdb -O ${POSTGRES_USER} ${db}" + su - postgres -c "psql -c 'CREATE EXTENSION IF NOT EXISTS pg_cron cascade;' ${SINGLE_DB}" for ext in $(echo ${POSTGRES_MULTIPLE_EXTENSIONS} | tr ',' ' '); do echo "Enabling \"${ext}\" in the database ${db}" - if [[ ${ext} = 'pg_cron' ]]; then - echo " pg_cron doesn't need to be installed" - else + if [[ ${ext} != 'pg_cron' ]]; then su - postgres -c "psql -c 'CREATE EXTENSION IF NOT EXISTS \"${ext}\" cascade;' $db" fi done @@ -144,12 +143,5 @@ for db in $(echo ${POSTGRES_DBNAME} | tr ',' ' '); do done done - -CRON_LOCKFILE="${ROOT_CONF}/.cron_ext.lock" -if [ ! -f "${CRON_LOCKFILE}" ]; then - su - postgres -c "psql -c 'CREATE EXTENSION IF NOT EXISTS pg_cron cascade;' ${SINGLE_DB}" - touch ${CRON_LOCKFILE} -fi - # This should show up in docker logs afterwards su - postgres -c "psql -l 2>&1" diff --git a/scripts/setup-pg_hba.sh b/scripts/setup-pg_hba.sh index 71721c3..3a27d60 100644 --- a/scripts/setup-pg_hba.sh +++ b/scripts/setup-pg_hba.sh @@ -2,7 +2,7 @@ source /scripts/env-data.sh -SETUP_LOCKFILE="${ROOT_CONF}/.pg_hba.conf.lock" +SETUP_LOCKFILE="${CONF_LOCKFILE_DIR}/.pg_hba.conf.lock" if [ -f "${SETUP_LOCKFILE}" ]; then return 0 fi diff --git a/scripts/setup-ssl.sh b/scripts/setup-ssl.sh index 116132e..9735df8 100644 --- a/scripts/setup-ssl.sh +++ b/scripts/setup-ssl.sh @@ -2,7 +2,7 @@ source /scripts/env-data.sh -SETUP_LOCKFILE="${ROOT_CONF}/.ssl.conf.lock" +SETUP_LOCKFILE="${CONF_LOCKFILE_DIR}/.ssl.conf.lock" if [ -f "${SETUP_LOCKFILE}" ]; then return 0 fi