由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"]
它的中断有两个不一样的缘由:工具
RUN
Dockerfile中的每一行都是一个不一样的过程。activate
单独运行RUN
不会影响之后的RUN
通话。出于全部实际目的,这是无人操做的。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
,它将执行许多操做:
deactivate
功能添加到您的shell中,并与混淆pydoc
。PYTHONHOME
若是有人碰巧设置了环境变量,它将取消设置环境变量。VIRTUAL_ENV
和PATH
。前四个基本上与Docker的使用无关,所以只剩下最后一个。大多数时候VIRTUAL_ENV
没有做用,可是某些工具(例如poetry
打包工具)使用它来检测您是否在virtualenv中运行。
最重要的部分是设置PATH
:PATH
是要搜索要运行的命令的目录列表。 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.