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