我一直在努力寻找使用 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 [email protected]
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/