1

我有一个 python 包,其中的依赖项在poetry.lock 文件中指定用于开发和测试。然后我构建并发布包,它安装在生产 docker 映像上。但问题是:发布的包在 pyproject.toml 的tool.poetry.dependencies部分中指定了它的依赖项,这可能与poetry.lock 不同。因此,生产环境最终可能会产生与测试环境不同的依赖关系。

我可以想到几种实现一致性的方法,但对我来说似乎没有一个好:

  1. 在 pyproject.toml 中使用与在poetry.lock 中相同的集合版本。这将保证发布的包具有与 dev/test 相同的依赖项。但是此时保留一个poetry.lock 文件还有什么意义,因为poetry install如果没有poetry.lock 文件,也可以使用pyproject.toml。我认为这行得通,但是我不明白为什么首先要有poetry.lock。

  2. 在生产 docker 映像中,从包 repo 中签出poetry.lock 文件并poetry install在安装包本身之前运行。但这会增加 docker 镜像的大小,如果 repo 是私有的,则会引入不必要的配置,并且总体上看起来并不自然。

我对 Python 的这一部分很陌生,所以其中之一可能是“标准”工作流程。或者,也许我只是完全错过了一些东西。谢谢回答!

4

1 回答 1

2

选项 1:不建议按照选项 1 中的描述确定依赖版本,因为它会导致不必要的严格包。这通常会导致可避免的冲突,特别是如果您正在编写的包也是对其他项目的内部依赖项。

选项 2:像这样处理依赖项肯定比选项 1 更好,但比我想提出的选项更难维护。作为旁注,它还需要在您的 docker 映像上安装诗歌 - 只有pip当您想要做的只是安装包时,您才真正需要。

选项 3:在构建管道的开头创建一个操舵室,并在后续步骤中使用它来安装运行时依赖项。这确保了测试代码和部署代码之间没有可能的差异,而且速度非常快,因为没有从 Internet 下载或构建仅源代码的发行版。我将使用一个示例.gitlab-ci.yml来说明我的意思,但是这个概念应该在没有太多问题的情况下转化为其他所有 CI/CD:

.gitlab-ci.yml

image: acaratti/pypoet
# a simple python:slim image that comes with poetry preinstalled

stages:
  - build
  - test
  - release

variables:
  WHEELHOUSE: wheelhouse 
  POETRY_VIRTUALENVS_PATH: venv  # speeds up jobs
  IMAGE_NAME: my-app

wheels:
  stage: build
  script:
    - poetry install
    - poetry build -f wheel
    - poetry export -f requirements.txt -o requirements.txt
    - poetry run pip wheel -w ${WHEELHOUSE} -r requirements.txt
    - mv dist/* ${WHEELHOUSE}
  artifacts:
    expire_in: 1 week
    paths:
      - ${WHEELHOUSE}
      - ${POETRY_VIRTUALENVS_PATH}

pytest:
  stage: test
  script:
    # no need to run `poetry install` because 
    # the venv from the build-job gets re-used
    - poetry run pytest

dockerize:
  stage: release
  image: docker:git
  script:
    - docker build . -t ${IMAGE_NAME}
    - docker push ${IMAGE_NAME}

如果你在 dockerization 期间有这样的操舵室,Dockerfile 本身通常就足够简单了:

Dockerfile

FROM python:3.9-slim

COPY wheelhouse/* wheelhouse/

RUN pip install wheelhouse/*

ENTRYPOINT ["run", "my", "app"]

注意事项

您用于wheel作业的映像需要与 docker 文件中的基本映像相同(或任何尝试安装操舵室或重新使用虚拟环境的作业) - 如果您将 debian 用于 gitlab 作业,但高山在产品形象中,事情会很快破裂。

这也扩展到在本地构建图像,如果这是您在开发期间想要做的事情。如果您的工作站有不同的架构,例如 ubuntu,您可能无法再这样做了。是一个在您的工作站上创建一个基于 debian 的可工作的操舵室的配方。

于 2021-05-14T12:56:35.967 回答