Docker容器

优雅地激活Dockerfile中的virtualenv

本文主要是介绍优雅地激活Dockerfile中的virtualenv,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

由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.

这篇关于优雅地激活Dockerfile中的virtualenv的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!