【问题标题】:Dockerfile Build Fails - Pipenv and Pyenv Multiple Versions of Python FoundDockerfile 构建失败 - 发现 Pipenv 和 Pyenv 多个版本的 Python
【发布时间】:2019-12-01 02:23:10
【问题描述】:

问题:如何修复 Dockerfile 以正确冻结 requirements.txt 并成功构建?

我正在部署 Python 脚本的 Dockerfile,利用 Pyenv 和 Pipenv 进行本地开发。

在 Piplock 文件被冻结为 requirements.txt 的构建步骤中,我收到以下错误:

错误:“--python”的值无效:路径中的预期 Python /Users/jz/.local/share/virtualenvs/quanter-TP0oWHoL/bin/python3 确实 不存在

我的 Dockerfile 是:

FROM python:3.7
RUN pip install pipenv
COPY Pipfile* /tmp/
RUN cd /tmp && pipenv --python /Users/x/.local/share/virtualenvs/quanter-TP0oWHoL/bin/python3 lock --requirements > requirements.txt
ENV RDKAFKA_INSTALL=system
RUN pip install -r /tmp/requirements.txt
COPY . /tmp/app/
RUN pip install /tmp/app/
CMD ["python", "./tmp/app/main.py"]

本地 Pipenv 环境的创建提供了有关解释器的以下信息(在 Dockerfile 中使用):

使用 /usr/local/opt/pyenv/versions/3.8.0/bin/python3 (3.8.0) 来 create virtualenv... ⠙ 创建虚拟环境...使用基本前缀 '/usr/local/opt/pyenv/versions/3.8.0' 新的 python 可执行文件 /Users/x/.local/share/virtualenvs/quanter-TP0oWHoL/bin/python3 还有 在中创建可执行文件 /Users/x/.local/share/virtualenvs/quanter-TP0oWHoL/bin/python

Pyenv 在本地使用 3.8.0:

pyenv versions
system
3.7.5
* 3.8.0 (set by /Users/x/Projects/quanter/.python-version)

我们将不胜感激任何帮助完成这项工作!谢谢。

【问题讨论】:

  • 为什么需要手动创建锁:从 pipenv 转换需求并加锁? Pipenv 为你做这件事,不是吗?
  • @funnydman 虽然我想在本地开发中使用 Pipenv 作为其虚拟环境,但我不希望 Docker 环境内部有一个虚拟环境,从而混淆了 Docker 作为环境的目的。我只想在 Docker 容器中使用 Pip 并从需求文件系统地安装依赖项。不需要虚拟环境。
  • @funnydman 就目前而言,由于我已经概述的无法找到 Pyenv 解释器的问题,Pipenv 无论如何都无法工作。

标签: python-3.x docker dockerfile pipenv pyenv


【解决方案1】:

最初的错误来自pipenv在给定路径上找不到python可执行文件的想法。它是硬编码的,但在每个全新的构建中,pipenv 将创建具有不同名称的 env。看看这个有趣的讨论:How does pipenv know the virtualenv for the current project?,似乎可以预见,但应该有更好的解决方案。

首先,您不需要直接指定 python 可执行文件的路径,因为 python 映像仅附带一个系统 python 安装,例如它会默认通过python 提供(当然你可以用不同版本的python手动创建不同的环境)。

其次,您可以在更多nicer and preferable way 中处理docker env 中的pipenv,而不是将pipenv 转换为类似流的pip。看看下面的例子:

FROM python:3.7

COPY Pipfile /
COPY Pipfile.lock /

RUN pip3 install pipenv \
    && pipenv install --system --deploy --ignore-pipfile 

几个值得考虑的注意事项:

  1. Pipfile.lock 提交到 VCS。在这种情况下,您可以确保在每个环境中您都拥有完全相同版本的包及其依赖项。
  2. 您可能对--system 选项感兴趣。这表示将依赖项安装到系统中,而不是 virtualenv(这是您所期望的)。但根据这个答案:https://stackoverflow.com/a/55610857/9926721 官方不推荐。但是,一个非常受欢迎的项目wemake-django-template 也使用它。
  3. 考虑拆分环境。 有一个有用的标志--dev。不再有几个需求文件。以更有效的方式处理它。

【讨论】:

  • 这是一个合理的建议,我意识到我在考虑本地解释器而不是 Docker 映像中的解释器,并指出 --system 选项允许在系统范围内安装依赖项.今晚我会复习并回复任何问题或将其标记为已回答。谢谢@funnydman。
  • @Liquidgenius 随时提出任何问题。
猜你喜欢
  • 2021-07-23
  • 2018-12-14
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2021-04-13
  • 2020-06-25
  • 2016-10-16
相关资源
最近更新 更多