Last active
May 5, 2020 12:30
-
-
Save BolaNasr/fec95e340087419a1dbb26bd4d178a55 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -Eeo pipefail | |
# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) | |
# 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 | |
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 | |
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" | |
# unset/cleanup "nss_wrapper" bits | |
if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then | |
rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" | |
unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP | |
fi | |
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment