跨过Nginx上基于uWSGI部署Django项目的坑
先说说他们的关系,Nginx和uWSGI都是Web服务器,Nginx负责静态内容,uWSGI负责Python这样的动态内容,二者配合共同提供Web服务以实现提高效率和负载均衡等目的。uWSGI实现了多个协议,如WSGI,HTTP协议,还有它自己的uwsgi协议,想了解更多关于uWSGI和uwsgi协议内容可以查阅这里。这样和fastcgi类似,请求和响应的流程如下:
Request > Nginx > uWSGI > Django > uWSGI > Nginx > Response
请求先交由Nginx,如果是静态内容就自己处理了,如果是动态内容就交给uWSGI服务器,uWSGI服务器处理整个Django项目的Python代码,响应请求,原路返回,但是与fastcgi不同,Nginx、uWSGI和Django可以独立部署,然后整合。那么我们从Django开始,这里的服务器环境是Ubuntu 16.10。
1. 部署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服务器
通过pip安装uWSGI。
pip3 install uwsgi
测试uWSGI是否正常,在~/work/project/pro目录中创建一个测试用的Python文件uwsgi_test.py
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来处理静态内容。
跨过Nginx上基于uWSGI部署Django项目的坑的更多相关文章
- nginx 基于uwsgi部署Django
1.安装nginx yum install -y nginx(需要epel源) 2.安装环境 可以考虑使用虚拟化环境,本处不再使用 3.安装uwsgi yum groupinstall "D ...
- nginx基于uwsgi部署Django
1.安装nginx yum install -y nginx(需要epel源) 2.安装uwsgi yum groupinstall "Development tools" yum ...
- Nginx + uWSGI 部署Django 项目,并实现负载均衡
一.uWSGI服务器 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI ...
- 填坑!!!virtualenv 中 nginx + uwsgi 部署 django
一.为什么会有这篇文章 第一次接触 uwsgi 和 nginx ,这个环境搭建,踩了太多坑,现在记录下来,让后来者少走弯路. 本来在 Ubuntu14.04 上 搭建好了环境,然后到 centos7. ...
- nginx + uwsgi 部署 Django+Vue项目
nginx + uwsgi 部署 Django+Vue项目 windows 本地 DNS 解析 文件路径 C:\Windows\System32\drivers\etc 单机本地测试运行方式,调用dj ...
- Python3.6+nginx+uwsgi部署Django程序到阿里云Ubuntu16.04系统
Python3.6+nginx+uwsgi部署Django程序到阿里云Ubuntu16.04系统 这个是写好的Django程序在本地机运行的情况,一个查询接口. 准备工作 1.首先购买一台阿里云的EC ...
- nginx + uwsgi 部署django项目
因项目需求,需要部署django项目,这里是基础的nginx配合uwsgi部署django,后续会采用docker部署的方式 环境: centos7 python3.5.4 django2.1.4 u ...
- 云服务器上利用Docker部署Django项目
转载别人的,请看下面链接 云服务器上利用Docker部署Django项目
- Django项目的ORM操作之--数据模型类创建
在django项目中,其自带了ORM(Object Relation Mapping)对象关系映射框架,我们在django项目下app的models模块下对类进行操作,通过ORM会将我们对类的操作转化 ...
随机推荐
- Solr5.2.1+Zookeeper3.4.8分布式集群搭建
1.选取三台服务器 由于机器比较少,现将zookeeper和solr都部署在以下三台机器上.(以下操作都是在172.16.20.101主节点上进行的哦) 172.16.20.101 主节点 172.1 ...
- 单发邮箱 群发邮箱 程序 Email winform
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- java学习笔记 --- 条件,循环语句
一.三元运算符 A:格式 比较表达式?表达式1:表达式2; B:执行流程: 首先计算比较表达式的值,看是true还是false. 如果是true,表达式1就是结果. 如果是 ...
- Hibernate的映射文件中基于主键的双向1对1的关联
1.Hibernate中采用基于主键的映射策略是,有一端(任意一端)的主键生成策略要是foreign,根据对方的主键来生成自己的主键,它的实体不能拥有自己的主键生成策略,如我的配置文件: <?x ...
- flex中过滤掉字符串的空格
1.先引入import mx.utils.StringUtil;这个包, 在使用StringUtil.trim(); 如:if(StringUtil.trim(this.d1.3.text) ==&q ...
- iOS开发之layoutSubviews
当发生下面两种情况该方法会被调用: (1)一个控件的frame发生改变的时候. (2)布局子控件的时候 一般在这里布局内部的子控件(设置子控件的frame) 例如: - (void)layoutSub ...
- CSS与HTML5响应式图片
随着 Retina 屏幕的逐渐普及,网页中对图片的适配要求也越来越高.如何让图片在放大了两倍的 Retina 屏幕显示依然清晰,曾经一度困扰着网页开发者,好在 CSS3 与 HTML5 已经着力在改变 ...
- git 入门宝典
本篇教程是按照我自己的组织方式,然后从多篇教程中拼凑出来的,嘎嘎~,真佩服自己的技术! 原本想叫 git 宝典的,结果一查git的命令大全,还有那么多的git命令与功能没有接触到,所以...还是谦虚一 ...
- Android -- 自定义ViewGroup+贝塞尔+属性动画实现仿QQ点赞效果
1,昨天我们写了篇简单的贝塞尔曲线的应用,今天和大家一起写一个QQ名片上常用的给别人点赞的效果,实现效果图如下: 红心的图片比较丑,见谅见谅(哈哈哈哈哈哈).... 2,实现的思路和原理 从上面的效果 ...
- Android -- onMeasure()源码分析
1,作为自定义控件最重要的三个方法之一,onMeasure()可以说是我们研究的重点,今天我们更详细的来研究一下View的onMeasure()方法和ViewGroup的onMeasure()方法 2 ...