Ubuntu系統Daphne + Nginx + supervisor部署Django項目
從Django 3.0開始支持ASGI應用程序運行,使Django完全具有異步功能。
Django打算在可預見的未來支持這兩者。但是,異步功能將僅對在 ASGI 下運行的應用程序可用。
所以說,我們也需要適時的更新我們的技能,學會部署asgi異步服務器環境中部署django項目!
ubuntu安裝Nginx
sudo apt-get install nginx
檢查nginx是否安裝成功:
nginx -v
查看nginx的版本,如果正確顯示格式如這樣nginx version: nginx/1.18.0 (Ubuntu)
,那麼證明安裝成功!
nginx常用命令:
- 啓動nginx:
service nginx start
- 停止nginx:
service nginx stop
- 重啓nginx:
service nginx restart
- 重載配置文件:
service nginx reload
- 查看nginx狀態:
service nginx status
克隆已經開發好的django項目
把我們已經開發好的django-blog博客項目從線上倉庫可克隆到Nginx的項目文件,建立虛擬環境,安裝項目依賴,創建數據庫,同步數據,開發環境調試項目可正常運轉後開始部署!
部署
一、虛擬環境中安裝Daphne
Daphne是一個純Python編寫的應用於UNIX環境的由Django項目維護的ASGI服務器。它扮演着ASGI參考服務器的角色。
你可以通過 pip 來安裝 Daphne,該命令需要在激活虛擬環境的情況下運行
python -m pip install daphne
在 Daphne 中運行 Django
一旦 Daphne 安裝完畢,你就可以使用 daphne 命令了,它將用來啓動 Daphne 服務進程。在最簡單的情形下,Daphne 加上包含一個 ASGI 應用模塊的位置和應用的名稱(以冒號分隔)。
對於一個典型的 Django 項目,可以像下面這樣來啓動 Daphne
daphne myproject.asgi:application
它將開啓一個進程,監聽 127.0.0.1:8000
。這需要你的項目位於 Python path 上。爲了確保這點,你應該在與 manage.py
文件相同的路徑中運行這個命令。
二、虛擬環境中安裝supervisor
Supervisor是用Python開發的一套通用的進程管理程序,能將一個普通的命令行進程變爲後臺daemon,並監控進程狀態,異常退出時能自動重啓。它是通過fork/exec的方式把這些被管理的進程當作supervisor的子進程來啓動,這樣只要在supervisor的配置文件中,把要管理的進程的可執行文件的路徑寫進去即可。也實現當子進程掛掉的時候,父進程可以準確獲取子進程掛掉的信息的,可以選擇是否自己啓動和報警。supervisor還提供了一個功能,可以爲supervisord或者每個子進程,設置一個非root的user,這個user就可以管理它對應的進程。
1. 安裝supervisor 的方式
安裝supervisor的方式非常多,最簡便的就是以下兩種,直接安裝在整個系統當中或者安裝在python項目的虛擬環境當中!
# 直接安裝在系統當中,整個環境中都有
sudo apt-get install supervisor
# 可以在虛擬環境中通過pip安裝
pip3 install supervisor
2. 生成配置文件
echo_supervisord_conf > /etc/supervisord.conf
備註:在任意文件夾下運行該命令,如果後邊未指定存放配置文件的路徑,而是單純的指定了supervisord.conf的配置文件名,那麼他會在當前文件夾下生成默認配置!
修改配置文件supervisord.conf,在最後一行增加
[include]
files = supervisord.d/*.ini
備註:files的路徑可自行指定,不是必須非要存放在這裏!
3. 創建配置文件
在files指定的目錄下創建一個asgi.ini
的文件,用來設置項目的配置信息
[fcgi-program:asgi]
# TCP socket used by Nginx backend upstream
socket=tcp://0.0.0.0:8000
# 項目文件所在目錄
directory=/home/qbc/webproject/django-blog
# 每個進程需要有一個單獨的socket文件,所以我們使用process_num
# 確保更新“mysite.asgi”以匹配您的項目名稱
command=daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers mysite.asgi:application
# 要啓動的進程數,大致爲您擁有的 CPU 數
numprocs=4
# 給每個進程一個唯一的名稱,以便它們可以被區分
process_name=asgi%(process_num)d
# 自動啓動和恢復進程
autostart=true
autorestart=true
# 選擇您希望日誌存放的位置
stdout_logfile=/home/qbc/webproject/django-blog/deploy/asgi.log
redirect_stderr=true
4. 啓動supervisor
supervisord -c /etc/supervisord.conf
備註:-c後邊的路徑爲存放第二步生成的配置文件目錄
錯誤甄別及處理:
錯誤1:
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.
For help, use /usr/bin/supervisord -h
如果啓動項目發生如上錯誤提示,說明supervisor進程已經啓動了,端口被佔用,我們可以運行以下命令,查看與supervisord有關的所有進程
ps -ef | grep supervisord
輸出如下:
root 3652 1 0 08:26 ? 00:00:00 /usr/bin/python3 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
root 6365 1 0 08:42 ? 00:00:00 /usr/bin/python3 /usr/bin/supervisord -c /etc/supervisord.conf
root 7201 4201 0 08:48 pts/1 00:00:00 grep --color=auto supervisord
殺死supervisord的進程即可
kill -s SIGTERM 3652
殺死之後重新啓動supervisord,運行啓動命令,不出意外就可以成功了!
通過supervisorctl命令查看進程狀態
asgi:asgi0 RUNNING pid 61400, uptime 0:26:15
asgi:asgi1 RUNNING pid 61401, uptime 0:26:15
asgi:asgi2 RUNNING pid 61402, uptime 0:26:15
asgi:asgi3 RUNNING pid 61403, uptime 0:26:15
如果狀態均爲RUNNING說明成功,否則可去看看我們配置得日誌文件提示的錯誤原因!
三、創建項目的Nginx配置文件
進入:cd /etc/nginx/sites-enabled
創建:touch asgi
用vim編輯打開剛纔創建的asgi
文件,將下邊的內容填寫進去,具體參考註釋說明:
有負載均衡的配置:
upstream asgi {
server 127.0.0.1:8001; # 轉發到服務器
}
server {
listen 80;
server_name 192.168.174.128;
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# location 配置請求靜態文件多媒體文件。
location /media {
alias /www/wwwroot/django-blog/media/;
}
# 靜態文件訪問的url
location /static {
# 指定靜態文件存放的目錄
alias /www/wwwroot/django-blog/static/;
}
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_pass http://0.0.0.0:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
無負載均衡的配置
server {
listen 80;
server_name example.com #i just want to hide domain name..
charset utf-8;
client_max_body_size 20M;
# location 配置請求靜態文件多媒體文件。
location /media {
alias /www/wwwroot/django-blog/media/;
}
# 靜態文件訪問的url
location /static {
# 指定靜態文件存放的目錄
alias /www/wwwroot/django-blog/static/;
}
location / {
proxy_pass http://0.0.0.0:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
重載nginx配置文件:service nginx reload,重載如果不報錯,說明我們已經啓動成功!