簡體   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