Ubuntu系統Daphne + Nginx + supervisor部署Django項目

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常用命令:

  1. 啓動nginx: service nginx start
  2. 停止nginx:service nginx stop
  3. 重啓nginx:service nginx restart
  4. 重載配置文件:service nginx reload
  5. 查看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,重載如果不報錯,說明我們已經啓動成功!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章