web-dev-qa-db-fra.com

Comment effectuez-vous les migrations de la base de données Django avec Docker-Compose?

J'ai configuré une application Docker Django/PostgreSQL en suivant de près le Instructions de démarrage rapide de Django sur le site Docker .

La première fois que j'exécute manage.py migrate de Django à l'aide de la commande Sudo docker-compose run web python manage.py migrate, cela fonctionne comme prévu. La base de données est construite parfaitement dans le conteneur Docker PostgreSQL.

Les modifications apportées à l'application Django elle-même sont également reflétées dans le conteneur Docker Django, au moment où je les enregistre. C'est génial!

Mais si je modifie ensuite un modèle dans Django et que je tente de mettre à jour la base de données Postgres pour qu'elle corresponde au modèle, aucune modification n'est détectée. Par conséquent, aucune migration n'a lieu, peu importe le nombre de fois où j'ai exécuté makemigrations ou migrate. encore.

Fondamentalement, chaque fois que je modifie le modèle Django, je dois supprimer les conteneurs Docker (à l'aide de Sudo docker-compose rm) et recommencez avec une nouvelle migration.

J'essaie encore de comprendre Docker, et je ne comprends pas très bien comment cela fonctionne, mais celui-ci me rend dingue. Pourquoi ne pas migrer voir mes modifications? Qu'est-ce que je fais mal?

68
John

Vous devez simplement vous connecter à votre conteneur docker en cours d'exécution et exécuter vos commandes.

  1. Construisez votre pile: docker-compose build -f path/to/docker-compose.yml
  2. Lancez votre pile: docker-compose up -f path/to/docker-compose.yml
  3. Afficher le conteneur en cours d'exécution des conteneurs: docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
3fcc49196a84        ex_nginx          "nginx -g 'daemon off"   3 days ago          Up 32 seconds       0.0.0.0:80->80/tcp, 443/tcp   ex_nginx_1
66175bfd6ae6        ex_webapp         "/docker-entrypoint.s"   3 days ago          Up 32 seconds       0.0.0.0:32768->8000/tcp       ex_webapp_1
# postgres docker container ...
  1. Obtenez le CONTAINER ID de vous Django et connectez-vous à:
docker exec -t -i 66175bfd6ae6 bash
  1. Maintenant que vous êtes connecté, allez dans le bon dossier: cd path/to/Django_app

  2. Et maintenant, chaque fois que vous modifiez vos modèles, exécutez-les dans votre conteneur: python manage.py makemigrations et python manage.py migrate

Je vous recommande également d’utiliser un docker-entrypoint pour votre fichier conteneur docker Django) à exécuter automatiquement:

  • collecstatic
  • migrer
  • serveur d'exécution ou lancez-le avec gunicorn ou uWSGI

Voici un exemple (docker-entrypoint.sh):

#!/bin/bash

# Collect static files
echo "Collect static files"
python manage.py collectstatic --noinput

# Apply database migrations
echo "Apply database migrations"
python manage.py migrate

# Start server
echo "Starting server"
python manage.py runserver 0.0.0.0:8000
66
Louis Barranqueiro

J'utilise ces méthodes:

services:
  web:
    build: .
    image: uzman
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "3000:3000"
      - "8000:8000"
    volumes:
      - .:/code
    depends_on:
      - migration
      - db
  migration:
    image: uzman
    command: python manage.py migrate --noinput
    volumes:
      - .:/code
    depends_on:
      - db

En utilisant la hiérarchie docker que nous avons créée, la migration du service s’exécute après la configuration de la base de données et avant l’exécution du service principal. Désormais, lorsque vous exécuterez votre service, docker exécutera les migrations avant d'exécuter le serveur. Si le serveur migration est appliqué sur la même image que le serveur Web, cela signifie que toutes les migrations seront prises à partir de votre projet, évitant ainsi les problèmes.

Vous évitez de faire un point d'entrée ou quoi que ce soit d'autre avec ce moyen.

37
SalahAdDin

Faites fonctionner votre pile, puis lancez une commande d'exécution docker-compos one-shot. Par exemple

#assume Django in container named web
docker-compose run web python3 manage.py migrate

https://docs.docker.com/compose/reference/run/

22
Oliver Shaw

Vous pouvez utiliser docker exec commande

docker exec -it container_id python manage.py migrate
2
SuperNova

Je sais que c'est vieux et qu'il me manque peut-être quelque chose ici (si c'est le cas, veuillez m'éclairer!), Mais pourquoi ne pas ajouter simplement les commandes à votre start.sh script, exécuté par Docker pour lancer votre instance? Cela ne prendra que quelques secondes supplémentaires.

N.B. Je règle le Django_SETTINGS_MODULE variable pour vérifier que la base de données correcte est utilisée, car j’utilise différentes bases de données pour le développement et la production (bien que je sache que ce n’est pas une "pratique exemplaire").

Cela l'a résolu pour moi:

#!/bin/bash
# Migrate the database first
echo "Migrating the database before starting the server"
export Django_SETTINGS_MODULE="edatool.settings.production"
python manage.py makemigrations
python manage.py migrate
# Start Gunicorn processes
echo "Starting Gunicorn."
exec gunicorn edatool.wsgi:application \
    --bind 0.0.0.0:8000 \
    --workers 3
1
TBZ92