Докер Составьте ENTRYPOINT и CMD с Django Migrations - PullRequest
0 голосов
/ 30 ноября 2018

Я пытался найти лучший способ справиться с настройкой проекта Django с помощью Docker.Но я несколько озадачен тем, как CMD и ENTRYPOINT работают по отношению к командам compose.

Когда я впервые настраиваю проект, мне нужно запустить createuperuser и выполнить миграцию для базы данных.Я пытался использовать скрипт для запуска команд в качестве точки входа в моем Dockerfile, но, похоже, он не работал согласованно.Я переключился на конфигурацию, показанную ниже, где я перезаписываю CMD Dockerfile с помощью команд в моем файле compose, где сказано запускать makemigrations, migrate и createuperuser.

У меня проблема именно в том, как установитьэто так, что он делает то, что мне нужно.Если я задаю команду (показанную как закомментированную в коде) в моем файле компоновки, она должна перезаписать CMD в моем Dockerfile из того, что я понимаю.

Что я не уверен, так это то, нужно ли мне использовать ENTRYPOINT или CMD в моем Dockerfile для достижения этой цели?Поскольку CMD перезаписывается моим файлом compose, а ENTRYPOINT - нет, разве это не вызовет проблем, если он будет установлен в ENTRYPOINT, поскольку он попытается запустить gunicorn во второй раз после выполнения команды compose?

Будут ли какие-либо недостатки в этом подходе по сравнению с использованием сценария точки входа?

И наконец, существует ли общий передовой подход к обработке команд установки Django при развертывании докернизированного приложения Django?Или я уже делаю то, что обычно делается?

Вот мой Dockerfile:

FROM python:3.6
LABEL maintainer x@x.com

ARG requirements=requirements/production.txt
ENV DJANGO_SETTINGS_MODULE=site.settings.production_test

WORKDIR /app

COPY manage.py /app/
COPY requirements/ /app/requirements/ 

RUN pip install -r $requirements

COPY config config
COPY site site
COPY templates templates
COPY logs logs
COPY scripts scripts

EXPOSE 8001

CMD ["/usr/local/bin/gunicorn", "--config", "config/gunicorn.conf", "--log-config", "config/logging.conf", "-e", "DJANGO_SETTINGS_MODULE=site.settings.production_test", "-w", "4", "-b", "0.0.0.0:8001", "site.wsgi:application"]

И мой файл compose (пропущены разделы nginx и postgres, поскольку они не нужны для иллюстрации проблемы):

version: "3.2"
services:
  app:
    restart: always
    build:
      context: .
      dockerfile: Dockerfile.prodtest
      args:
        requirements: requirements/production.txt
    #command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn --config gunicorn.conf --log-config loggigng.conf -e DJANGO_SETTINGS_MODULE=site.settings.production_test -W 4 -b 0.0.0.0:8000 site.wsgi"
    container_name: dj01
    environment:
      - DJANGO_SETTINGS_MODULE=site.settings.production_test
      - PYTHONDONTWRITEBYTECODE=1
    volumes:
      - ./:/app
      - /static:/static
      - /media:/media
    networks:
      - main
    depends_on:
      - db

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

У меня есть следующий скрипт точки входа, который будет пытаться выполнить миграцию автоматически в моем проекте Django:

#!/bin/bash -x

python manage.py migrate --noinput || exit 1
exec "$@"

Единственное изменение, которое должно произойти с вашим Dockerfile, - это ДОБАВИТЬ его и указать ENTRYPOINT,Я обычно помещаю эти строки непосредственно об инструкции CMD:

ADD docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod a+x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]

(обратите внимание, что chmod необходим, только если файл docker-entrypoint.sh в вашей среде сборки уже не является исполняемым)

Я добавляю || exit 1, чтобы скрипт остановил контейнер в случае сбоя миграции по любой причине.При запуске вашего проекта через docker-compose, возможно, что база данных может быть не на 100% готова к принятию соединений при выполнении этой команды переноса.Между выходом при ошибке и restart: always, который у вас уже есть в вашем docker-compose.yml, это будет правильно обрабатывать это состояние гонки.

Обратите внимание, что параметр -x, который я указал для bash, выводит эхочто делает bash, что я считаю полезным для отладки моих скриптов.Его можно опустить, если вы хотите меньше многословия в журналах контейнеров.

0 голосов
/ 30 ноября 2018

Dockerfile:

...
ENTRYPOINT ["entrypoint.sh"]
CMD ["start"]

entrypoint.sh будет выполняться постоянно, в то время как CMD будет аргументом по умолчанию для него ( docs )

entrypoint.sh:

if ["$1" = "start"]
then
    /usr/local/bin/gunicorn --config config/gunicorn.conf \
        --log-config config/logging.conf ...
elif  ["$1" = "migrate"]
    # whatever
    python manage.py migrate
fi

теперь можно сделать что-то вроде

version: "3.2"
services:
  app:
    restart: always
    build:
      ...
    command: migrate # if needed

или

docker exec -it <container> bash -c entrypoint.sh migrate
...