When using multiple containers approach with Docker Compose, we often get race condition issues, where the application server depends on the database, but the first one ends up running too early and may break the stack. Here, we’re gonna see a Python way to solve this problem.
Django + Postgres, a race condition example
One of the most used stacks in the Python community is the Django web framework with Postgres database. Making the use of Docker Compose, it’s easy to create both in separate containers, like this:
Here, we’ve created two services with basic configuration, exposing the right ports and mouting our local project directory on /code inside the Django container. To build the Django container, I used the following Dockerfile:
Python Script to the rescue
Now, the tricky part. When we run docker-compuse up to start our containers, possbily the web container will come up before the db. Django will try to execute its migrations and fail with a database connection error. To avoid that, we’ll use the check_db.py script, listed as first command to be executed on the web service. It will test the database port and exits when it is open. Here’s the little guy:
Now when you run docker-compose up, the script’s output should appear on the logs:
The first and sixth lines show our script in action, holding the container until the database is up and running.
Wrapping up
If your container have Python 3, you can easily use the same script. If not, it shouldn’t be hard to code the same logic on your prefered language, just create an infinite loop to check the port and break it when your service is up.