Docker-Compose를 사용할 때 Django 데이터베이스 마이그레이션을 어떻게 수행합니까?


99

Docker 사이트Django Quick Start 지침에 따라 Docker Django / PostgreSQL 앱을 설정했습니다 .

Django의 manage.py migrate를 처음 실행할 때 다음 명령을 사용합니다. sudo docker-compose run web python manage.py migrate 하면 예상대로 작동합니다. 데이터베이스는 Docker PostgreSQL 컨테이너 내부에 구축됩니다.

Django 앱 자체에 대한 변경 사항은 저장하는 순간 Docker Django 컨테이너에도 반영됩니다. 대단해!

그러나 Django에서 모델을 변경하고 모델과 일치하도록 Postgres 데이터베이스를 업데이트하려고하면 변경 사항이 감지되지 않으므로 몇 번 makemigrations이나 실행해도 마이그레이션이 발생하지 않습니다.migrate 다시 .

기본적으로 Django 모델을 변경할 때마다 Docker 컨테이너를 삭제해야합니다. sudo docker-compose rm ) 새 마이그레이션으로 새로 시작해야합니다.

나는 여전히 Docker에 대해 머리를 돌리려고 노력하고 있으며 작동 방식에 대해 이해하지 못하는 끔찍한 것이 있지만 이것은 나를 미치게합니다. 마이그레이션에 내 변경 사항이 표시되지 않는 이유는 무엇입니까? 내가 뭘 잘못하고 있죠?


이유를 알아 내 셨나요? 나는 아래의 대답을 얻고 작동합니다. You just have to log into your running docker container and run your commands.그러나 그것이 그렇게 행동하는 이유는 무엇입니까? @LouisBarranqueiro
lukik

답변:


104

실행중인 도커 컨테이너에 로그인하고 명령을 실행하기 만하면됩니다.

  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. 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를 사용하는 것이 좋습니다. 이러한 작업은 자동으로 실행되지 않아야합니다 . 특히 마이그레이션을 의미 합니다.
Opal 2015

7
어떤 환경에 있는지는 중요하지 않습니다. 배포는 항상 동일해야합니다. 마이그레이션이 자동화 된 경우 동시에 실행될 수 있으므로 권장하지 않습니다. 예 : heroku에서 마이그레이션은 배포의 일부로 실행되지 않습니다.
Opal 2015

5
동시에? 여기 우리는 개발 환경에 있습니다. 나는 달린다 makemigrations. 다음 번에 내가 스택을 실행할 것을 migrate... 그렇지 않으면 장고 응용 프로그램은 제대로 작동하지 않습니다, 취소 마지막 마이그레이션과 데이터베이스를 업데이트합니다 그것은 단지 바로 가기에서 dev에 ENV 당신이 현재 앱 올바른 데이터베이스 스키마를 가지고 할 수
Louis Barranqueiro

2
@LouisBarranqueiro, 여러 인스턴스, 단일 DB를 의미했습니다.
Opal 2015

1
4 단계의 경우 다음을 권장합니다. docker exec -ti $ CONTAINER_ID / bin / sh
Santiago Magariños

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 서버가 웹 서버가이 문제를 방지, 모든 마이그레이션 프로젝트에서 수행된다는 것을 의미하는 것과 같은 이미지 위에 적용된다.

이 방법으로 진입 점을 만들거나 다른 것을 피할 수 있습니다.


2
않는 방법 build: .으로 작업 image: 내가 마이그레이션이 명명 된 이미지를 당겨 수없는 오류
아론 McMillin

2
내가 넣어 그것을 해결 build:migration전에 실행하기 때문에web
아론 McMillin

4
이것은 uzman 이미지를 계속 실행하고 RAM을 영원히 소비하지 않습니까? 또한, 무엇 이다 uzman 이미지는?
mlissner

내 커스텀 도커 이미지인데 아직 RAM을 테스트하지 않았습니다.
SalahAdDin

32

스택을 실행 한 다음 원샷 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인스턴스를 실행하기 위해 Docker에서 실행 하는 명령을 스크립트에 추가하는 것은 어떻습니까? 몇 초 밖에 걸리지 않습니다.

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.