Nginx + Gunicorn 部署 Django 項目

只是簡單地記錄了一下一個非常 low 的部署方法,沒有任何的 CI/CD,這部分內容日後更新:

Clone 項目 & 安裝環境

在 GitHub 上設置好 Deploy Key 之後即可在服務器上 Clone 下自己的倉庫,並且在項目內創建 Virtualenv:

python -m venv env

進入了 env 之後,就是安裝本地需要的庫啦:

pip3 install -r requirements.txt

由於使用了消息隊列 Celery,還需要安裝 redis 等,也就是一些 apt 的事情。

一切搞定之後就使用 Gunicorn 啓動(臨時解決方案是放在 screen 中跑,長期解決方案是 systemd),在項目目錄下:

gunicorn <project_name>.wsgi

當然,一個稍微好一點的方式是把 Gunicorn 放在 systemd 中運行,可以通過在 /etc/systemd/system/ 下創建一個 gunicorn.service ,文件內容如下:

[Unit]
Description = Django Gunicorn
After = network.target

[Service]
User = ubuntu
Group = ubuntu
WorkingDirectory = /var/www/project_name
ExecStart = /var/www/project_name/env/bin/gunicorn --access-logfile - --workers 3 project_name.wsgi

[Install]
WantedBy = multi-user.target

然後就可以通過 systemctl start|stop|enable gunicorn 來搞定啦,Yey!

準備 Django 文件

由於 Django 默認 Static 文件是丟的到處都是的,且 Django 的設計理念就是不讓 Django (而是 Nginx)來輸出靜態文件,所以我們需要把所有的靜態文件丟到一個地方之後讓 Nginx 來搞定,我們先指定 Static 文件放在哪兒,於我的話,我打算放在 project_name/static/ 目錄下,所以在 settings.py 中有如下寫法:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'

PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')

然後讓 Django 把靜態文件移動一下,指令如下:

python manage.py collectstatic

反向代理

之後 Nginx 反向代理,需要注意的是,如果沒有 proxy_set_header X-Forwarded-Proto $scheme; 的話,會出現 CSRF 的問題,具體原因有待深究。

server {
        listen 80;
        server_name project_name.nova.moe;
        location / {
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_pass http://127.0.0.1:8000;
        }
            location /static/ {
                root /var/project_name/project_name;
            }
}