Files
dockerfiles/postgres/bootstrap.sh
Qi Zheng 3259d3bab3 Use su-exec to run commands on entryponit
With su-exec, make sure the SIGTERM upon docker stop
could be received by the running program thus causing
a clean stop/exit.

Signed-off-by: Qi Zheng <qi.zheng@intel.com>
2019-07-23 15:47:45 -07:00

164 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Taken from https://github.com/docker-library/postgres/blob/master/11/docker-entrypoint.sh
# with minor modifications to run on Clear Linux
set -Eeo pipefail
# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables)
source /usr/share/defaults/etc/bash.bashrc
# 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
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
if [ "${1:0:1}" = '-' ]; then
set -- postgres "$@"
fi
# allow the container to be started with `--user`
if [ "$1" = 'postgres' ] && [ "$(id -u)" = '0' ]; then
mkdir -p "$PGDATA"
chown -R postgres "$PGDATA"
chmod 700 "$PGDATA"
mkdir -p /var/run/postgresql
chown -R postgres /var/run/postgresql
chmod 775 /var/run/postgresql
# Create the transaction log directory before initdb is run (below) so the directory is owned by the correct user
if [ "$POSTGRES_INITDB_WALDIR" ]; then
mkdir -p "$POSTGRES_INITDB_WALDIR"
chown -R postgres "$POSTGRES_INITDB_WALDIR"
chmod 700 "$POSTGRES_INITDB_WALDIR"
fi
sed -i "s|#listen_addresses.*|listen_addresses = '*'|" /usr/share/postgresql/postgresql.conf.sample
exec su-exec postgres "$BASH_SOURCE" "$@"
fi
if [ "$1" = 'postgres' ]; then
mkdir -p "$PGDATA"
chown -R "$(id -u)" "$PGDATA" 2>/dev/null || :
chmod 700 "$PGDATA" 2>/dev/null || :
# look specifically for PG_VERSION, as it is expected in the DB dir
if [ ! -s "$PGDATA/PG_VERSION" ]; then
# "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary
# see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html
file_env 'POSTGRES_USER' 'postgres'
file_env 'POSTGRES_PASSWORD'
file_env 'POSTGRES_INITDB_ARGS'
if [ "$POSTGRES_INITDB_WALDIR" ]; then
export POSTGRES_INITDB_ARGS="$POSTGRES_INITDB_ARGS --waldir $POSTGRES_INITDB_WALDIR"
fi
eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS"
# check password first so we can output the warning before postgres
# messes it up
if [ -n "$POSTGRES_PASSWORD" ]; then
authMethod=md5
if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then
cat >&2 <<-'EOWARN'
WARNING: The supplied POSTGRES_PASSWORD is 100+ characters.
This will not work if used via PGPASSWORD with "psql".
https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412)
https://github.com/docker-library/postgres/issues/507
EOWARN
fi
else
# The - option suppresses leading tabs but *not* spaces. :)
cat >&2 <<-'EOWARN'
****************************************************
WARNING: No password has been set for the database.
This will allow anyone with access to the
Postgres port to access your database. In
Docker's default configuration, this is
effectively any other container on the same
system.
Use "-e POSTGRES_PASSWORD=password" to set
it in "docker run".
****************************************************
EOWARN
authMethod=trust
fi
{
echo
echo "host all all all $authMethod"
} >> "$PGDATA/pg_hba.conf"
# internal start of server in order to allow set-up using psql-client
# does not listen on external TCP/IP and waits until start finishes
PGUSER="${PGUSER:-$POSTGRES_USER}" \
pg_ctl -D "$PGDATA" \
-o "-c listen_addresses=''" \
-w start
file_env 'POSTGRES_DB' "$POSTGRES_USER"
export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"
psql=( psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --no-password )
if [ "$POSTGRES_DB" != 'postgres' ]; then
"${psql[@]}" --dbname postgres --set db="$POSTGRES_DB" <<-'EOSQL'
CREATE DATABASE :"db" ;
EOSQL
echo
fi
psql+=( --dbname "$POSTGRES_DB" )
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh)
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
# https://github.com/docker-library/postgres/pull/452
if [ -x "$f" ]; then
echo "$0: running $f"
"$f"
else
echo "$0: sourcing $f"
. "$f"
fi
;;
*.sql) echo "$0: running $f"; "${psql[@]}" -f "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
PGUSER="${PGUSER:-$POSTGRES_USER}" \
pg_ctl -D "$PGDATA" -m fast -w stop
unset PGPASSWORD
echo
echo 'PostgreSQL init process complete; ready for start up.'
echo
fi
fi
exec "$@"