繁体   English   中英

在 Dockerfile 中激活 python virtualenv

[英]Activate python virtualenv in Dockerfile

我有一个 Dockerfile,我尝试在其中激活 python virtualenv,它应该在这个 env 中安装所有依赖项。 但是,所有内容仍会在全局范围内安装。 我使用了不同的方法,但没有一个有效。 我也没有收到任何错误。 哪里有问题?

1. ENV PATH $PATH:env/bin

2. ENV PATH $PATH:env/bin/activate

3. RUN . env/bin/activate RUN . env/bin/activate

我还遵循了 Google Cloud 上 python-runtime 映像的 Dockerfile 配置示例,它与上面的内容基本相同。

设置这些环境变量与运行 source /env/bin/activate 相同。

ENV VIRTUAL_ENV /env

ENV PATH /env/bin:$PATH

此外, ENV VIRTUAL_ENV /env是什么意思以及它是如何使用的?

您不需要在 Docker 容器中使用 virtualenv。

virtualenv用于依赖隔离。 您希望防止安装的任何依赖项或软件包在应用程序之间泄漏。 Docker实现了同样的目标,它隔离了容器内的依赖关系,并防止容器之间和应用程序之间的泄漏。

因此,除非您在同一个容器中运行多个应用程序,否则在 Docker 容器中使用 virtualenv 是没有意义的,如果是这种情况,我会说您做错了什么,解决方案是将您的应用程序构建在一个更好的方法并将它们分成多个容器。


编辑 2022:鉴于这个答案获得了很多观点,我认为在 4 年后的现在添加这一点可能是有意义的,我意识到 Docker 映像中实际上存在虚拟环境的有效用法,尤其是在进行多阶段构建时:

FROM python:3.9-slim as compiler
ENV PYTHONUNBUFFERED 1

WORKDIR /app/

RUN python -m venv /opt/venv
# Enable venv
ENV PATH="/opt/venv/bin:$PATH"

COPY ./requirements.txt /app/requirements.txt
RUN pip install -Ur requirements.txt

FROM python:3.9-slim as runner
WORKDIR /app/
COPY --from=compiler /opt/venv /opt/venv

# Enable venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . /app/
CMD ["python", "app.py", ]

在上面的Dockerfile示例中,我们在/opt/venv创建一个 virtualenv 并使用ENV语句激活它,然后我们将所有依赖项安装到这个/opt/venv ,并且可以简单地将这个文件夹复制到我们构建的runner阶段。 这有助于最小化 docker 图像大小。

在容器中使用 virtualenv 有完全正当的理由。

您不一定需要激活 virtualenv 来安装软件或使用它。 尝试直接从 virtualenv 的bin目录调用可执行文件:

FROM python:2.7

RUN virtualenv /ve
RUN /ve/bin/pip install somepackage

CMD ["/ve/bin/python", "yourcode.py"]

您也可以只设置 PATH 环境变量,以便所有进一步的 Python 命令将使用 virtualenv 中的二进制文件,如https://pythonspeed.com/articles/activate-virtualenv-dockerfile/中所述

FROM python:2.7

RUN virtualenv /ve
ENV PATH="/ve/bin:$PATH"
RUN pip install somepackage

CMD ["python", "yourcode.py"]

设置此变量

ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH

和刚跑不完全一样

RUN . env/bin/activate

因为在单个RUN内激活不会影响 Dockerfile 中该RUN以下的任何行。 但是通过ENV设置环境变量会为所有RUN命令激活你的虚拟环境。

看这个例子:

RUN virtualenv env                       # setup env
RUN which python                         # -> /usr/bin/python
RUN . /env/bin/activate && which python  # -> /env/bin/python
RUN which python                         # -> /usr/bin/python

因此,如果您确实需要为整个 Dockerfile 激活 virtualenv,您需要执行以下操作:

RUN virtualenv env
ENV VIRTUAL_ENV /env                     # activating environment
ENV PATH /env/bin:$PATH                  # activating environment
RUN which python                         # -> /env/bin/python

尽管我同意 Marcus 的观点,这不是使用 Docker 的方式,但你可以做你想做的事。

直接使用 Docker 的 RUN 命令不会给你答案,因为它不会在虚拟环境中执行你的指令。 而是使用 /bin/bash 压缩在一行中执行的指令。 以下 Dockerfile 对我有用:

FROM python:2.7

RUN virtualenv virtual
RUN /bin/bash -c "source /virtual/bin/activate && pip install pyserial && deactivate"
...

这应该只在虚拟环境中安装 pyserial 模块。

如果您使用 python 3.x :

RUN pip install virtualenv
RUN virtualenv -p python3.5 virtual
RUN /bin/bash -c "source /virtual/bin/activate"

如果您使用的是 python 2.x :

RUN pip install virtualenv
RUN virtualenv virtual
RUN /bin/bash -c "source /virtual/bin/activate"

考虑迁移到pipenv - 一个可以为您自动化 virtualenv 和 pip 交互的工具。 PyPA推荐它。

在 docker 镜像中通过pipenv重现环境非常简单:

FROM python:3.7

RUN pip install pipenv

COPY src/Pipfile* ./

RUN pipenv install --deploy

...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM