1
0
mirror of https://github.com/docker-library/postgres.git synced 2025-07-28 10:42:06 +03:00

Resync function interfaces with MySQL, improve comments

add `DATABASE_ALREADY_EXISTS` variable
This commit is contained in:
Joe Ferguson
2019-07-08 17:09:59 -07:00
parent 2e70e7103e
commit 6e85168bb0

View File

@ -56,6 +56,9 @@ docker_create_db_directories() {
} }
# initialize empty PGDATA directory with new database via 'initdb' # initialize empty PGDATA directory with new database via 'initdb'
# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function
# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames
# this is also where the database user is created, specified by `POSTGRES_USER` env
docker_init_database_dir() { docker_init_database_dir() {
# "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary # "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 # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html
@ -67,12 +70,11 @@ docker_init_database_dir() {
echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP"
fi fi
file_env 'POSTGRES_INITDB_ARGS'
if [ "$POSTGRES_INITDB_WALDIR" ]; then if [ "$POSTGRES_INITDB_WALDIR" ]; then
export POSTGRES_INITDB_ARGS="$POSTGRES_INITDB_ARGS --waldir $POSTGRES_INITDB_WALDIR" set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@"
fi fi
eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS" eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS"' "$@"'
# unset/cleanup "nss_wrapper" bits # unset/cleanup "nss_wrapper" bits
if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then
@ -116,15 +118,16 @@ docker_verify_minimum_env() {
fi fi
} }
# run, source, or read files from /docker-entrypoint-initdb.d (or specified directory) # usage: docker_process_init_files [file [file [...]]]
# ie: docker_process_init_files /always-initdb.d/*
# process initializer files, based on file extensions and permissions
docker_process_init_files() { docker_process_init_files() {
# psql here for backwards compatiblilty "${psql[@]}" # psql here for backwards compatiblilty "${psql[@]}"
psql=( docker_process_sql ) psql=( docker_process_sql )
local initDir="${1:-/docker-entrypoint-initdb.d}"
echo echo
for f in "${initDir%/}"/*; do local f
for f; do
case "$f" in case "$f" in
*.sh) *.sh)
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
@ -145,7 +148,11 @@ docker_process_init_files() {
done done
} }
# run `psql` with proper arguments for user and db # Execute sql script, passed via stdin (or -f flag of pqsl)
# usage: docker_process_sql [psql-cli-args]
# ie: docker_process_sql --dbname=mydb <<<'INSERT ...'
# ie: docker_process_sql -f my-file.sql
# ie: docker_process_sql <my-file.sql
docker_process_sql() { docker_process_sql() {
local query_runner=( psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --no-password ) local query_runner=( psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --no-password )
if [ -n "$POSTGRES_DB" ]; then if [ -n "$POSTGRES_DB" ]; then
@ -155,8 +162,8 @@ docker_process_sql() {
"${query_runner[@]}" "$@" "${query_runner[@]}" "$@"
} }
# create initial postgresql superuser with password and database # create initial database
# uses environment variables for input: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB # uses environment variables for input: POSTGRES_DB
docker_setup_db() { docker_setup_db() {
if [ "$POSTGRES_DB" != 'postgres' ]; then if [ "$POSTGRES_DB" != 'postgres' ]; then
POSTGRES_DB= docker_process_sql --dbname postgres --set db="$POSTGRES_DB" <<-'EOSQL' POSTGRES_DB= docker_process_sql --dbname postgres --set db="$POSTGRES_DB" <<-'EOSQL'
@ -166,12 +173,20 @@ docker_setup_db() {
fi fi
} }
# get user/pass and db from env vars or via file # Loads various settings that are used elsewhere in the script
# This should be called before any other functions
docker_setup_env() { docker_setup_env() {
file_env 'POSTGRES_PASSWORD' file_env 'POSTGRES_PASSWORD'
file_env 'POSTGRES_USER' 'postgres' file_env 'POSTGRES_USER' 'postgres'
file_env 'POSTGRES_DB' "$POSTGRES_USER" file_env 'POSTGRES_DB' "$POSTGRES_USER"
file_env 'POSTGRES_INITDB_ARGS'
declare -g DATABASE_ALREADY_EXISTS
# look specifically for PG_VERSION, as it is expected in the DB dir
if [ -s "$PGDATA/PG_VERSION" ]; then
DATABASE_ALREADY_EXISTS='true'
fi
} }
# append md5 or trust auth to pg_hba.conf based on existence of POSTGRES_PASSWORD # append md5 or trust auth to pg_hba.conf based on existence of POSTGRES_PASSWORD
@ -189,10 +204,13 @@ pg_setup_hba_conf() {
} >> "$PGDATA/pg_hba.conf" } >> "$PGDATA/pg_hba.conf"
} }
# start socket-only postgresql server for setting up user or running scripts # start socket-only postgresql server for setting up or running scripts
# all arguments will be passed along as arguments to `postgres` (via pg_ctl) # all arguments will be passed along as arguments to `postgres` (via pg_ctl)
docker_temp_server_start() { docker_temp_server_start() {
# internal start of server in order to allow set-up using psql-client if [ "$1" = 'postgres' ]; then
shift
fi
# internal start of server in order to allow setup using psql client
# does not listen on external TCP/IP and waits until start finishes (can be overridden via args) # does not listen on external TCP/IP and waits until start finishes (can be overridden via args)
PGUSER="${PGUSER:-$POSTGRES_USER}" \ PGUSER="${PGUSER:-$POSTGRES_USER}" \
pg_ctl -D "$PGDATA" \ pg_ctl -D "$PGDATA" \
@ -214,6 +232,7 @@ _main() {
if [ "$1" = 'postgres' ]; then if [ "$1" = 'postgres' ]; then
docker_setup_env
# setup data directories and permissions (when run as root) # setup data directories and permissions (when run as root)
docker_create_db_directories docker_create_db_directories
if [ "$(id -u)" = '0' ]; then if [ "$(id -u)" = '0' ]; then
@ -222,22 +241,18 @@ _main() {
fi fi
# only run initialization on an empty data directory # only run initialization on an empty data directory
# look specifically for PG_VERSION, as it is expected in the DB dir if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
if [ ! -s "$PGDATA/PG_VERSION" ]; then
docker_init_database_dir
docker_setup_env
docker_verify_minimum_env docker_verify_minimum_env
docker_init_database_dir
pg_setup_hba_conf pg_setup_hba_conf
# PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless
# e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS
export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}"
docker_temp_server_start "${@:2}" docker_temp_server_start "$@"
docker_setup_db docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
docker_process_init_files
docker_temp_server_stop docker_temp_server_stop
unset PGPASSWORD unset PGPASSWORD