关于docker:优雅地激活Dockerfile中的virtualenv

9次阅读

共计 2748 个字符,预计需要花费 7 分钟才能阅读完成。

由 Itamar Turner-Trauring 最初更新 2020 年 6 月 25 日,最后创立于 2019 年 3 月 20 日

在 Docker 映像中打包 Python 应用程序时,通常会应用virtualenv。例如,您可能正在执行多阶段构建以获取较小的镜像。

因为您正在应用virtualenv,因而须要激活它 - 然而,如果您只是开始应用 Dockerfile,那么童稚的办法将不起作用。即便您的确晓得该怎么做,通常的办法也是重复性的,因而容易出错。

有一种激活 virtualenv 的简略办法,我将在本文中进行演示。 然而首先,咱们将介绍其余一些不太优雅(或损坏!)的办法。

留神:在所探讨的主题之外,本文中的 Dockerfile 并不是最佳实际的示例,因为减少的复杂性将使本文的重点难以了解。因而,如果要应用 Docker 在生产环境中运行 Python 应用程序,能够采纳以下两种办法来利用最佳实际:

  • 如果您想本人动手做:具体的清单,包含示例和参考
  • 如果您心愿尽快进行无效的设置:一个模板,其中已为您施行了最佳实际

有效的办法

如果您只是将 shell 脚本自觉地转换为 Dockerfile,则会失去看起来正确但实际上已损坏的内容:

FROM python:3.8-slim-buster
RUN python3 -m venv /opt/venv

# This is wrong!
RUN . /opt/venv/bin/activate

# Install dependencies:
COPY requirements.txt .
RUN pip install -r requirements.txt

# Run the application:
COPY myapp.py .
CMD ["python", "myapp.py"]

它的中断有两个不同的起因:

  1. RUNDockerfile 中的每一行都是一个不同的过程。activate独自运行 RUN 不会影响当前的 RUN 通话。出于所有理论目标,这是无人操作的。
  2. 当您运行生成的 Docker 映像时,它将运行 CMD- 也将不会在 virtualenv 外部运行,因为它也不受RUN 过程的影响。

最无效的反复办法

一种解决方案是显式应用 virtualenv 中二进制文件的门路。在这种状况下,咱们只有两次反复,然而在更简单的状况下,您须要一遍又一遍。

除了不足可读性之外,反复也是谬误的本源。当您向 Python 程序增加更多调用时,很容易遗记增加魔术 /opt/venv/bin/ 前缀。

它将(大部分)工作:

FROM python:3.8-slim-buster

RUN python3 -m venv /opt/venv

# Install dependencies:
COPY requirements.txt .
RUN /opt/venv/bin/pip install -r requirements.txt

# Run the application:
COPY myapp.py .
CMD ["/opt/venv/bin/python", "myapp.py"]

惟一须要留神的是,如果任何 Python 过程启动了子过程,则该子过程将_不会_在 virtualenv 中运行。

齐全无效的反复办法

您能够通过别离别离独自激活 virtualenv RUN和:来解决此问题CMD

FROM python:3.8-slim-buster

RUN python3 -m venv /opt/venv

# Install dependencies:
COPY requirements.txt .
RUN . /opt/venv/bin/activate && pip install -r requirements.txt

# Run the application:
COPY myapp.py .
CMD . /opt/venv/bin/activate && exec python myapp.py

(在 exec 那里能够失去正确的信号处理。)

优雅的办法,咱们能够学习激活的理论作用

人们很容易将其设想 activate 为某种神秘的魔术,一种被鲜血吸引住的五芒星,以使 Python 平安地被困住。但这只是软件,而且是相当简略的软件。virtualenv 文档甚至会告诉您activate“相对不便”。

如果您去浏览的代码activate,它将执行许多操作:

  1. 它能够弄清楚您正在运行什么 shell。
  2. 它将 deactivate 性能增加到您的 shell 中,并与混同pydoc
  3. 它将 shell 提醒更改为包含 virtualenv 名称。
  4. PYTHONHOME如果有人碰巧设置了环境变量,它将勾销设置环境变量。
  5. 它设置了两个环境变量:VIRTUAL_ENVPATH

前四个基本上与 Docker 的应用无关,因而只剩下最初一个。大多数时候 VIRTUAL_ENV 没有作用,然而某些工具(例如 poetry 打包工具)应用它来检测您是否在 virtualenv 中运行。

最重要的局部是设置 PATHPATH 是要搜寻要运行的命令的目录列表。activate只需将 virtualenv 的 bin/ 目录增加到列表的结尾。

咱们能够 activate 通过设置适当的环境变量来代替:Docker 的 ENV 命令将后续 RUN 以及都利用于CMD

后果是以下 Dockerfile:

FROM python:3.8-slim-buster

ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

# Install dependencies:
COPY requirements.txt .
RUN pip install -r requirements.txt

# Run the application:
COPY myapp.py .
CMD ["python", "myapp.py"]

当初,virtualenv 能够主动为 RUN 和两者应用CMD,而无需反复或无需记住任何内容。

软件不是魔术

事件就在这里:一个与原始的原始版本一样简略的版本,但实际上做对了。无反复,谬误范畴更小。

当某些货色看起来不必要地简单时,请深入研究并弄清楚它是如何工作的。您应用的软件可能比您设想的更简略(或更简略),并且只需破费大量工作便能够提供更优雅的解决方案。


 ____________________________________
/ You may be gone tomorrow, but that \
| doesn't mean that you weren't here |
\ today.     edited by Yujiaao       /
 ------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

© 2020 Hyphenated Enterprises LLC. All rights reserved.

正文完
 0