介紹
今天在使用 docker 部署 web 項目的時候遇到一個很詭異的問題,再此記錄下這次解決問題的過程,梳理一下思路。首先這個項目主要由 nginx + gunicorn + Django 來部署的,其中 gunicorn 用來啟動 Django,并且綁定 socket 文件,nginx 監聽端口并反向代理到后端 socket。至于為什么沒有直接使用 gunicorn 監聽某個端口,而是選擇綁定某個 socket 文件原因如下:
- gunicorn, Django 不處理靜態文件,由 nginx 來處理靜態資源,那我我只能通過反向代理的方式使得 nginx 可以正確的處理靜態資源(原因:nginx 和 gunicorn 不能同時綁定同一個端口),這一下占了我的倆個端口。
- socket 傳輸的效率明顯高于網絡端口之間的傳輸效率。一個是網絡層面,一個直接文件系統層面,快慢立馬看出來。
具體配置如圖示:
8348900A-29B1-47FE-A4F7-798E4BC66AC8.png
使用 gunicorn 啟動命令如下:
gunicorn --bind=unix:/tmp/mail.sock --workers=4 -u root -g root --log-file error.log wsgi:application
這其中需要注意的幾點:
- gunicorn 命令必須指定用戶,用戶組,因為我們在 docker 里面 root 用戶,所以必須指定,我一開始就沒有指定,所以報錯。
- --bind 參數一定不要忘了 unix:前綴,我看很多人經常忘了添加這個協議前綴,所以就會報錯。
- 記住在啟動面前一定不要事先創建/tmp/mail.sock這個文件,然后還傻乎乎的賦予該文件777權限,結果你懂的,試一試就知道。
坑來了
一切看上去都挺好,由于我一直在 docker 內部操作,一切看上去完事了,準備 commit,提交鏡像了。結果到另一臺機器pull鏡像鏡像啟動應用,報錯了: