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


98

Docker Django / PostgreSQLアプリを次のように設定しました DockerサイトのDjangoクイックスタートの指示に

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

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

私は、Djangoの中にモデルを変更し、モデルに一致するようにPostgresデータベースを更新しようとすると何の移行は、私が実行回数に関係なく起こりませんので、しかし、何も変更が検出されないmakemigrationsか、migrateもう一度を。

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

私はまだDockerの周りに頭を抱えようとしています、そしてそれがどのように機能するかについて理解していない恐ろしいことがたくさんありますが、これは私を狂わせています。移行しても私の変更が表示されないのはなぜですか?何が悪いのですか?


理由がわかりましたか?私は以下の答えを得て動作します:You just have to log into your running docker container and run your commands.しかし、それがそのように動作する理由は何ですか?@LouisBarranqueiro
lukik

回答:


102

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

  1. スタックを構築します。 docker-compose build -f path/to/docker-compose.yml
  2. スタックを起動します。 docker-compose up -f path/to/docker-compose.yml
  3. コンテナを実行しているDockerを表示します。 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. djangoアプリのCONTAINER IDを取得してログインします。
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を使用することをお勧めします。

  • 集う
  • 移行する
  • 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

16
また、django Dockerコンテナーファイルのdocker-entrypointを使用して自動的に実行することもお勧めします。このような操作は自動的に実行されるべきではありません- 特に移行を意味します
オパール

7
どの環境でもかまいません。展開は常に同じように見える必要があります。移行が自動化されている場合、同時に実行される可能性があるため、お勧めしません。たとえばheroku-移行はデプロイの一部として実行されることはありません。
オパール

5
同意して?ここでは、開発環境にいます。私は走るmakemigrations。次回スタックを起動したときにmigrate、最後の移行が元に戻されてデータベースが更新されます。そうしないと、djangoアプリが正しく機能しません...現在のアプリで適切なデータベーススキーマを取得できるようにするためのdev env内のショートカット
ルイBarranqueiro

2
@LouisBarranqueiro、私は複数のインスタンス、単一のDBを意味しました。
オパール

1
ステップ4については、次のことをお勧めします。docker exec -ti $ CONTAINER_ID / bin / sh
SantiagoMagariños19年

52

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

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サーバが、それは問題を避け、すべての移行プロジェクトから取られることを意味していることと同じ画像の上に適用されます。

この方法では、エントリポイントなどの作成を避けます。


1
どのようにbuild: .して仕事image: 私は、移行が指定した名前の画像引くことができないというエラーが出る
アーロン・マクミラン

2
以前に実行されるため、build:オンにして解決しましたmigrationweb
アーロンマクミリン

4
これはuzmanイメージを実行し続け、RAMを永久に消費し続けませんか?また、uzmanイメージとは何ですか?
mlissner

これは私のカスタムDockerイメージです。RAMはまだテストしていません。
SalahAdDin

32

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

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

これは、組み込み(デフォルト)SQLiteデータベースだけでなく、依存関係としてリストされている外部のドッキングされたデータベースにも適しています。以下はdocker-compose.yamlファイルの例です。

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

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


12

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

docker exec -it container_id python manage.py migrate

1
これが答えになるはずです。
tolga

上記のcontainer_idを取得するには、docker psdjangoサーバーのCOMMAND列を探してください。
Jai Sharma

5

あなたの中にこのようなものがあれば docker-compose.yml

version: "3.7"

services:

  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    ports:
    - 8000:8000
    volumes:
        - ./:/usr/src/app
    depends_on:
      - db

  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: docker
      POSTGRES_PASSWORD: docker
      POSTGRES_DB: docker

次に、簡単に実行できます...

~$ docker-compose exec app python manage.py makemigrations
~$ docker-compose exec app python manage.py migrate

2

私はこれが古いことを知っており、おそらくここに何かが足りない(もしそうなら、私に啓発してください!) start.shインスタンスを起動するためにドッカーが運営するスクリプトを、?ほんの数秒かかります。

NB私は設定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

docker execを使用すると、次のエラーが発生しました。

AppRegistryNotReady("Models aren't loaded yet.")

だから私は代わりにこのコマンドを使いました:

docker-compose -f local.yml run django python manage.py makemigrations
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.