使用 uWSGI 和 Nginx 部署 Django 項目

前言

本文只介紹部署
首先須要有一個已經可用的 Django 項目。html

操做環境 Ubuntu。node

uWSGI 的安裝配置

安裝

pip install uwsgi
複製代碼

Debian 及衍生系統,如 Ubuntu,須要先安裝 python-devpython3-dev。不然不能正常安裝 uwsgi。python

使用 uWSGI 在 8000 端口運行 Django 項目:nginx

uwsgi --http 127.0.0.1:8000 --chdir /path/to/project/ --wsgi-file /path/to/wsgi.py
複製代碼

根據 uWSGI 文檔,爲了正確加載模塊,必須添加 chdir 選項。git

而實際上,chdir 選項的做用是切換到該目錄,見《uwsgi 經常使用參數說明》
因此若是全部的配置都使用完整路徑的話,就不須要 chdir 了。github

配置項

  • --processes 啓用的進程數,默認1
  • --threads 每一個進程的線程數,默認1
  • --stats 設置一個地址,能夠經過該地址監控運行狀態,輸出 JSON 格式的數據

關於 --statsdjango

  • 由於是一個地址,因此可使用 telnetcurl 查看。或者使用官方提供的工具 uwsgitop,最後一部分會簡單介紹一下。

示例:安全

uwsgi --http 127.0.0.1:8000 --chdir /path/to/project/ --wsgi-file /path/to/wsgi.py --processes 4 --threads 2 --stats 127.0.0.1:8080
複製代碼

上面的命令在 8000 端口啓動了一個 uWSGI 實例,產生4個進程,每一個進程2個線程,並能夠在 127.0.0.1:8080 查看運行狀態。bash

命令行參數寫爲配置文件

顯然上面的命令有點長了。能夠把配置寫在配置文件裏,執行時只須要一個配置文件作參數:服務器

# conf.ini
[uwsgi]
http = 127.0.0.1:8000
chdir = /path/to/project/
wsgi-file = /path/to/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:8080
複製代碼

考慮到安全性,uWSGI 文檔中提到,不要使用 root 權限來運行 uWSGI,添加 uidgid 選項指定用戶和組。

使用配置文件運行:

uwsgi conf.ini
複製代碼

如今項目已經經過 uWSGI 運行在 8000 端口了。

注意:
http 選項的參數能夠只是一個端口,好比 :8000,不過效果等於 0.0.0.0:8000
因此最好完整地寫爲 127.0.0.1:8000,讓項目只運行在本地,而後反向代理出去。

中止和重啓

通常會設置多個進程,那麼能夠在配置文件中添加 master 選項:

master = true
複製代碼

這樣一來,除了配置中設置的進程數,還將另外啓動一個 master 進程,用來管理其餘進程。

這時,

  • kill master 進程的 pid,master 將自動重啓
  • kill uWSGI 的其餘進程,master 將自動從新啓動一個進程

可使用 killall 退出 uWSGI,參考 StackOverflow 上的這個問題
能夠,可是沒有必要。

爲了更優雅地操做 uWSGI,再添加 safe-pidfile 選項,使用 pidfile 來操做 uWSGI:

safe-pidfile = /path/to/uwsgi-master.pid
複製代碼

safe-pidfile 會在指定的位置生成一個 pid 文件。

這時,

  • 中止 uWSGI:uwsgi --stop /path/to/uwsgi-master.pid
  • 重啓 uWSGI:uwsgi --reload /path/to/uwsgi-master.pid

詳細內容見管理 uWSGI 服務器 - uWSGI 文檔

我的感受 --reload 常常沒效果,不少時候 --stop 後再啓動才行。

配置 Nginx

這裏只給出一個最簡單的配置:

server{
  listen 80;
  # 若是有域名
  server_name example.com;

  location / {
    proxy_pass http://127.0.0.1:8000;
    include uwsgi_params;
  }
  ...
}
複製代碼

uwsgi_params 文件在 /etc/nginx/ 目錄中。若是沒有,能夠從 GitHub 獲取。

使用 Unix Sockets

簡介

應該叫 Unix Domain Socket,不過 uWSGI 官方文檔寫的就是 Unix Sockets。

上面 uWSGI 經過 http 配置項使 Django 項目運行在 http://127.0.0.1:8000,所以 Nginx 中須要使用 proxy_pass 對這個地址進行反向代理。這是使用 TCP Socket 的運行方式。

下面將修改成使用 Unix Sockets 的方式,好處是開銷低,效率高。

關於 TCP Socket 和 Unix Sockets 更具體一些的區別,能夠看一下這篇文章:《Node.js HTTP Server 監聽 Unix Socket 套接字》

一個比較直觀的表現是:

  • 使用 http 選項運行 uWSGI 時,若是使用 uWSGI 的 pid 來查看它所佔用的端口,是能夠查到的
  • 使用 socket 選項運行,而且值設置爲 sock 文件時(見下文),使用 uWSGI 的 pid 來查看它所佔用的端口,是查不到的,由於不走 TCP

下面看一下怎麼改。

修改 uWSGI 配置

刪除 http選項,添加 socket 選項,並設置一個 sock 文件的路徑,運行 uWSGI 後會生成該 sock 文件。
生成的 sock 文件可能會缺乏執行權限,能夠經過設置 chmod-socket = 666 解決。

關於 Linux 中的權限,能夠看這篇文章:《檔案權限》

socket 選項能夠設置兩種類型的值:

  • sock 文件
  • IP 地址,即原來 http 選項的值

例以下面的配置:

[uwsgi]
socket = /path/to/sock.sock
chmod-socket = 666
...
複製代碼

修改 Nginx 配置

uWSGI 改成使用 socket 後:
socket 設置爲 IP 時,只要把原 Nginx 配置中的 proxy_pass 改爲 uwsgi_pass 便可。
socket 設置爲 sock 文件時,須要把 proxy_pass 改成:

location / {
  uwsgi_pass unix:///path/to/sock.sock;
  ...
}
...
複製代碼

注意,有三條斜線,由 unix:///path/to/sock.sock 兩部分組成

使用 upstream

uWSGI 文檔中,Nginx 配置中使用了 uwsgi_passupstream

upstream django{
  server ...;
}
server{
  location /{
    uwsgi_pass django;
  }
  ...
}
複製代碼

至關於原本直接設置 uwsgi_pass 的值,如今改爲了先把值賦給變量 django,再把變量 django 設置到 uwsgi_pass 上。

使用 IP 地址時,下面兩個例子效果是同樣的:

# 使用upstream
upstream django{
  server 127.0.0.1:8000;
}
server {
  location / {
    uwsgi_pass django;
    ...
  }
}

# 不使用upstream
server {
  location / {
    uwsgi_pass 127.0.0.1:8000;
    ...
  }
}
複製代碼

使用 sock 文件時,下面兩個例子效果也是同樣的:

# 使用upstream
upstream django{
  server unix:///path/to/sock.sock;
}
server {
  location / {
    uwsgi_pass django;
    ...
  }
}

# 不使用upstream
server {
  location / {
    uwsgi_pass unix:///path/to/sock.sock;
    ...
  }
}
複製代碼

upstream 經常使用於須要作負載均衡的場景,一個 upstream 裏能夠配置多個 server。
就再也不詳細介紹了。

配置 SSL 證書

若是要配置 SSL 證書,只要修改 Nginx 的配置便可:

server{
  ssl_certificate      crt;
  ssl_certificate_key  key;
  ...
}
複製代碼

更詳細的配置能夠參考 StackOverflow 上的這個問題

可使用 Let's Encrypt 生成免費的 SSL 證書
欲知使用方法,請瘋狂點擊這篇文章:《你的網站還沒用上 HTTPS 嗎》

其餘

使用域名時

若是使用域名,記得把域名添加到 settings.pyALLOWED_HOSTS 中。

uWSGI 監控工具 uwsgitop

安裝:

pip install uwsgi
複製代碼

啓動:

uwsgi :port
複製代碼

退出:

  • Ctrl + C 主動退出
  • 當 uWSGI 進程結束時自動退出

參考連接

參考連接較多,再也不一一列出。

打個廣告

個人其餘文章:

《你的網站還沒用上 HTTPS 嗎》
《polipo/privoxy 實現 Linux 系統全局/自動代理》

相關文章
相關標籤/搜索