wait for db with docker and python

wait for db with docker and python

In this post we will see how to resolve classic problem to let python application wait to mysql docker container to be ready.

We have two ways to put the waiting process:

In python application

# assume 'db' is a peewee database object

def wait_for_db_connection(max_tries, sleep_duration_in_seconds):
    try_count = 0
    while True:
        try_count += 1
        try:
            db.connect()
            logger.info("database server connection try {0}: OK".format(try_count))
            return
        except Exception as error:
            if try_count < max_tries:
                logger.info("database server connection try {0}: FAILED".format(try_count))
                time.sleep(sleep_duration_in_seconds)
                pass
            else:
                logger.error("database server connection reached max tries. Unable to connect to DB")
                logger.exception(error)
                raise

Then call wait_for_db_connection(..)

In Dockerfile

COPY ./wait-for-db.sh /wait-for-db.sh
RUN chmod +x {{ compose_project_path }}/wait-for-db.sh
CMD [ "/wait-for-db.sh", "python", "app.py" ]

Where wait-for-db.sh (jinja2 like):

#!/bin/sh
# wait-for-db.sh

set -e

host="{{ database_host }}"
port={{ database_port }}

shift
cmd="$@"

until nc -z -v -w30 $host $port; do
  >&2 echo "Database server is unavailable - sleeping"
  sleep 2
done

>&2 echo "Database server is up - executing command"
exec $cmd
admin

Leave a Reply

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax