优雅地激活Dockerfile中的virtualenv

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

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

因为您正在使用virtualenv,所以须要激活它-可是,若是您只是开始使用 Dockerfile,那么幼稚的方法将不起做用。即便您确实知道该怎么作,一般的方法也是重复性的,所以容易出错。shell

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

注意:在所讨论的主题以外,本文中的Dockerfile并非最佳实践的示例,由于增长的复杂性将使本文的重点难以理解。所以,若是要使用Docker在生产环境中运行Python应用程序,能够采用如下两种方法来应用最佳实践:app

无效的方法

若是您只是将shell脚本盲目地转换为Dockerfile,则会获得看起来正确但实际上已损坏的内容:ide

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/前缀。ui

它将(大部分)工做:code

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.

相关文章
相关标签/搜索