postgresqldocker

How to block until initdb has finished running in a Docker Postgres container?


I'd like to use Docker to load a .sql file into a PostgreSQL database and serve it.

The following command returns quickly (before the database has been fully populated - which appears to happen asynchronously in the background).

docker run \
    --name myContainer \
    -p 5432:5432 \
    -v mySqlFile.sql:/docker-entrypoint-initdb.d/dump.sql \
    -d postgres:alpine

Since this command will be part of a script, I'd like the command to block until the database has fully initialised with mySqlFile.sql

How would I go about getting the command to block, or some other means of pausing while mySqlFile.sql is loaded?

For clarity: I run the above command, and then the following command:

echo "select count(*) as \"Posts imported\" from posts;" | docker exec -i myContainer psql -U postgres
 Posts imported
----------------
              0
(1 row)

Waiting a few seconds, and I get this:

echo "select count(*) as \"Posts imported\" from posts;" | docker exec -i myContainer psql -U postgres
 Posts imported
----------------
          51103
(1 row)

This is a problem, because I am looking to build an automated solution. I want the docker run command to block until all records have been imported into Postgres. Then I have the database in a state which is ready for the next command.


Solution

  • I have found a solution. I think you can use this way.

    When you run your postgres image, ENTRYPOINT is a shell.

    In that time if you run ps aux, you will see that PID 1 is bash.

    But when all initialization is completed, postgres becomes the main process for exec "$@". That time PID 1 is postgres.

    You can use this hack. You don't know when your initialization will be completed. But you are sure that, when your initialization is completed, your PID 1 will be postgres.

    $ docker exec -i myContainer ps -p 1 -o comm=
    

    This will return bash when initialization is running. And will be changed to postgres when everything is done.

    Of course, you need loop. But in this way you will be sure when initialization is totally completed without any guess.

    UPDATE

    As you are using alpine image, it has cut version of ps. You need to install uncut ps in your alpine image. (stack overflow question)

    Run following command first.

    $ docker exec -i myContainer apk add --no-cache procps
    

    Now ps -p 1 -o comm= will work

    Hope this will help