如何使使用 Poetry 安装的软件包在 Docker 中可访问?

How can I make packages installed using Poetry accessible in Docker?

我有一个 Django REST 框架 API,我正在尝试 运行 Docker。该项目使用 Poetry 1.1.12。当 运行ning 时,我可以看到 Poetry 已正确安装,并且 Poetry 安装了我的 pyproject.toml 中的包,包括 Django。我正在使用 supervisor 运行 API 使用 Daphne,以及其他一些任务(比如收集静态文件)。

然而,当主管 运行 应用程序时,我得到:

Traceback (most recent call last):
  File "/home/docker/api/manage.py", line 22, in <module>
    main()
  File "/home/docker/api/manage.py", line 13, in main
    raise ImportError(
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
Traceback (most recent call last):
  File "/home/docker/api/manage.py", line 11, in main
    from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'

请注意我是如何设置 POETRY_VIRTUALENVS_CREATE=falseENV PATH="/root/.local/bin:${PATH}" 的。根据诗歌安装脚本,那是需要加入PATH的路径。

这是我的 Docker 文件的删节版:

FROM python:3.9-slim-buster
ENV PATH="/root/.local/bin:${PATH}"

RUN apt-get update && apt-get install -y --no-install-recommends \
    ... \
    curl \
    supervisor \
    && curl -sSL 'https://install.python-poetry.org' | python - && poetry --version \
    && apt-get remove -y curl \
    && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
    && apt-get clean -y && rm -rf /var/lib/apt/lists/* \
    && rm -rf /var/lib/apt/lists/*

COPY poetry.lock pyproject.toml /home/docker/api/

WORKDIR /home/docker/api

RUN if [ "$DEBUG" = "false" ] \
    ; then POETRY_VIRTUALENVS_CREATE=false poetry install --no-dev --no-interaction --no-ansi -vvv --extras "production" \
    ; else POETRY_VIRTUALENVS_CREATE=false poetry install --no-interaction --no-ansi -vvv --extras "production" \
    ; fi

COPY . /home/docker/api/
COPY .docker/services/api/files/supervisor.conf /etc/supervisor/conf.d/

CMD ["supervisord", "-n"]

这几乎就是我看到其他人的做法。有什么想法吗?

会不会是因为缺少 DJANGO_SETTINGS_MODULE 环境变量?

诗歌documents itself总是非常努力地运行在一个虚拟环境中。但是,Docker 容器本身与其他 Python 容器隔离,在“系统”Python.

中安装包是正常的(也是最简单的)

有一个 poetry export 命令可以将 Poetry 的文件转换为普通的 pip requirements.txt 文件,从那里您可以 RUN pip install 在您的 Docker 文件中。您可以使用多阶段 Docker 文件生成该文件,而无需在主图像中实际包含 Poetry。

FROM python:3.9-slim-buster AS poetry
RUN pip install poetry
WORKDIR /app
COPY pyproject.toml poetry.lock .
RUN poetry export -f requirements.txt --output requirements.txt

FROM python:3.9-slim-buster
WORKDIR /app
COPY --from=poetry /app/requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["./manage.py", "runserver", "0.0.0.0:8000"]

django 应该出现在生成的 requirements.txt 文件中,并且由于 pip install 将其安装为“正常”“系统”包 Python,您的应用程序应该能够正常看到它,无需调整环境变量或其他设置。