使用Docker部署Python應用的一些經驗總結

2021-10-10 16:39:51 字數 2743 閱讀 5776

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

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

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

按照上面的思路(利用快取)來推斷,檔案新增到容器的順序至關重要。我們應該把頻繁變更的檔案放置到dockerfile的下方,以便充分使用快取來加速docker的構建過程。例如,應用配置、系統配置和依賴都很少改變,我們就可以把它們放到dockerfile的頂部。而原始檔,比如路由檔案、檢視(views)和資料庫**會經常發生改變,所以我們就可以把它們放在dockerfile的下方,注意是docker配置命令(expose、env等)的下方。

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

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

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

啟動gunicorn很簡單:

# 安裝

pip3 install gunicorn

# 執行伺服器

最後是在nginx後面執行你的應用伺服器,這樣你可以進行負載均衡。

你是不是想過在容器中執行多個程序?我想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,我們視為啟動成功

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 使用Docker部署Node服務

docker 是乙個開源的容器引擎。開發者可以將自己的應用以及依賴打包為乙個可移植的容器,然後發布到 linux 機器上。它類似於乙個輕量級的虛擬機器,極大地方便了使用者在伺服器端部署和管理應用環境。apt install docker.io安裝成功後檢視docker版本 建立package.jso...

使用Docker部署Gitlab

由於公司的 伺服器已使用gitosis搭建,但由於使用者和許可權管理太麻煩,現在想在原有伺服器上再搭建gitlab,使用gitlab官方方法直接安裝,會導致與gitosis衝突,使得gitosis不可用,因為要保持兩個服務同時存在,所以就想到利用docker來搭建gitlab。以下以ubuntu 1...

使用docker部署gitlab

docker build t lemonbar gitlab 注意此處的 不是句號,是代表dockerfile所在的路徑,代表當前路徑。t是build出來的image的名字。docker push lemonbar gitlab 可以通過push命令,來把自己的image上傳到public regi...