@@ -56,6 +56,9 @@ docker_create_db_directories() {
56
56
}
57
57
58
58
# initialize empty PGDATA directory with new database via 'initdb'
59
+ # arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function
60
+ # `initdb` automatically creates the "postgres", "template0", and "template1" dbnames
61
+ # this is also where the database user is created, specified by `POSTGRES_USER` env
59
62
docker_init_database_dir () {
60
63
# "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary
61
64
# 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() {
67
70
echo " postgres:x:$( id -g) :" > " $NSS_WRAPPER_GROUP "
68
71
fi
69
72
70
- file_env ' POSTGRES_INITDB_ARGS'
71
73
if [ " $POSTGRES_INITDB_WALDIR " ]; then
72
- export POSTGRES_INITDB_ARGS= " $POSTGRES_INITDB_ARGS --waldir $POSTGRES_INITDB_WALDIR "
74
+ set -- --waldir " $POSTGRES_INITDB_WALDIR " " $@ "
73
75
fi
74
76
75
- eval ' initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") ' " $POSTGRES_INITDB_ARGS "
77
+ eval ' initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") ' " $POSTGRES_INITDB_ARGS " ' "$@" '
76
78
77
79
# unset/cleanup "nss_wrapper" bits
78
80
if [ " ${LD_PRELOAD:- } " = ' /usr/lib/libnss_wrapper.so' ]; then
@@ -116,15 +118,16 @@ docker_verify_minimum_env() {
116
118
fi
117
119
}
118
120
119
- # run, source, or read files from /docker-entrypoint-initdb.d (or specified directory)
121
+ # usage: docker_process_init_files [file [file [...]]]
122
+ # ie: docker_process_init_files /always-initdb.d/*
123
+ # process initializer files, based on file extensions and permissions
120
124
docker_process_init_files () {
121
125
# psql here for backwards compatiblilty "${psql[@]}"
122
126
psql=( docker_process_sql )
123
127
124
- local initDir=" ${1:-/ docker-entrypoint-initdb.d} "
125
-
126
128
echo
127
- for f in " ${initDir%/ } " /* ; do
129
+ local f
130
+ for f; do
128
131
case " $f " in
129
132
* .sh)
130
133
# https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
@@ -145,7 +148,11 @@ docker_process_init_files() {
145
148
done
146
149
}
147
150
148
- # run `psql` with proper arguments for user and db
151
+ # Execute sql script, passed via stdin (or -f flag of pqsl)
152
+ # usage: docker_process_sql [psql-cli-args]
153
+ # ie: docker_process_sql --dbname=mydb <<<'INSERT ...'
154
+ # ie: docker_process_sql -f my-file.sql
155
+ # ie: docker_process_sql <my-file.sql
149
156
docker_process_sql () {
150
157
local query_runner=( psql -v ON_ERROR_STOP=1 --username " $POSTGRES_USER " --no-password )
151
158
if [ -n " $POSTGRES_DB " ]; then
@@ -155,8 +162,8 @@ docker_process_sql() {
155
162
" ${query_runner[@]} " " $@ "
156
163
}
157
164
158
- # create initial postgresql superuser with password and database
159
- # uses environment variables for input: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB
165
+ # create initial database
166
+ # uses environment variables for input: POSTGRES_DB
160
167
docker_setup_db () {
161
168
if [ " $POSTGRES_DB " != ' postgres' ]; then
162
169
POSTGRES_DB= docker_process_sql --dbname postgres --set db=" $POSTGRES_DB " << -'EOSQL '
@@ -166,12 +173,20 @@ docker_setup_db() {
166
173
fi
167
174
}
168
175
169
- # get user/pass and db from env vars or via file
176
+ # Loads various settings that are used elsewhere in the script
177
+ # This should be called before any other functions
170
178
docker_setup_env () {
171
179
file_env ' POSTGRES_PASSWORD'
172
180
173
181
file_env ' POSTGRES_USER' ' postgres'
174
182
file_env ' POSTGRES_DB' " $POSTGRES_USER "
183
+ file_env ' POSTGRES_INITDB_ARGS'
184
+
185
+ declare -g DATABASE_ALREADY_EXISTS
186
+ # look specifically for PG_VERSION, as it is expected in the DB dir
187
+ if [ -s " $PGDATA /PG_VERSION" ]; then
188
+ DATABASE_ALREADY_EXISTS=' true'
189
+ fi
175
190
}
176
191
177
192
# append md5 or trust auth to pg_hba.conf based on existence of POSTGRES_PASSWORD
@@ -189,10 +204,13 @@ pg_setup_hba_conf() {
189
204
} >> " $PGDATA /pg_hba.conf"
190
205
}
191
206
192
- # start socket-only postgresql server for setting up user or running scripts
207
+ # start socket-only postgresql server for setting up or running scripts
193
208
# all arguments will be passed along as arguments to `postgres` (via pg_ctl)
194
209
docker_temp_server_start () {
195
- # internal start of server in order to allow set-up using psql-client
210
+ if [ " $1 " = ' postgres' ]; then
211
+ shift
212
+ fi
213
+ # internal start of server in order to allow setup using psql client
196
214
# does not listen on external TCP/IP and waits until start finishes (can be overridden via args)
197
215
PGUSER=" ${PGUSER:- $POSTGRES_USER } " \
198
216
pg_ctl -D " $PGDATA " \
@@ -214,6 +232,7 @@ _main() {
214
232
215
233
216
234
if [ " $1 " = ' postgres' ]; then
235
+ docker_setup_env
217
236
# setup data directories and permissions (when run as root)
218
237
docker_create_db_directories
219
238
if [ " $( id -u) " = ' 0' ]; then
@@ -222,22 +241,18 @@ _main() {
222
241
fi
223
242
224
243
# only run initialization on an empty data directory
225
- # look specifically for PG_VERSION, as it is expected in the DB dir
226
- if [ ! -s " $PGDATA /PG_VERSION" ]; then
227
- docker_init_database_dir
228
-
229
- docker_setup_env
244
+ if [ -z " $DATABASE_ALREADY_EXISTS " ]; then
230
245
docker_verify_minimum_env
246
+ docker_init_database_dir
231
247
pg_setup_hba_conf
232
248
233
249
# PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless
234
250
# e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS
235
251
export PGPASSWORD=" ${PGPASSWORD:- $POSTGRES_PASSWORD } "
236
- docker_temp_server_start " ${ @: 2} "
252
+ docker_temp_server_start " $@ "
237
253
238
254
docker_setup_db
239
-
240
- docker_process_init_files
255
+ docker_process_init_files /docker-entrypoint-initdb.d/*
241
256
242
257
docker_temp_server_stop
243
258
unset PGPASSWORD
0 commit comments