使用Docker部署Python應用程式的方法總結

高洛峰
發布: 2017-03-23 16:10:27
原創
1742 人瀏覽過

本篇文章源自作者團隊在長期開發過程中總結的寶貴經驗,其中Supervisor、Gunicorn以及Nginx更是在使用Python開發Web應用時最常用的軟體,因此對於打算使用Docker部署Python應用的讀者而言,這些最佳實踐是很有參考價值。同時希望各位在日常實踐過程中,也能將各自踩過的「坑」以及寶貴的經驗分享出來,大家共同進步!

我們可以使用Docker簡單而有效率的部署Python應用,同時,也有一些最佳實踐來幫助我們愉快的完成部署。當然,也不是說這些最佳實踐就是完成部署的唯一方式,只不過我們團隊發現它們具有高可用性,並且容易維護。注意本文中大多數內容都只是代表我的立場,基於Docker的實作方式有很多,你可以隨便選擇。本文中我不會過多的介紹Volume,因為它可能需要一個單獨的話題來解釋。我們通常會使用Volume將原始程式碼複製到容器中,而不是在每次運行時都重新建置。

DEBIAN_FRONTEND

Docker使用者應該都很熟悉這個環境變量,它告知作業系統應該從哪裡獲得使用者輸入。如果設定為”noninteractive”,你就可以直接執行指令,而無需向使用者要求輸入(譯者註:所有操作都是非互動式的)。這在執行apt-get指令的時候格外有用,因為它會不停的提示使用者進行到了哪一步並且需要不斷確認。非互動模式會選擇預設的選項並以最快的速度完成建置。

請確保你只在Dockerfile中調用的RUN命令中設置了該選項,而不是使用ENV命令進行全局的設置,因為ENV命令在整個容器運行過程中都會生效,所以當你通過BASH和容器進行互動時,如果進行了全域設定那就會出問題。範例如下:

# 正确的做法 - 只为这个命令设置ENV变量
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3
# 错误地做法 - 为接下来的任何命令都设置ENV变量,包括正在运行地容器
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -y python3
登入後複製

requirements.txt

比相比基本的程式碼(codebase),應用程式的依賴很少發生變化,因此我們可以在Dockerfile中安裝專案依賴,這也可以加快之後的建置速度(之後的建置只需要建置變更的程式碼)。 Docker容器的層級建置可以快取依賴安裝的過程,所以之後的建置速度會非常快,因為它不需要重新下載和建置依賴。

檔案順序

依照上面的想法(利用快取)來推斷,檔案加入容器的順序至關重要。我們應該把頻繁變更的檔案放置到Dockerfile的下方,以便充分使用快取來加速Docker的建置流程。例如,應用程式配置、系統配置和依賴都很少改變,我們就可以把它們放到Dockerfile的頂部。而原始文件,例如路由文件、視圖(views)和資料庫程式碼會經常改變,所以我們就可以把它們放在Dockerfile的下方,注意是Docker設定指令(EXPOSE、ENV等)的下方。

另外,不要考慮如何將你的檔案拷貝到Docker,它不會加快你的建置速度,因為大多數的檔案根本不會用到,例如應用原始檔。

應用金鑰

之前我們一直不知道如何把應用程式金鑰安全的傳遞給應用,後來我們發現可以使用docker run指令中的 env-file參數。我們會把所有的金鑰和設定都放在app_config.list檔案中,然後透過這個檔案交付給應用程式。具體如下:

docker run -d -t -—env-file app_config.list <image:tag>
登入後複製

這個方法允許我們簡單地改變應用程式設定和金鑰,而無需重建一個容器。

注意:請務必確保app_config.list在.gitignore檔案的記錄中,不然它不會被檢錄到原始檔案中。

Gunicorn

我們使用Gunicorn作為容器內部的應用程式伺服器,Gunicorn非常的穩定且效能很好,它有非常多的配置選項,例如指定worker數量和類型(green threads、 gevent等)的能力,你可以根據負載來調整應用,以獲得最佳效能。

啟動Gunicorn很簡單:

# 安装
pip3 install gunicorn

# 运行服务器
gunicorn api:app -w 4 -b 127.0.0.1:5000
登入後複製

最後是在Nginx後面運行你的應用程式伺服器,這樣你可以進行負載平衡

supervisord

你是否想過在容器中執行多個進程?我想Supervisord絕對是你的最佳輔助工具。假設我們想要部署這樣一個容器,它包含Nginx反向代理程式以及Gunicorn應用程式。你透過BASH腳本可能就能實現,但讓我們想更簡潔一點。

Supevisor是「一個進程控制系統,它支援使用者在類別UNIX作業系統上,監視並控制一些進程」。聽起來很完美!你需要先在你的Docker容器內安裝Supervisor。

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y
supervisor
登入後複製

為了讓Supervisor知道該運行什麼以及如何管理進程,我們接下來需要為它寫一個設定檔。

[supervisord]
nodaemon = true  # 这个会让supervisord运行在前端

[program:nginx]  # 你想运行的第一个程序的命名
command = /usr/sbin/nginx  # nginx可执行程序的路径
startsecs = 5  # 如果nginx保持开启5s,我们视为启动成功

[program:app-gunicorn]
command = gunicorn api -w 4 -b 127.0.0.1:5000
startsecs = 5
登入後複製

這是非常基本的配置,它還有很多的配置項,例如控制日誌、stdout/stderr重定向、重新啟動策略等。這個工具真不錯。

一旦你完成了配置,請確保Docker將其複製到了容器中。

ADD supervisord.conf /etc/supervisord.conf
登入後複製

讓Supervisor作為容器的自啟動指令。

CMD supervisord -c /etc/supervisord.conf
登入後複製

它将会在容器启动的时候,运行Gunicorn和Nginx。如果已经配置过了,那将会按需重启它们。

学到的东西以及未来的目标

我们已经花了很长时间在Docker中部署代码,并且接下来会投入更多的时间。在使用Docker的过程中,我们学到的最重要经验就是如何最小化思考(think minimally)。在一个容器中运行你的整个系统真的很诱人,但是在应用各自的容器中运行应用进程却更容易维护。一般情况下,我们会在容器中运行Nignx和Web服务器,并且在一些场景中,使用单独的容器来运行Nginx却没有任何优势,它可能只会增加复杂度。我们发现对于大多数情况,它在容器中的开销是可接受的。

我希望这些信息对各位有价值!当我们团队学到更多最佳实践时,我会更新这篇文章。

以上是使用Docker部署Python應用程式的方法總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板