user16837137
user16837137

Reputation:

Docker/Django - How to make sure that all migrations are completed bofor application start?

at my dockerized Django application I have the following bash function at my docker-entrypoint.sh. This basically only checks if the database is available:

function check_mariadb {
  while ! mysqladmin --user=$MYSQL_USER --password=$MYSQL_PASSWORD --host $MYSQL_HOST ping --silent &> /dev/null; do
    echo "Waiting for MariaDB service to become available"
    sleep 3
    done
    echo "MariaDB is up and available"
}

As my application can start in 3 modes (as application, Celery_worker or Celery_beat) I somehow have to make sure that all migration are done before celery starts. Otherwise I'm running into issues that celery is missing one of these tables:

django_celery_results_chordcounter
django_celery_results_groupresult
django_celery_results_taskresult

Can somebody give me a hint what might be the best practices to check for open migration in this context? And only let celery start if all migrations are done?!... Would be awesome if this could also be handled in a simple bash function like the one above.

Would be awesome If I could do more than just:

python manage.py showmigrations | grep '\[ \]'

Thanks in advance.

Upvotes: 1

Views: 1549

Answers (2)

SebFest
SebFest

Reputation: 1

There is a debian package called wait-for-it that this related thread discusses :

How to use wait-for-it in docker-compose file?

For example, I have set up a short celery.sh script file that I set as entrypoint for my beat and worker celery service in my compose file:

#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

wait-for-it web:8000

exec "$@"

Where "web" is the host name of my django service and 8000 the host port for the web service.

Upvotes: 0

Nico Griffioen
Nico Griffioen

Reputation: 5405

In your docker-compose.yaml, you can add a healthcheck to the Django container:

healthcheck:
  test: ["CMD", "curl --fail http://localhost:8000/ || exit 1"]
  interval: 10s
  timeout: 5s
  retries: 5

Then you can add depends_on to your celery/celerybeat container:

depends_on:
  django:
    condition: service_healthy

This will start the celery container only after the django healthcheck passes. In the healthcheck we simply poll localhost:8000, because when the server's returning responses, we can be sure the migrations have been applied.

Upvotes: 1

Related Questions