Nginx+uWSGI部署Django

本文基于ubuntu16.04系统

看django官方网站有好几种部署方式,这里选择Nginx+uWSGI的方式。

原理

nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是NGINX的强项)。然后,NGINX将所有非静态请求通过uwsgi传递给Django,由Django来进行处理,从而完成一次WEB请求。

http_server_structure

准备

首先安装Nginx、uWSGI感觉都不用说了。

需要注意的是,我使用virtualenv安装的uWSGI,所以下面执行uWSGI命令的时候需要先激活虚拟环境。

uwsgi测试

安装完uWSGI可以测试一下,写一个py文件(test.py),内容:

1
2
3
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return "Hello World"

再执行命令

uwsgi --http :8001 --wsgi-file test.py

然后访问网页:

http://127.0.0.1:8001/

可以看到浏览器显示了Hello World

也就是说,其实没有nginx也是可以完成这个流程的。

uwsgi配置

保证你的django项目可以直接跑起来,项目的结构大概是这样的:

django项目

我们可以测试一下直接用uWSGI跑django项目:

uwsgi --http :8001 --chdir /home/work/testdjango/mysite --module django_wsgi

项目的路径是:/home/work/testdjango/mysite,如果你使用了virtualenv的话可能还需要指定python的路径,这个命令其实…我跑完是打开不了网页,可能有配置有问题…

我们假设刚才的命令可以让django应用在uWSGI上跑起来了^_^,那么每次执行一下命令其实还是有点复杂的,而且如果需要配置的参数太多也不方便,所以我们要用配置文件的方式去跑uWSGI。
那么我们在django项目根目录下创建一个ini文件:tttimeline_uwsgi.ini(文件名随便起,类型是ini就行)
配置内容如下:

1
2
3
4
5
6
7
8
9
[uwsgi]
socket = :8077
chdir = /home/kyntu/Dev/workspace/pythonws/TTTimelineWebsite/tttimeline
module = tttimeline.wsgi
master = True
vacuum = True
max-requests = 5000
daemonize = /var/log/uwsgi/tttimeline_uwsgi.log
pythonpath = /home/kyntu/Dev/Python/virtualenvs/tttimelineenv/bin
  • socket是uWSGI的端口,一会儿nginx需要指定这个端口来连接uWSGI的
  • chdir就是项目的路径
  • module是项目中的wsgi文件,这个文件应该是django初始化的时候就会帮你生成的
  • master似乎是可以让uWSGI在主进程的,具体我也不清楚
  • daemonize比较重要,因为你可以查看这个log来了解uWSGI到底有没有跑起来,出现了什么警告或者error,这个路径如果没有的话自己创建一下吧
  • pythonpath是因为我使用了virtualenv才需要指定一下虚拟环境的python的路径,否则应该是会找不到uwsgi的(但是因为我执行uwsgi命令就在这个虚拟环境下执行的…所以也可能找得到…没试过…)

配置nginx

安装好nginx之后ubuntu的etc/nginx路径下的文件结构大概是这样的:

nginx配置结构

nginx.conf文件是主要的配置文件,我们可以看到里面有这么两行:

1
2
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

所以!!!千万不要像网上的一些教程一样在这里面直接配置,而是应该在conf.d文件夹下自己创建conf文件去配置,我感觉这样应该会比较好一点。另外,sites-enabled和sites-available文件夹下的default大概就是默认的配置文件,应该是会被其他配置文件覆盖的。

我们可以先修改一下默认的配置文件,修改默认的端口打开sites-enabled或sites-available下的default,注意,这两个目录下的default文件似乎是同一个文件,修改其中一个另一个就会变了,所以我们随便打开哪个就可以,修改端口为8089:

1
2
listen 8089 default_server;
listen [::]:8089 default_server;

这时候我们把nginx跑起来,浏览器打开http://127.0.0.1:8089/应该可以看到nginx的欢迎页面。

nginx的几个常用命令:
service nginx start
service nginx stop
service nginx reload

接下来配置一下项目的nginx参数,在conf.d文件夹下自己创建tttimeline.conf文件,内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 8089;
server_name 127.0.0.1;
charset UTF-8;
access_log /var/log/nginx/tttimeline_access.log;
error_log /var/log/nginx/tttimeline_error.log;
root /var/www/html;
index index.html;

location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8077;
}
}
  • listen就是配置端口,让nginx监听这个端口,我们就可以通过这个端口访问web服务了
  • server_name暂时用本机地址,应该是要用你的域名的
  • access_log和error_log最好指定一下,因为出了问题可以看下log,root不知道干嘛用的
  • index大概就是配置一下访问index的时候返回的文件吧
  • location比较重要,指定了nginx转发请求给uWSGI的配置,include uwsgi_params一定要写,uwsgi_pass就是刚才uWSGI的地址和端口。

不要混淆了,这里一共两个端口,一个是uWSGI的端口:8077,一个是nginx前端的端口:8089,用户通过8089端口来访问web服务。

另外,default的location节点下面有一个try_files $uri $uri/ =404;的配置,这个千万不要在我们的配置文件中写,否则访问什么url都是404…

到这里我们配置文件都弄好了,其实回过头看看也没多少,不过搞错一点真是很头疼的,你需要会看一些错误日志,像我之前uWSG配置语法错了,看了下daemonize = /var/log/uwsgi/tttimeline_uwsgi.log的日志文件就有这个错误定位。另外命令行也会有一些错误或者告诉你执行X命令可以see detail。

我们现在重新开始跑一下:

先看下8077端口有没有进程在跑

lsof -i :8077

有的话kill掉(sudo kill -9 + pid)

sudo kill -9 12494 12497

关闭nginx服务

service nginx stop

再打开

service nginx start

或者直接reload

service nginx reload

然后在虚拟python环境下跑uWSGI

uwsgi --ini tttimeline_uwsgi.ini

如果想看看uWSGI的运行结果,可以查看/var/log/uwsgi/tttimeline_uwsgi.log,看看有没有地方报错的,正常的情况如图:

uwsgi_log

这时候应该可以通过浏览器访问了http://127.0.0.1:8089/

还有,我用django做的restful api,所有没有静态文件,如果有静态文件,应该还要在nginx的配置文件中配置一下。

写完收工~

参考