Skip to content

Manual merge with upstream as of 2017-07-25 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 86 additions & 51 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,58 +1,79 @@
#!/bin/bash
#!/usr/bin/env bash
set -e

# Backwards compatibility for old variable names (deprecated)
if [ "x$PGUSER" != "x" ]; then
POSTGRES_USER=$PGUSER
fi
if [ "x$PGPASSWORD" != "x" ]; then
POSTGRES_PASSWORD=$PGPASSWORD
fi
# 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"
}

# Forwards-compatibility for old variable names (pg_basebackup uses them)
if [ "x$PGPASSWORD" = "x" ]; then
export PGPASSWORD=$POSTGRES_PASSWORD
if [ "${1:0:1}" = '-' ]; then
set -- postgres "$@"
fi

# Based on official postgres package's entrypoint script (https://hub.docker.com/_/postgres/)
# Modified to be able to set up a slave. The docker-entrypoint-initdb.d hook provided is inadequate.
# 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"

set -e
mkdir -p /var/run/postgresql
chown -R postgres /var/run/postgresql
chmod 775 /var/run/postgresql

if [ "${1:0:1}" = '-' ]; then
set -- postgres "$@"
# Create the transaction log directory before initdb is run (below) so the directory is owned by the correct user
if [ "$POSTGRES_INITDB_XLOGDIR" ]; then
mkdir -p "$POSTGRES_INITDB_XLOGDIR"
chown -R postgres "$POSTGRES_INITDB_XLOGDIR"
chmod 700 "$POSTGRES_INITDB_XLOGDIR"
fi

exec gosu postgres "$BASH_SOURCE" "$@"
fi

if [ "$1" = 'postgres' ]; then
mkdir -p "$PGDATA"
chmod 700 "$PGDATA"
chown -R postgres "$PGDATA"

mkdir -p /run/postgresql
chmod g+s /run/postgresql
chown -R postgres /run/postgresql
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
if [ "x$REPLICATE_FROM" == "x" ]; then
eval "gosu postgres initdb $POSTGRES_INITDB_ARGS"
else
until ping -c 1 -W 1 ${REPLICATE_FROM}
do
echo "Waiting for master to ping..."
sleep 1s
done
until gosu postgres pg_basebackup -h ${REPLICATE_FROM} -D ${PGDATA} -U ${POSTGRES_USER} -vP -w
do
echo "Waiting for master to connect..."
sleep 1s
done
file_env 'POSTGRES_INITDB_ARGS'
if [ "$POSTGRES_INITDB_XLOGDIR" ]; then
export POSTGRES_INITDB_ARGS="$POSTGRES_INITDB_ARGS --xlogdir $POSTGRES_INITDB_XLOGDIR"
fi

if [ "x$REPLICATE_FROM" == "x" ]; then
eval "initdb --username=postgres $POSTGRES_INITDB_ARGS"
fi

# check password first so we can output the warning before postgres
# messes it up
file_env 'POSTGRES_PASSWORD'
if [ "$POSTGRES_PASSWORD" ]; then
pass="PASSWORD '$POSTGRES_PASSWORD'"
authMethod=md5

# Forwards-compatibility for old variable names (pg_basebackup uses them)
if [ "x$PGPASSWORD" = "x" ]; then
export PGPASSWORD=$POSTGRES_PASSWORD
fi
else
# The - option suppresses leading tabs but *not* spaces. :)
cat >&2 <<-'EOWARN'
Expand All @@ -73,20 +94,35 @@ if [ "$1" = 'postgres' ]; then
authMethod=trust
fi

if [ "x$REPLICATE_FROM" == "x" ]; then
if [ "x$REPLICATE_FROM" == "x" ]; then
true # Do nothing
else
until ping -c 1 -W 1 ${REPLICATE_FROM}
do
echo "Waiting for master to ping..."
sleep 1s
done
until pg_basebackup -h ${REPLICATE_FROM} -D ${PGDATA} -U ${POSTGRES_USER} -vP -w
do
echo "Waiting for master to connect..."
sleep 1s
done
fi

if [ "x$REPLICATE_FROM" == "x" ]; then

{ echo; echo "host replication all 0.0.0.0/0 $authMethod"; } | gosu postgres tee -a "$PGDATA/pg_hba.conf" > /dev/null
{ echo; echo "host all all 0.0.0.0/0 $authMethod"; } | gosu postgres tee -a "$PGDATA/pg_hba.conf" > /dev/null
{ echo; echo "host replication all 0.0.0.0/0 $authMethod"; } >> "$PGDATA/pg_hba.conf"
{ echo; echo "host all all 0.0.0.0/0 $authMethod"; } >> "$PGDATA/pg_hba.conf"

# internal start of server in order to allow set-up using psql-client
# 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
gosu postgres pg_ctl -D "$PGDATA" \
PGUSER="${PGUSER:-postgres}" \
pg_ctl -D "$PGDATA" \
-o "-c listen_addresses='localhost'" \
-w start

: ${POSTGRES_USER:=postgres}
: ${POSTGRES_DB:=$POSTGRES_USER}
export POSTGRES_USER POSTGRES_DB
file_env 'POSTGRES_USER' 'postgres'
file_env 'POSTGRES_DB' "$POSTGRES_USER"

psql=( psql -v ON_ERROR_STOP=1 )

Expand All @@ -106,32 +142,31 @@ if [ "$1" = 'postgres' ]; then
$op USER "$POSTGRES_USER" WITH SUPERUSER $pass ;
EOSQL
echo
fi

fi

psql+=( --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" )

echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${psql[@]}" < "$f"; echo ;;
*.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

if [ "x$REPLICATE_FROM" == "x" ]; then
gosu postgres pg_ctl -D "$PGDATA" -m fast -w stop
fi
if [ "x$REPLICATE_FROM" == "x" ]; then
PGUSER="${PGUSER:-postgres}" \
pg_ctl -D "$PGDATA" -m fast -w stop
fi

echo
echo 'PostgreSQL init process complete; ready for start up.'
echo
fi

exec gosu postgres "$@"
fi

exec "$@"