Докеризованный контейнер django не создает локальный файл миграций
Вопрос
Я новичок в docker; это первый проект, который я создал с его помощью, и я не особенно понимаю, что я делаю. Я буду очень признателен, если кто-нибудь даст мне совет, как лучше всего получить миграции из докеризованного приложения django для хранения локально
Что я пробовал до сих пор
У меня есть локальный проект django со следующей структурой файлов:
.docker
-Dockerfile
project
-data
-models
- __init__.py
- user.py
- test.py
-migrations
- 0001_initial.py
- 0002_user_role.py
...
settings.py
...
manage.py
Makefile
docker-compose.yml
...
В текущем состоянии миграции для модели test.py не были запущены; поэтому я попытался сделать это с помощью docker-compose exec main python manage.py makemigrations
. Это сработало успешно, вернув следующее:
Migrations for 'data':
project/data/migrations/0003_test.py
- Create model Test
Но локального файла нет. Однако, если я исследую файловую систему контейнера, я вижу, что файл существует в самом контейнере.
После выполнения следующего:
docker-compose exec main python manage.py migrate
Я получаю:
Running migrations:
No migrations to apply.
Your models in app(s): 'data' have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
У меня сложилось впечатление, что даже если это не создаст локальный файл, то, по крайней мере, запустит миграции на контейнере.
В любом случае, я хотел, чтобы при запуске docker-compose exec main python manage.py makemigrations
файл сохранялся локально в папке project/data/migrations
, а затем я просто запускал migrate
вручную. Я не могу найти много документации о том, как это сделать; единственный пост, который я видел, предлагал bind mounts (Migrations files not created in dockerized Django), что я и попытался сделать, добавив следующее в мой docker-compose
файл:
volumes:
- type: bind
source: ./data/migrations
target: /var/lib/migrations_test
но мне с трудом удавалось заставить его работать, и после этого я понятия не имел, как запускать команды через этот том с помощью docker-compose, и я сомневался, хорошая ли это идея, поскольку где-то читал, что использование bind mounts не является лучшей практикой
Настройка проекта:
Файл docker-compose.yml
выглядит следующим образом:
version: '3.7'
x-common-variables: &common-variables
ENV: 'DEV'
DJANGO_SETTINGS_MODULE: 'project.settings'
DATABASE_NAME: 'postgres'
DATABASE_USER: 'postgres'
DATABASE_PASSWORD: 'postgres'
DATABASE_HOST: 'postgres'
CELERY_BROKER_URLS: 'redis://redis:6379/0'
volumes:
postgres:
services:
main:
command:
python manage.py runserver 0.0.0.0:8000
build:
context: ./
dockerfile: .docker/Dockerfile
target: main
environment:
<<: *common-variables
ports:
- '8000:8000'
env_file:
- dev.env
networks:
- default
postgres:
image: postgres:13.6
volumes:
- postgres:/var/lib/postgresql/data
ports:
- '25432:5432'
environment:
POSTGRES_PASSWORD: 'postgres'
command: postgres -c log_min_messages=INFO -c log_statement=all
wait_for_dependencies:
image: dadarek/wait-for-dependencies
environment:
SLEEP_LENGTH: '0.5'
redis:
image: redis:latest
ports:
- '16379:6379'
worker:
build:
context: .
dockerfile: .docker/Dockerfile
target: main
command: celery -A project worker -l INFO
environment:
<<: *common-variables
volumes:
- .:/code/delegated
env_file:
- dev.env
networks:
- default
beat:
build:
context: .
dockerfile: .docker/Dockerfile
target: main
command: celery -A project beat -l INFO
environment:
<<: *common-variables
volumes:
- .:/code/delegated
env_file:
- dev.env
networks:
- default
networks:
default:
Makefile:
build: pre-run
build:
docker-compose build --pull
dev-deps: pre-run
dev-deps:
docker-compose up -d postgres redis
docker-compose run --rm wait_for_dependencies postgres:5432 redis:6379
migrate: pre-run
migrate:
docker-compose run --rm main python manage.py migrate
setup: build dev-deps migrate
up: dev-deps
docker-compose up -d main
Dockerfile:
FROM python:3.10.2 as main
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
RUN mkdir -p /code
WORKDIR /code
ADD . ./
RUN useradd -m -s /bin/bash app
RUN chown -R app:app .
USER app
EXPOSE 8000
Мне удалось исправить это, добавив следующее к моему "главному" сервису в моем docker compose:
volumes:
- .:/code:delegated