使用 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 系统全局/自动代理》

相关文章
相关标签/搜索