How to wait for postgres startup in ENTRYPOINT? How to wait for postgres startup in ENTRYPOINT? postgresql postgresql

How to wait for postgres startup in ENTRYPOINT?


Thanks to @zeppelin for suggesting pg_isready. I ended up using this:

#!/bin/bash# wait-for-postgres.shset -ecmd="$@"timer="5"until runuser -l postgres -c 'pg_isready' 2>/dev/null; do  >&2 echo "Postgres is unavailable - sleeping for $timer seconds"  sleep $timerdone>&2 echo "Postgres is up - executing command"exec $cmd

I'm using this in my ENTRYPOINT:

ENTRYPOINT \            # Start PostgreSQL            runuser -l postgres -c '/usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf & ' && \            # Exectute tests when db is up            ./wait-for-postgres.sh nosetests --verbose --cover-erase --with-coverage --cover-package=stalker


I will normally use a small "tcp-port-wait" script, like this:

#!/bin/bashset -e if [ -z "$1" -o -z "$2" ]then    echo "tcp-port-wait - block until specified TCP port becomes available"    echo "Usage: ntcp-port-wait HOST PORT"    exit 1fiecho Waiting for port $1:$2 to become available...while ! nc -z $1 $2 2>/dev/nulldo    let elapsed=elapsed+1    if [ "$elapsed" -gt 90 ]     then        echo "TIMED OUT !"        exit 1    fi      sleep 1;doneecho "READY !"

To wait until a certain service is up and ready.

In case of Postgresql, the default port it will listen on is 5432, so the command would be:

tcp-port-wait localhost 5432

That will block until Postgresql service is ready to serve connections, on :5432 on the loopback interface inside the container (when run in context of the ENTRYPOINT script).

You certainly have to copy this script into your container,by adding a line like that to your Dockerfile:

COPY tcp-port-wait /usr/local/bin/

before you can use it.

And also install the netcat utility.

You can use this for other types of services, like Tomcat or Mysql, too.

And, if you need, you can also wait "outside the container", like this:

docker exec my_container tcp-port-wait localhost 5432

Note, there are certainly other ways to do this, e.g. by using some orchestration tool, like docker-compose with healthcheck directive, or some process manager inside the container itself.