#!/bin/bash set -e # 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 if [ "$1" = 'postgres' ]; then chown -R postgres:postgres $PGDATA echo here1 # look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s "$PGDATA/PG_VERSION" ]; then file_env 'POSTGRES_INITDB_ARGS' if [ "$POSTGRES_INITDB_XLOGDIR" ]; then export POSTGRES_INITDB_ARGS="$POSTGRES_INITDB_ARGS --xlogdir $POSTGRES_INITDB_XLOGDIR" fi echo hehe2 su - $1 -c "initdb -D $PGDATA -U postgres -E UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8 $POSTGRES_INITDB_ARGS" echo hehe3 # 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 else # The - option suppresses leading tabs but *not* spaces. :) cat >&2 <<-EOF **************************************************** 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". **************************************************** EOF pass= authMethod=trust fi { echo echo "host all all all $authMethod" } >> "$PGDATA/pg_hba.conf" su postgres echo `whoami` # 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 su - $1 -c "pg_ctl -D \"$PGDATA\" -o \"-c listen_addresses='localhost'\" -w start" file_env 'POSTGRES_USER' 'postgres' file_env 'POSTGRES_DB' "$POSTGRES_USER" psql=( psql -v ON_ERROR_STOP=1 ) if [ "$POSTGRES_DB" != 'postgres' ]; then "${psql[@]}" --username postgres <<-EOSQL CREATE DATABASE "$POSTGRES_DB" ; EOSQL echo fi if [ "$POSTGRES_USER" = 'postgres' ]; then op='ALTER' else op='CREATE' fi "${psql[@]}" --username postgres <<-EOSQL $op USER "$POSTGRES_USER" WITH SUPERUSER $pass ; EOSQL echo 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 "$f"; echo ;; *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;; *) echo "$0: ignoring $f" ;; esac echo done PGUSER="${PGUSER:-postgres}" \ su - $1 -c "pg_ctl -D \"$PGDATA\" -m fast -w stop" echo echo 'PostgreSQL init process complete; ready for start up.' echo fi fi exec su - $1 -c "$@ -D $PGDATA"