Почему мне не удается выполнить миграцию django с помощью команды "docker-compose run web"?
Поэтому я развертываю контейнеры django, postgress и nginx через docker-compose, и у меня есть проблема, которую я не могу понять.
Чтобы разрешить следующую ошибку в моем приложении Django, я знал, что мне просто нужно запустить миграцию Django.
[email protected] ERROR: relation "accounts_myprofile" does not exist
В попытке выполнить миграцию я попытался:
docker-compose run web python manage.py makemigrations
docker-compose run web python manage.py migrate
который возвратил следующее:
Migrations for 'accounts':
accounts/migrations/0001_initial.py:
- Create model Entry
- Create model MyProfile
Running migrations:
No migrations to apply.
Я смог успешно выполнить миграцию из контейнера Django, например:
docker exec -i -t 6dc97c6a305c /bin/bash
python manage.py makemigrations
python manage.py migrate
Хотя я решил проблему, я все еще не понимаю, почему запуск миграции через запуск docker-compose фактически не переносит ничего. Я надеюсь, что кто-то может, возможно, указать мне в правильном направлении.
Кроме того, я не знаю, связана ли эта проблема или нет, но когда я запускаю эти веб-команды для запуска профайлов, они, похоже, создают новые контейнеры, которые не будут закрыты, если я их не остановлю вручную, остановка докеры не удаляет их.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7bb3c7106d1 accounts_web "python manage.py che" 4 hours ago Restarting (0) 41 minutes ago 8000/tcp accounts_web_run_62
ee19ca6cdf49 accounts_web "python manage.py mig" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_60
2d87ee35de3a accounts_web "python manage.py mak" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_59
1c6143c13097 accounts_web "python manage.py mig" 4 hours ago Restarting (1) 44 minutes ago 8000/tcp accounts_web_run_58
6dc97c6a305c b1cb7debb103 "python manage.py run" 3 days ago Up 4 hours 8000/tcp accounts_web_1
Примечание. Стоп-стоп-стоп правильно остановит контейнер внизу (как и должно быть), но другой контейнер, созданный приложением для запуска веб-python manage.py, запускается с помощью docker-comp, должен быть остановлен вручную.
мой докер-сочинитель
web:
restart: always
build: ./web
expose:
- "8000"
links:
- postgres:postgres
volumes:
- /usr/src/app
- /usr/src/app/static
env_file: .env
environment:
DEBUG: 'true'
command: python manage.py runserver 0.0.0.0:8000
postgres:
restart: always
image: kartoza/postgis:9.4-2.1
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data/
Ответы
Ответ 1
Запуск docker-compose создает новые контейнеры
Вы уже заметили проблему. Когда вы используете docker-compose run
, создается новый контейнер.
Когда вы запустили первую команду (makemigrations), был создан новый контейнер, запущены makemigrations и файлы миграции были записаны в (новую) файловую систему контейнера.
Когда вы запустили вторую команду (migrate), был создан новый новый контейнер. Миграция продолжалась, но ей нечего было делать. Это потому, что файлы миграции недоступны - они были написаны в другом контейнере, чем этот новый.
Вы можете решить это несколькими способами.
Использование команды docker-compose
Во-первых, вы можете делать то, что уже делали, но вместо run
используйте docker-compose exec
.
docker-compose exec web python manage.py makemigrations
docker-compose exec web python manage.py migrate
exec
будет использовать уже запущенный контейнер, а не создавать новые контейнеры.
Использование сценария точки входа
Другим вариантом является использование сценария точки входа и запуск миграции там до запуска сервера. Это путь, если вы предпочитаете, чтобы все было более автоматическим.
Dockerfile:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
entrypoint.sh:
#!/bin/sh
python manage.py makemigrations
python manage.py migrate
exec "[email protected]"
docker-compose.yml (под "web"):
entrypoint: /entrypoint.sh
В этом случае, когда контейнер запускается, запускается сценарий точки входа, обрабатывает вашу миграцию, а затем runserver
command
(которая в этом случае является runserver
Django).
Новый контур контейнера навсегда
Как вы заметили, новые контейнеры остаются включенными. Это, как правило, неожиданно, потому что вы перегрузили команду тем, который должен выйти (а не оставаться в рабочем состоянии). Однако в docker-compose.yml вы указали restart: always
. Поэтому они будут запускать команды миграции снова и снова, перезагружая каждый раз, когда команда завершается.
Ответ 2
Дэн Лоу дал очень хороший ответ, но сценарий входа не работал для меня. Проблема в том, что некоторые "makemigrations" ожидают вашего ввода, например "да"/"нет".
Вы можете дополнить ответ дэна Лоу:
python manage.py makemigrations --noinput
вместо
python manage.py makemigrations
(Это работает по крайней мере для простых вопросов "да"/"нет")