我一直在努力寻找使用 Docker 设置 Django 项目的最佳方法。但是我对 CMD 和 ENTRYPOINT 与 compose 命令相关的功能有些困惑。

当我第一次设置项目时,我需要运行 createsuperuser 并为数据库迁移。我曾尝试使用脚本将命令作为 Dockerfile 中的入口点运行,但它似乎无法始终如一地工作。我切换到如下所示的配置,在那里我用我的撰写文件中的命令覆盖了 Dockerfile CMD,在那里它被告知运行 makemigrations、migrate 和 createsuperuser。

我遇到的问题正是如何设置它才能满足我的需要。如果我在我的 compose 文件中设置了一个命令(显示为代码中的注释),它应该根据我的理解覆盖我的 Dockerfile 中的 CMD。

我不确定的是我是否需要在我的 Dockerfile 中使用 ENTRYPOINT 或 CMD 来实现这一点?由于 CMD 被我的 compose 文件覆盖而 ENTRYPOINT 没有覆盖,如果将其设置为 ENTRYPOINT 会不会导致问题,因为它会在 compose 命令执行后再次尝试运行 gunicorn?

与使用入口点脚本相比,这种方法有什么缺点吗?

最后,在部署 dockerized 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"]

我的撰写文件(省略了 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

最佳答案

我有以下入口点脚本,它将尝试在我的 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"]

(请注意,仅当构建环境中的 docker-entrypoint.sh 文件不可执行时,才需要 chmod)

我添加 || exit 1 以便脚本将在迁移因任何原因失败时停止容器。通过 docker-compose 启动项目时,当此 migrate 命令运行时,数据库可能未 100% 准备好接受连接。在错误退出方法和 docker-compose.yml 中已有的 restart: always 之间,这将正确处理该竞争条件。

请注意,我为 bash 指定的 -x 选项反射(reflect)了 bash 正在执行的操作,我认为这有助于调试我的脚本。如果您希望在容器日志中减少冗长,则可以省略它。

关于django - Docker Compose ENTRYPOINT 和 CMD 与 Django 迁移,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53563437/

10-16 13:48