優雅地激活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.

相關文章
相關標籤/搜索