postgresql: dockerfile create user and database from entrypoint script

Santhosh picture Santhosh · Mar 24, 2019 · Viewed 7.8k times · Source

I have a Dockerfile

COPY ./docker-entrypoint.sh /

RUN chmod +x /docker-entrypoint.sh

USER postgres

ENTRYPOINT ["/docker-entrypoint.sh"]

where docker-entrypoint.sh is:

#!/bin/sh

# Before PostgreSQL can function correctly, the database cluster must be initialized:
initdb -D /var/lib/postgres/data


#start postgres server
/usr/bin/postgres -D /var/lib/postgres/data &


# create a user or role
psql -d postgres -c "CREATE USER someuser WITH PASSWORD 'jkhkjah';" 

# create database 

psql -d postgres -c "CREATE DATABASE dockertest OWNER 'someuser';"

It does not create someuser and dockertest database. how to do this

Answer

Sergey Parfenov picture Sergey Parfenov · Mar 26, 2019

Look at the official docker postgresql image

It has such workflow:

  1. Execute docker-entrypoint.sh
  2. Start postgresql server

So you need to modify your Dockerfile like this:

COPY ./docker-entrypoint.sh /

RUN chmod +x /docker-entrypoint.sh

USER postgres

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 5432
CMD ["postgres"]

And then modify your docker-entrypoint.sh like this:

#!/bin/sh

# Before PostgreSQL can function correctly, the database cluster must be initialized:
initdb -D /var/lib/postgres/data

# 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
pg_ctl -D "/var/lib/postgres/data" -o "-c listen_addresses=''" -w start

# create a user or role
psql -d postgres -c "CREATE USER someuser WITH PASSWORD 'jkhkjah';" 

# create database 
psql -v ON_ERROR_STOP=1 -d postgres -c "CREATE DATABASE dockertest OWNER 'someuser';"

# stop internal postgres server
pg_ctl -v ON_ERROR_STOP=1 -D "/var/lib/postgres/data" -m fast -w stop

exec "$@"

I think your main mistake is starting postgresql in background

/usr/bin/postgres -D /var/lib/postgres/data &

and starting to execute queries immediately, before server has started.

Also i recommend to add -v ON_ERROR_STOP=1 parameters to psql, to see verbose information and stop process if error occurs