将 Python Poetry 与 Docker 集成

2025-03-26 09:08:00
admin
原创
17
摘要:问题描述:您能否给我一个示例,说明我可以从Docker 中Dockerfile安装我需要的所有软件包poetry.lock并将其安装到我的镜像/容器中?pyproject.toml解决方案 1:将 Poetry 与 Docker 一起使用时需要注意几点。安装安装 Poetry 的官方方式是:curl -sSL...

问题描述:

您能否给我一个示例,说明我可以从Docker 中Dockerfile安装我需要的所有软件包poetry.lock并将其安装到我的镜像/容器中?pyproject.toml


解决方案 1:

将 Poetry 与 Docker 一起使用时需要注意几点。

安装

安装 Poetry 的官方方式是:

curl -sSL https://install.python-poetry.org | python3 -

这样可以将 Poetry 及其依赖项与您的依赖项隔离。

你也可以使用pip install 'poetry==$POETRY_VERSION'。但是,这会将 Poetry 及其依赖项安装到你的主 中site-packages/。这可能并不理想。

另外,也将此版本固定在您的pyproject.toml

[build-system]
# Should be the same as `$POETRY_VERSION`:
requires = ["poetry-core>=1.6"]
build-backend = "poetry.core.masonry.api"

它将保护您免受本地和 Docker 环境之间的版本不匹配的影响。

缓存依赖项

我们希望缓存我们的需求,并且仅在文件更改时重新安装它们pyproject.tomlpoetry.lock否则构建会很慢。为了实现有效的缓存层,我们应该放置:

COPY poetry.lock pyproject.toml /code/

在安装 Poetry 之后,但在添加任何其他文件之前。

虚拟环境

接下来要记住的是virtualenv创建。我们在 Docker 中不需要它。它已经被隔离了。因此,我们使用POETRY_VIRTUALENVS_CREATE=falsepoetry config virtualenvs.create false设置来关闭它。

开发与生产

如果您像我一样在开发和生产中使用相同的方法Dockerfile,那么您将需要根据某些环境变量安装不同的依赖项集:

poetry install $(test "$YOUR_ENV" == production && echo "--only=main")

这种方式$YOUR_ENV将控制安装哪些依赖项集:全部(默认)或仅带有--only=main标志的生产。

您可能还想添加更多选项以获得更好的体验:

  1. --no-interaction不要问任何互动问题

  2. --no-ansi标记以使您的输出更加日志友好

结果

你最终会得到类似如下的结果:

FROM python:3.11.5-slim-bookworm

ARG YOUR_ENV

ENV YOUR_ENV=${YOUR_ENV} \n  PYTHONFAULTHANDLER=1 \n  PYTHONUNBUFFERED=1 \n  PYTHONHASHSEED=random \n  PIP_NO_CACHE_DIR=off \n  PIP_DISABLE_PIP_VERSION_CHECK=on \n  PIP_DEFAULT_TIMEOUT=100 \n  # Poetry's configuration:
  POETRY_NO_INTERACTION=1 \n  POETRY_VIRTUALENVS_CREATE=false \n  POETRY_CACHE_DIR='/var/cache/pypoetry' \n  POETRY_HOME='/usr/local' \n  POETRY_VERSION=1.7.1
  # ^^^
  # Make sure to update it!

# System deps:
RUN curl -sSL https://install.python-poetry.org | python3 -

# Copy only requirements to cache them in docker layer
WORKDIR /code
COPY poetry.lock pyproject.toml /code/

# Project initialization:
RUN poetry install $(test "$YOUR_ENV" == production && echo "--only=main") --no-interaction --no-ansi

# Creating folders, and files for a project:
COPY . /code

您可以在此处找到一个完全可行且真实的例子。

解决方案 2:

使用 Poetry 和 venv 进行多阶段 Docker 构建

更新(2024-03-16)

在过去的几年里,这变得容易多了。这些天,我会使用 Poetry 的 bundle 插件将应用程序安装到虚拟环境中,然后将虚拟环境复制到无发行版映像中。使用 Debian 打包的 pipx 安装 Poetry。(当您的项目与新的 Poetry 版本不兼容时,您可能希望固定 Poetry 以避免损坏。)--only=main捆绑时使用该选项以省略开发依赖项。

FROM debian:12-slim AS builder
RUN apt-get update && \n    apt-get install --no-install-suggests --no-install-recommends --yes pipx
ENV PATH="/root/.local/bin:${PATH}"
RUN pipx install poetry
RUN pipx inject poetry poetry-plugin-bundle
WORKDIR /src
COPY . .
RUN poetry bundle venv --python=/usr/bin/python3 --only=main /venv

FROM gcr.io/distroless/python3-debian12
COPY --from=builder /venv /venv
ENTRYPOINT ["/venv/bin/my-awesome-app"]

原始答案

不要禁用虚拟环境创建。虚拟环境在 Docker 构建中起着重要作用,因为它们提供了一种利用多阶段构建的优雅方式。简而言之,构建阶段会将所有内容安装到虚拟环境中,而最后阶段只是将虚拟环境复制到一个小映像中。

poetry export在复制代码之前,请先使用并安装固定需求。这样您就可以使用 Docker 构建缓存,并且永远不会因为更改了代码中的一行而重新安装依赖项。

不要使用poetry install来安装您的代码,因为它将执行可编辑的安装。相反,使用poetry build来构建一个 wheel,然后将其 pip 安装到您的虚拟环境中。(感谢PEP 517,整个过程也可以用简单的 来执行pip install .,但由于构建隔离,您最终会安装另一份 Poetry。)

以下是将 Flask 应用安装到 Alpine 映像的示例 Dockerfile,该映像依赖于 Postgres。此示例使用入口点脚本来激活虚拟环境。但通常情况下,没有入口点脚本也没问题,因为您只需/venv/bin/python在指令中引用 Python 二进制文件即可CMD

Dockerfile

FROM python:3.7.6-alpine3.11 as base

ENV PYTHONFAULTHANDLER=1 \n    PYTHONHASHSEED=random \n    PYTHONUNBUFFERED=1

WORKDIR /app

FROM base as builder

ENV PIP_DEFAULT_TIMEOUT=100 \n    PIP_DISABLE_PIP_VERSION_CHECK=1 \n    PIP_NO_CACHE_DIR=1 \n    POETRY_VERSION=1.0.5

RUN apk add --no-cache gcc libffi-dev musl-dev postgresql-dev
RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv

COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt | /venv/bin/pip install -r /dev/stdin

COPY . .
RUN poetry build && /venv/bin/pip install dist/*.whl

FROM base as final

RUN apk add --no-cache libffi libpq
COPY --from=builder /venv /venv
COPY docker-entrypoint.sh wsgi.py ./
CMD ["./docker-entrypoint.sh"]

docker-entrypoint.sh

#!/bin/sh

set -e

. /venv/bin/activate

while ! flask db upgrade
do
     echo "Retry..."
     sleep 1
done

exec gunicorn --bind 0.0.0.0:5000 --forwarded-allow-ips='*' wsgi:app

wsgi.py

import your_app

app = your_app.create_app()

解决方案 3:

这是对@Claudio 提供的答案的一个小修改,它使用了@sobolevn 在其答案中poetry install --no-root描述的新功能。

为了强制诗歌将依赖项安装到特定的虚拟环境中,首先需要启用它。

. /path/to/virtualenv/bin/activate && poetry install

因此将这些添加到@Claudio的答案中,我们得到

FROM python:3.10-slim as base

ENV PYTHONFAULTHANDLER=1 \n    PYTHONHASHSEED=random \n    PYTHONUNBUFFERED=1

WORKDIR /app

FROM base as builder

ENV PIP_DEFAULT_TIMEOUT=100 \n    PIP_DISABLE_PIP_VERSION_CHECK=1 \n    PIP_NO_CACHE_DIR=1 \n    POETRY_VERSION=1.3.1

RUN pip install "poetry==$POETRY_VERSION"

COPY pyproject.toml poetry.lock README.md ./
# if your project is stored in src, uncomment line below
# COPY src ./src
# or this if your file is stored in $PROJECT_NAME, assuming `myproject`
# COPY myproject ./myproject
RUN poetry config virtualenvs.in-project true && \n    poetry install --only=main --no-root && \n    poetry build

FROM base as final

COPY --from=builder /app/.venv ./.venv
COPY --from=builder /app/dist .
COPY docker-entrypoint.sh .

RUN ./.venv/bin/pip install *.whl
CMD ["./docker-entrypoint.sh"]

如果您需要将其用于开发目的,可以--no-dev通过替换此行来添加或删除

RUN . /venv/bin/activate && poetry install --no-dev --no-root

如@sobolevn 的回答所示

RUN . /venv/bin/activate && poetry install --no-root $(test "$YOUR_ENV" == production && echo "--no-dev")

添加适当的环境变量声明后。

该示例使用 debian-slim 作为基础,但将其适配到基于 alpine 的图像应该是一项简单的任务。

解决方案 4:

总结

我已经能够使用 来设置poetry一个Django项目postgres。经过一番研究,我最终得到了以下结果Dockerfile

FROM python:slim

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1

# Install and setup poetry
RUN pip install -U pip \n    && apt-get update \n    && apt install -y curl netcat \n    && curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
ENV PATH="${PATH}:/root/.poetry/bin"

WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \n  && poetry install --no-interaction --no-ansi

# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]

这是的内容entrypoint.sh

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

python manage.py migrate

exec "$@"

详细说明

需要注意的几点:

  • 我决定使用slim而不是alpine作为python图像的标签,因为尽管alpine图像应该可以减小 Docker 图像的大小并加快构建速度,但使用 Python,您实际上可能会得到更大的图像,并且需要一段时间才能构建(阅读本文了解更多信息)。

  • 使用此配置比使用 alpine 镜像构建容器更快,因为我不需要添加一些额外的包来正确安装 Python 包。

  • 我正在直接从文档中提供的 URL 安装poetry。我知道 提供的警告sobolevn。但是,我认为从长远来看,poetry默认使用 的最新版本比依赖我应该定期更新的环境变量更好。

  • 更新环境变量PATH至关重要。否则,您将收到一条错误消息,指出未找到诗歌

  • 依赖项直接安装在容器的 Python 解释器中。它不会poetry在安装依赖项之前创建虚拟环境。

如果您需要alpine这个版本Dockerfile

FROM python:alpine

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1

# Install dev dependencies
RUN apk update \n    && apk add curl postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev

# Install poetry
RUN pip install -U pip \n    && curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
ENV PATH="${PATH}:/root/.poetry/bin"

WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \n  && poetry install --no-interaction --no-ansi

# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]

请注意,该alpine版本需要一些依赖项postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev才能正常工作。

解决方案 5:

这是对我有用的最小配置:

FROM python:3.7

ENV PIP_DISABLE_PIP_VERSION_CHECK=on

RUN pip install poetry

WORKDIR /app
COPY poetry.lock pyproject.toml /app/

RUN poetry config virtualenvs.create false
RUN poetry install --no-interaction

COPY . /app

请注意,它不如@sobolevn 的配置那么安全。

我要补充一点,如果项目可以进行可编辑安装pyproject.toml,则可以删除一两行:

FROM python:3.7

ENV PIP_DISABLE_PIP_VERSION_CHECK=on

WORKDIR /app
COPY poetry.lock pyproject.toml /app/

RUN pip install -e .

COPY . /app

解决方案 6:

使用docker多阶段构建和python slim镜像,将诗歌锁导出到requirements.txt,然后在virtualenv中通过pip安装。

它具有最小的尺寸不需要在运行时映像中添加诗歌,固定所有内容的版本。

FROM python:3.9.7 as base
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /app

FROM base as poetry
RUN pip install poetry==1.1.12
COPY poetry.lock pyproject.toml /app/
RUN poetry export -o requirements.txt

FROM base as build
COPY --from=poetry /app/requirements.txt /tmp/requirements.txt
RUN python -m venv .venv && \n    .venv/bin/pip install 'wheel==0.36.2' && \n    .venv/bin/pip install -r /tmp/requirements.txt

FROM python:3.9.7-slim as runtime
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /app
ENV PATH=/app/.venv/bin:$PATH
COPY --from=build /app/.venv /app/.venv
COPY . /app

解决方案 7:

这是一个精简的示例,其中首先将一个包含依赖项的层(仅在这些依赖项发生变化时构建),然后将一个包含完整源代码的层添加到映像中。设置poetry为安装到全局site-packages会留下一个配置工件,该工件也可以被删除。

FROM python:alpine

WORKDIR /app

COPY poetry.lock pyproject.toml ./
RUN pip install --no-cache-dir --upgrade pip \n && pip install --no-cache-dir poetry \n \n && poetry config settings.virtualenvs.create false \n && poetry install --no-dev \n \n && pip uninstall --yes poetry \n
COPY . ./

解决方案 8:

我的 Dockerfile 基于@lmiguelvargasf 的回答。请参阅他的帖子以获得更详细的解释。我唯一做出的重大更改如下:

  • 我现在使用的是最新的官方安装程序,install-poetry.py而不是官方文档中推荐的get-poetry.py弃用版本。我也使用标志安装特定版本,但您也可以使用环境变量。更多信息请参阅他们的官方文档!--version`POETRY_VERSION`

  • PATH使用的是/root/.local/bin:$PATH而不是${PATH}:/root/.poetry/bin来自 OP 的 Dockerfile

FROM python:3.10.4-slim-buster

ENV PYTHONDONTWRITEBYTECODE 1 \n    PYTHONUNBUFFERED 1

RUN apt-get update \n    && apt-get install curl -y \n    && curl -sSL https://install.python-poetry.org | python - --version 1.1.13

ENV PATH="/root/.local/bin:$PATH"

WORKDIR /usr/app

COPY pyproject.toml poetry.lock ./

RUN poetry config virtualenvs.create false \n    && poetry install --no-dev --no-interaction --no-ansi

COPY ./src ./

EXPOSE 5000

CMD [ "poetry", "run", "gunicorn", "-b", "0.0.0.0:5000", "test_poetry.app:create_app()" ]

解决方案 9:

我使用 lock 包(依赖于 lock 文件中所有版本的包)创建了一个解决方案。这会导致干净的 pip 安装,而无需任何要求文件。

步骤如下:构建包、构建锁包、将两个轮子复制到容器中、使用 pip 安装两个轮子。

安装是:poetry add --dev poetry-lock-package

docker build 之外的步骤包括:

poetry build
poetry run poetry-lock-package --build

那么你的Dockerfile应该包含:

FROM python:3-slim

COPY dist/*.whl /

RUN pip install --no-cache-dir /*.whl \n    && rm -rf /*.whl

CMD ["python", "-m", "entry_module"]

为了使其适用于多个平台,第一步可以在多阶段构建的第一阶段完成。例如:

FROM python:alpine AS builder

WORKDIR /app

RUN pip install --no-cache-dir --upgrade pip \n && pip install --no-cache-dir poetry

COPY . ./

RUN poetry add --group dev poetry-lock-package
RUN poetry build
RUN poetry run poetry-lock-package --build

FROM python:alpine

ENV PYTHONUNBUFFERED 1

WORKDIR /app

COPY --from=builder /app/dist/*.whl /

RUN pip install --no-cache-dir /*.whl \n    && rm -rf /*.whl

CMD [ "python", "-m", "entry_module" ]

解决方案 10:

我向社区提供了一个 Poetry docker 镜像。此镜像始终适用于最新的三个 Poetry 版本和不同的 Python 版本。你可以选择自己喜欢的版本:

您可以查看 Docker 文件以了解我在其中应用的实践。它非常简单:https://github.com/max-pfeiffer/python-poetry/blob/main/build/Dockerfile

# References: using official Python images
# https://hub.docker.com/_/python
ARG OFFICIAL_PYTHON_IMAGE
FROM ${OFFICIAL_PYTHON_IMAGE}
ARG POETRY_VERSION

LABEL maintainer="Max Pfeiffer <max@maxpfeiffer.ch>"

# References:
# https://pip.pypa.io/en/stable/topics/caching/#avoiding-caching
# https://pip.pypa.io/en/stable/cli/pip/?highlight=PIP_NO_CACHE_DIR#cmdoption-no-cache-dir
# https://pip.pypa.io/en/stable/cli/pip/?highlight=PIP_DISABLE_PIP_VERSION_CHECK#cmdoption-disable-pip-version-check
# https://pip.pypa.io/en/stable/cli/pip/?highlight=PIP_DEFAULT_TIMEOUT#cmdoption-timeout
# https://pip.pypa.io/en/stable/topics/configuration/#environment-variables
# https://python-poetry.org/docs/#installation

ENV PIP_NO_CACHE_DIR=off \n    PIP_DISABLE_PIP_VERSION_CHECK=on \n    PIP_DEFAULT_TIMEOUT=100 \n    POETRY_VERSION=${POETRY_VERSION} \n    POETRY_HOME="/opt/poetry"

ENV PATH="$POETRY_HOME/bin:$PATH"

# https://python-poetry.org/docs/#osx--linux--bashonwindows-install-instructions
RUN apt-get update \n    && apt-get install --no-install-recommends -y \n        build-essential \n        curl \n    && curl -sSL https://install.python-poetry.org | python - \n    && apt-get purge --auto-remove -y \n      build-essential \n      curl

我将此图像用作另外两个项目的基础图像,您可以在其中看到如何利用 Poetry 创建虚拟环境并使用 Uvicorn 和/或 Gunicorn 应用程序服务器运行 Python 应用程序:

第一个图像的 Dockerfile:https://github.com/max-pfeiffer/uvicorn-poetry/blob/main/build/Dockerfile

# The Poetry installation is provided through the base image. Please check the
# base image if you interested in the details.
# Base image: https://hub.docker.com/r/pfeiffermax/python-poetry
# Dockerfile: https://github.com/max-pfeiffer/python-poetry/blob/main/build/Dockerfile
ARG BASE_IMAGE
FROM ${BASE_IMAGE}
ARG APPLICATION_SERVER_PORT

LABEL maintainer="Max Pfeiffer <max@maxpfeiffer.ch>"

    # https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUNBUFFERED
ENV PYTHONUNBUFFERED=1 \n    # https://docs.python.org/3/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE
    PYTHONDONTWRITEBYTECODE=1 \n    PYTHONPATH=/application_root \n    # https://python-poetry.org/docs/configuration/#virtualenvsin-project
    POETRY_VIRTUALENVS_IN_PROJECT=true \n    POETRY_CACHE_DIR="/application_root/.cache" \n    VIRTUAL_ENVIRONMENT_PATH="/application_root/.venv" \n    APPLICATION_SERVER_PORT=$APPLICATION_SERVER_PORT

# Adding the virtual environment to PATH in order to "activate" it.
# https://docs.python.org/3/library/venv.html#how-venvs-work
ENV PATH="$VIRTUAL_ENVIRONMENT_PATH/bin:$PATH"

# Principle of least privilege: create a new user for running the application
RUN groupadd -g 1001 python_application && \n    useradd -r -u 1001 -g python_application python_application

# Set the WORKDIR to the application root.
# https://www.uvicorn.org/settings/#development
# https://docs.docker.com/engine/reference/builder/#workdir
WORKDIR ${PYTHONPATH}
RUN chown python_application:python_application ${PYTHONPATH}

# Create cache directory and set permissions because user 1001 has no home
# and poetry cache directory.
# https://python-poetry.org/docs/configuration/#cache-directory
RUN mkdir ${POETRY_CACHE_DIR} && chown python_application:python_application ${POETRY_CACHE_DIR}

# Document the exposed port
# https://docs.docker.com/engine/reference/builder/#expose
EXPOSE ${APPLICATION_SERVER_PORT}

# Use the unpriveledged user to run the application
USER 1001

# Run the uvicorn application server.
CMD exec uvicorn --workers 1 --host 0.0.0.0 --port $APPLICATION_SERVER_PORT app.main:app

如果你像这样构建它,示例应用程序的 Dockerfile 可以像这样简单进行多阶段构建:https://github.com/max-pfeiffer/uvicorn-poetry/blob/main/examples/fast_api_multistage_build/Dockerfile

# Be aware that you need to specify these arguments before the first FROM
# see: https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG BASE_IMAGE=pfeiffermax/uvicorn-poetry:3.0.0-python3.10.9-slim-bullseye@sha256:cdd772b5e6e3f2feb8d38f3ca7af9b955c886a86a4aecec99bc43897edd8bcbe
FROM ${BASE_IMAGE} as dependencies-build-stage

# install [tool.poetry.dependencies]
# this will install virtual environment into /.venv because of POETRY_VIRTUALENVS_IN_PROJECT=true
# see: https://python-poetry.org/docs/configuration/#virtualenvsin-project
COPY ./poetry.lock ./pyproject.toml /application_root/
RUN poetry install --no-interaction --no-root --without dev

FROM ${BASE_IMAGE} as production-image

# Copy virtual environment
COPY --chown=python_application:python_application --from=dependencies-build-stage /application_root/.venv /application_root/.venv

# Copy application files
COPY --chown=python_application:python_application /app /application_root/app/

解决方案 11:

我看到这里的所有答案都是使用 pip 方式安装 Poetry 以避免版本问题。安装 Poetry 的官方方式会读取 POETRY_VERSION 环境变量(如果已定义)来安装最合适的版本。

github上有一个问题,我认为这张票的解决方案非常有趣:

# `python-base` sets up all our shared environment variables
FROM python:3.8.1-slim as python-base

    # python
ENV PYTHONUNBUFFERED=1 \n    # prevents python creating .pyc files
    PYTHONDONTWRITEBYTECODE=1 \n    \n    # pip
    PIP_NO_CACHE_DIR=off \n    PIP_DISABLE_PIP_VERSION_CHECK=on \n    PIP_DEFAULT_TIMEOUT=100 \n    \n    # poetry
    # https://python-poetry.org/docs/configuration/#using-environment-variables
    POETRY_VERSION=1.0.3 \n    # make poetry install to this location
    POETRY_HOME="/opt/poetry" \n    # make poetry create the virtual environment in the project's root
    # it gets named `.venv`
    POETRY_VIRTUALENVS_IN_PROJECT=true \n    # do not ask any interactive question
    POETRY_NO_INTERACTION=1 \n    \n    # paths
    # this is where our requirements + virtual environment will live
    PYSETUP_PATH="/opt/pysetup" \n    VENV_PATH="/opt/pysetup/.venv"


# prepend poetry and venv to path
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"


# `builder-base` stage is used to build deps + create our virtual environment
FROM python-base as builder-base
RUN apt-get update \n    && apt-get install --no-install-recommends -y \n        # deps for installing poetry
        curl \n        # deps for building python deps
        build-essential

# install poetry - respects $POETRY_VERSION & $POETRY_HOME
RUN curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python

# copy project requirement files here to ensure they will be cached.
WORKDIR $PYSETUP_PATH
COPY poetry.lock pyproject.toml ./

# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN poetry install --no-dev


# `development` image is used during development / testing
FROM python-base as development
ENV FASTAPI_ENV=development
WORKDIR $PYSETUP_PATH

# copy in our built poetry + venv
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH

# quicker install as runtime deps are already installed
RUN poetry install

# will become mountpoint of our code
WORKDIR /app

EXPOSE 8000
CMD ["uvicorn", "--reload", "main:app"]


# `production` image used for runtime
FROM python-base as production
ENV FASTAPI_ENV=production
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
COPY ./app /app/
WORKDIR /app
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app"]

解决方案 12:

这是一种不同的方法,它保持 Poetry 完整,因此您仍然可以使用poetry add等。如果您使用 VS Code devcontainer,这种方法很好。

简而言之,安装 Poetry,让 Poetry 创建虚拟环境,然后每次启动新 shell 时通过修改进入虚拟环境.bashrc

FROM ubuntu:20.04

RUN apt-get update && apt-get install -y python3 python3-pip curl

# Use Python 3 for `python`, `pip`
RUN    update-alternatives --install /usr/bin/python  python  /usr/bin/python3 1 \n    && update-alternatives --install /usr/bin/pip     pip     /usr/bin/pip3    1

# Install Poetry
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python3 -
ENV PATH "$PATH:/root/.local/bin/"

# Install Poetry packages (maybe remove the poetry.lock line if you don't want/have a lock file)
COPY pyproject.toml ./
COPY poetry.lock ./
RUN poetry install --no-interaction

# Provide a known path for the virtual environment by creating a symlink
RUN ln -s $(poetry env info --path) /var/my-venv

# Clean up project files. You can add them with a Docker mount later.
RUN rm pyproject.toml poetry.lock

# Hide virtual env prompt
ENV VIRTUAL_ENV_DISABLE_PROMPT 1

# Start virtual env when bash starts
RUN echo 'source /var/my-venv/bin/activate' >> ~/.bashrc

提醒一下,没有必要避免使用虚拟环境。它不会影响性能,而且 Poetry 的设计并不是为了在没有它们的情况下工作。

pyproject.toml编辑:@Davos 指出,除非您已经有一个and文件,否则这不起作用poetry.lock。如果您需要处理这种情况,您可能能够使用此解决方法,无论这些文件是否存在,它都应该有效。

COPY pyproject.toml* ./
COPY poetry.lock* ./
RUN poetry init --no-interaction; (exit 0) # Does nothing if pyproject.toml exists
RUN poetry install --no-interaction

解决方案 13:

以下是使用官方安装程序 bash 脚本和 Docker 镜像的配方continuumio/miniconda。此镜像是开始使用 Pythonic Docker 堆栈的好地方。

FROM continuumio/miniconda3

RUN apt update && \n    apt-get install -y curl && \n    apt-get clean && \n    rm -rf /var/lib/apt/lists/*

...

# Install poetry to /root/.local/bin
ENV POETRY_VIRTUALENVS_CREATE=false \n    POETRY_VERSION=1.8.3

# Install Python packages via Poetry
WORKDIR /app
RUN curl -sSL https://install.python-poetry.org | python3 -
ENV PATH="/root/.local/bin:$PATH"
COPY pyproject.toml poetry.lock /app/

# Skips dev packagesL --no-dev, doesn't install a package: --no-root
RUN poetry config virtualenvs.create false && \n    poetry config installer.max-workers 10 && \n    poetry install --no-dev --no-interaction --no-ansi --no-root -vvv && \n    poetry cache clear pypi --all -n

但是,在某些企业环境中,您无法运行curl到主机名,因为您使用 Artifactory 之类的东西从本地存储库安装软件包。以下是安装到 installinstall.python-poetry.org的秘诀。pipx`poetry`

FROM continuumio/miniconda3:latest

RUN apt update && \n    apt upgrade -y && \n    apt install curl -y && \n    apt clean && \n    rm -rf /var/lib/apt/lists/*

# Install pipx so we can install poetry inside the firewall
RUN python3 -m pip install --index-url "https://pypi-repository-url/folder" --user pipx
ENV PATH=/root/.local/bin:$PATH

# Install poetry to /root/.local/bin
ENV POETRY_VIRTUALENVS_CREATE=false \n    POETRY_VERSION=1.8.3
RUN pipx install --index-url "https://pypi-repository-url/folder" poetry

# Copy the poetry.lock and pyproject.toml files
WORKDIR /app
COPY pyproject.toml poetry.lock ./app/

# Skips dev packagesL --no-dev, doesn't install a package: --no-root
RUN poetry config virtualenvs.create false && \n    poetry config installer.max-workers 10 && \n    poetry install --no-dev --no-interaction --no-ansi --no-root -vvv && \n    poetry cache clear pypi --all -n

解决方案 14:

我的 Python 应用程序的 Dockerfile 如下所示 -

FROM python:3.10-alpine
RUN apk update && apk upgrade
RUN pip install -U pip poetry==1.1.13
WORKDIR /app
COPY . .
RUN poetry export --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000
ENTRYPOINT [ "python" ]
CMD ["main.py"]

解决方案 15:

其他答案都很好,但我必须根据以下要求做出一些修改:

  1. 我想要一个小图像,所以想使用 Alpine。

  2. 我想确保不要以 root 身份运行最终的图像。

  3. 我特别专注于能够以我的pyproject.toml名字运行诗歌脚本。

例如,如果我在中有这个脚本pyproject.toml

...
[tool.poetry.scripts]
my_tool = "my_tool.cli.cli:start"
...

然后,我希望my_tool(CLI) 成为我的 Dockerfile ENTRYPOINT,以便容器命令提供的参数将成为我的 CLI 的参数。这个解决方案完全满足了我的要求:

# Stage - base
FROM python:3.11-alpine3.18 as base

ENV PYTHONFAULTHANDLER=1 \n    PYTHONHASHSEED=random \n    PYTHONUNBUFFERED=1

WORKDIR /app

# Stage - builder
FROM python:3.11-alpine3.18 as builder

ENV PIP_DEFAULT_TIMEOUT=100 \n    PIP_DISABLE_PIP_VERSION_CHECK=1 \n    POETRY_VERSION=1.7.0

RUN pip install poetry==$POETRY_VERSION

WORKDIR /app

RUN python -m venv /venv

COPY pyproject.toml poetry.lock ./
RUN . /venv/bin/activate && poetry install --no-dev --no-root

COPY . .
RUN . /venv/bin/activate && poetry build

# Stage - release
FROM base as release

# install sudo as root
RUN apk add --update sudo

# add new user
ENV USER=appuser
RUN adduser -D $USER \n        && echo "$USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER \n        && chmod 0440 /etc/sudoers.d/$USER

ENV PATH="/venv/bin:$PATH"

COPY --from=builder /venv /venv
COPY --from=builder /app/dist .
RUN chown -hR $USER /venv

RUN . /venv/bin/activate && pip install *.whl

USER $USER

ENTRYPOINT ["my_cli"]

解决方案 16:

我将它添加到我的 Dockerfile 中并且它起作用了

RUN pip3 install pipx
RUN pipx install poetry
ENV PATH="/root/.local/bin:${PATH}"
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2079  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1459  
  建筑行业正处于数字化转型的关键时期,建筑产品生命周期管理(PLM)系统的实施对于提升项目效率、质量和协同性至关重要。特别是在 2025 年,基于建筑信息模型(BIM)的项目进度优化工具成为众多建筑企业关注的焦点。这些工具不仅能够整合项目全生命周期的数据,还能通过精准的分析和模拟,为项目进度管理提供强大支持。BIM 与建...
plm是什么软件   0  
  PLM系统开发的重要性与现状PLM(产品生命周期管理)系统在现代企业的产品研发、生产与管理过程中扮演着至关重要的角色。它贯穿产品从概念设计到退役的整个生命周期,整合了产品数据、流程以及人员等多方面的资源,极大地提高了企业的协同效率和创新能力。通过PLM系统,企业能够实现产品信息的集中管理与共享,不同部门之间可以实时获取...
国产plm软件   0  
  PLM(产品生命周期管理)系统在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和技术的飞速发展,企业对PLM系统的迭代周期优化需求日益迫切。2025年敏捷认证对项目管理提出了新的要求,其中燃尽图作为一种强大的可视化工具,在PLM系统迭代周期优化中有着广泛且重要的应用。深入探讨这些应用,对于提升企业的项...
plm系统主要干什么的   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用