先说说他们的关系,Nginx和uWSGI都是Web服务器,Nginx负责静态内容,uWSGI负责Python这样的动态内容,两者配合共同提供Web服务以实现提升效率和负载均衡等目的。uWSGI实现了多个协议,如WSGI,HTTP协议,还有它本身的uwsgi协议,想了解更多关于uWSGI和uwsgi协议内容能够查阅这里。这样和fastcgi相似,请求和响应的流程以下:html
Request > Nginx > uWSGI > Django > uWSGI > Nginx > Responsepython
请求先交由Nginx,若是是静态内容就本身处理了,若是是动态内容就交给uWSGI服务器,uWSGI服务器处理整个Django项目的Python代码,响应请求,原路返回,可是与fastcgi不一样,Nginx、uWSGI和Django能够独立部署,而后整合。那么咱们从Django开始,这里的服务器环境是Ubuntu 16.10。nginx
1. 部署Django的项目django
安装Python和Django,Ubuntu自带2.7和3.5版本的Python,安装相应的Django版本,注意在Ubuntu中不一样版本Python都有相应的命令浏览器
www@cloud-vm-ub01:~$ python --version Python 2.7.12+ www@cloud-vm-ub01:~$ python3 --version Python 3.5.2+ www@cloud-vm-ub01:~$ pip -V pip 9.0.1 from /home/www/.local/lib/python2.7/site-packages (python 2.7) www@cloud-vm-ub01:~$ pip3 -V pip 9.0.1 from /home/www/.local/lib/python3.5/site-packages (python 3.5) pip3 install django
将已经完成开发的Django项目pro(pro是Django项目名)拷贝到服务器,这里拷贝到了www用户(www是服务器可登陆用户名)路径下,最后相对路径是~/work/project/pro,绝对路径是/home/www/work/project/pro服务器
进入以上目录,使用Django的内置服务器测试看看pro项目是否运行正常。网络
python3 ./manage.py runserver 127.0.0.1:8080
2. 部署uWSGI服务器app
经过pip安装uWSGI。负载均衡
pip3 install uwsgi
测试uWSGI是否正常,在~/work/project/pro目录中建立一个测试用的Python文件uwsgi_test.pysocket
def application(env, start_response): start_response('200 OK',[('Content-Type', 'text/html')]) #return ['Hello world'] # Python2 return [b'Hello world'] # Python3
在pro项目路径下,基于HTTP协议运行uWSGI,若是uWSGI安装正常的话,能够在浏览器中访问9090端口,看到Hello world字样
uwsgi --http 127.0.0.1:9090 --wsgi-file uwsgi_test.py
接下来启动uWSGI加载Django项目,这里依然使用HTTP协议,将指向具体Python文件--wsgi-file参数替换为指向Django项目的--module参数,参数的值pro.wsgi指向~/work/project/pro/pro/wsgi.py模块,若是正常能够在浏览器http://127.0.0.1:9090端口打开了项目,可是静态文件路径有问题,不过不要紧后面再处理。
www@cloud-vm-ub01:~/work/project/pro$ uwsgi --http 127.0.0.1:9090 --module pro.wsgi
对于uWSGI服务器的配置,如上命令加上不少参数很是麻烦,能够写成配置文件的方式,在~/work/project/pro中建立一个配置文件uwsgi.ini,注释掉参数暂时忽略,Django 1.4之前的版本须要配置如env,pythonpath等参数,这里再也不深究了。
其中http参数用于以上测试,而与Nginx交互须要使用socket参数,即便用TCP协议,WSGI和uwsgi协议都在TCP协议之上。socket参数也能够配置为网络地址,如socket=127.0.0.1:7070,但若是Nginx和uWSGI同在一个服务器上,可使用socket文件的形式。chmod-socket是为了动态配置socket文件的权限,由于socket文件会在每次uWSGI启动时被从新建立。
[uwsgi] http=127.0.0.1:8000 #socket=/home/www/work/project/pro/nginx_uwsgi.socket chdir=/home/www/work/project/pro/ #chmod-socket=664 master=true processes=4 threads=2 module=pro.wsgi #wsgi-file=uwsgi_test.py #stats=127.0.0.1:9000
经过下面命令一样能够启动uWSGI加载Djiango项目
uwsgi --ini uwsgi.ini
设置uwsgi为自启动,在Ubuntu 16. 10
3. 部署Nginx服务器
经过apt安装Nginx
sudo apt install nginx
Nginx能够经过如下命令控制。正常安装和启动Nginx后,经过http://127.0.0.1:80能够看到Nginx的欢迎页
sudo service nginx start sudo service nginx stop sudo service nginx restart
接下来修改配置Nginx配置与uWSGI服务器交互。Nginx的主要配置文件在/etc/nginx/nginx.conf和sites-enabled文件夹里,nginx.conf是全局设置,sites-enabled文件夹里的能够针对不一样站点进行配置,其中有个默认的default配置文件,该文件实际上是sites-available文件夹里的default文件的软连接,sites-avaliable像个仓库,但只有sites-enabled里的才有效。咱们能够将sites-enabled的default删除,再cp一份sites-available的default到sites-enabled里重名为nginx-pro,同时cp /etc/nginx/uwsgi_params ~/work/project/pro里以备nginx-pro配置文件调用。
#nginx-pro
upstream django{ server unix:///home/www/work/project/pro/nginx_uwsgi.sock; # file socket #server 127.0.0.1:7070; # TCP socket } server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name 127.0.0.1; # IP or FQDN location /static { alias /home/www/work/project/pro/static; } location / { uwsgi_pass django; include /home/www/work/project/pro/uwsgi_params; #try_files $uri $uri/ =404; } }
uwsgi_params文件是Nginx向uWSGI传递的参数,uwsgi_pass的意思动态内容请求都经过名为django的upstream传递给uWSGI,这使用文件socket的方式,那么与以前uwsgi.ini里的socket参数配置一致。
4. Nginx权限问题
以上所有配置完成了,可是还有一个重要的权限问题,若是启动uWSGI和Nginx(如下须要两个终端窗口,由于uwsgi命令会占据一个),会报错
uwsgi --ini uwsgi.ini sudo service nginx restart
在/var/log/nginx/error.log中会看到Permission denied字样,是对home/www/work/project/pro/nginx_uwsgi.socket文件没有读写权限,即运行Nginx工做进程的用户须要socket文件的读写权限。
运行Nginx的工做进程的用户在/etc/nginx/nginx.conf中有配置,是user的值www-data,但查看/etc/group发现www-data是个用户组
user www-data; worker_processes auto; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; }
咱们能够将www用户加入该用户组
usermod -G www-data www
也能够将socket文件及其上级目录pro的用户组改成www-data,并为该用户组授予读写权限
chown :www-data ~/home/work/project/pro chown :www-data ~/home/work/project/pro/nginx_uwsgi.socket chmod g+rw ~/home/work/project/pro/nginx_uwsgi.socket
5.Nginx和Django静态文件处理
Django项目能够正常打开,可是静态文件引用路径还有问题,在Django开发时Django本身能够正确处理静态文件的路径,可是部署后Nginx去没法找到静态文件路径。
检查Nginx配置文件夹sites-enabled里的nginx-pro文件,确保里面默认的try_files要删掉或者注释掉,不然Nginx会所以检查静态文件是否存在。
将Django的静态文件集中起来,Django为此有专门的工具
如今Django的Settings文件中加上StATIC_ROOT,把静态文件都集中到这个路径下
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
执行命令
python3 ./manage.py collectstatic
这样全部Django先后台的静态文件都会集中到项目文件夹pro下static中,另外nginx-pro其中一个配置location /static便可让Nginx来处理静态内容。