3

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

Santhosh
  • 9,965
  • 20
  • 103
  • 243
  • Can you provide thee entire Dockerfile (or at least the base image) ? How does it not work, is their an error during start-up or in db logs? Or it simply does nothing and the image works otherwise? – Pierre B. Mar 24 '19 at 20:37
  • The image works. If also tried to start postgres in background, but postgresql takes time to start. So how can on run `create user` and `create database` only after postgresql is started – Santhosh Mar 25 '19 at 18:38

1 Answers1

6

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

  • 1
    Why do we start and also stop the server at the same time. – Santhosh Mar 26 '19 at 20:38
  • I need postgres running because my django cotainer needs access when i am using docker compose – Santhosh Mar 26 '19 at 20:47
  • first start is only "technical start" to prepare database to necessary state, at this time your database is not ready to accept connections because it's schema is not correct yet. and second is "production" start, when schema is prepared, and we are ready to accept connections – Sergey Parfenov Mar 27 '19 at 03:42