web-dev-qa-db-ja.com

Docker-Composeを使用する場合、Djangoデータベースの移行をどのように実行しますか?

DockerサイトのDjangoクイックスタート手順 に厳密に従ってDocker Django/PostgreSQLアプリをセットアップしました。

Sudo docker-compose run web python manage.py migrateコマンドを使用してDjangoのmanage.py migrateを初めて実行すると、期待どおりに動作します。データベースはDocker PostgreSQLコンテナー内に正常に構築されます。

Djangoアプリ自体に加えられた変更は、保存した時点でDocker Djangoコンテナーにも同様に反映されます。それは素晴らしい!

しかし、その後Djangoでモデルを変更し、モデルに一致するようにPostgresデータベースを更新しようとすると、変更が検出されないため、makemigrationsまたはmigrateを何度実行しても移行は発生しません。

基本的に、Djangoモデルを変更するたびに、Dockerコンテナを(Sudo docker-compose rmを使用して)削除し、新しい移行で新たに開始する必要があります。

私はまだDockerに頭を悩ませようとしています。そして、それがどのように機能するかについて、私は非常に多くのことを理解していませんが、これは私を夢中にさせています。移行したときに変更が表示されないのはなぜですか?私は何が間違っていますか?

68
John

実行中のdockerコンテナーにログインし、コマンドを実行するだけです。

  1. スタックを構築します:docker-compose build -f path/to/docker-compose.yml
  2. スタックを起動します:docker-compose up -f path/to/docker-compose.yml
  3. コンテナーを実行しているドッカーを表示: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. CONTAINER IDのDjangoアプリを取得してログインします。
docker exec -t -i 66175bfd6ae6 bash
  1. ログインしたら、正しいフォルダーに移動します:cd path/to/Django_app

  2. そして今、モデルを編集するたびに、コンテナで実行します:python manage.py makemigrationsおよびpython manage.py migrate

また、Django dockerコンテナファイルを自動的に実行するにはdocker-entrypointを使用することをお勧めします。

  • collecstatic
  • 移行
  • runserverまたはgunicornまたはuWSGIで起動します

次に例を示します(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

私はこれらの方法を使用します:

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

作成したdocker階層を使用して、データベースのセットアップ後、メインサービスの実行前にサービスの移行を実行します。これで、サービスを実行すると、dockerはサーバーを実行する前に移行を実行します。 migrationサーバーがWebサーバーと同じイメージに適用されていることを確認してください。これは、すべての移行がプロジェクトから取得され、問題を回避することを意味します。

この方法で、エントリポイントやその他のものを作成しないようにします。

37
SalahAdDin

スタックを実行してから、一発のdocker-compose runコマンドを実行します。例えば

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

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

22
Oliver Shaw

docker execコマンドを使用できます

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

私はこれが古いことを知っており、おそらくここに何かが足りないかもしれません(もしそうなら、私に教えてください!)、なぜあなたのインスタンスを起動するためにDockerによって実行されるstart.shスクリプトにコマンドを追加しないのですか?ほんの数秒余分にかかります。

N.B。Django_SETTINGS_MODULE変数を設定して、正しいデータベースが使用されるようにします。これは、開発と実稼働で異なるデータベースを使用しているためです(ただし、これは「ベストプラクティス」ではありません)。

これは私のためにそれを解決しました:

#!/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