1

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.

  • Are you running in a Docker-compose environment? As in, do you run separate containers for django and celery? Could you share that config? – Nico Griffioen Sep 28 '21 at 14:12
  • I do it exactly as you mentioned ;) I have docker-compose with one CT for Django, one for celery_worker one for celery_beat but these are starting all from the same image so I simply need a function that checks if all migrations are done –  Sep 28 '21 at 14:14
  • Does anything bad happen if you unconditionally run migrations in your entrypoint wrapper script? – David Maze Sep 28 '21 at 14:56

2 Answers2

2

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.

Nico Griffioen
  • 5,143
  • 2
  • 27
  • 36
  • Mmm yes okay this might be a good Idea If you are only running on docker but I have to make sure that my container runs on all major platforms like K8s and OpenShift so this practice is not wrong but out of scope to me. Anyways, thanks –  Sep 28 '21 at 14:26
0

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.

SebFest
  • 1
  • 2