设为首页 收藏本站
查看: 1942|回复: 0

[经验分享] 跨过Nginx上基于uWSGI部署Django项目的坑

[复制链接]
发表于 2017-12-22 11:09:36 | 显示全部楼层 |阅读模式
  先说说他们的关系,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/wisesoe/.local/lib/python2.7/site-packages (python 2.7)  
www@cloud
-vm-ub01:~$ pip3 -V  
pip
9.0.1 from /home/wisesoe/.local/lib/python3.5/site-packages (python 3.5)  

  
pip3
install django  将已经完成开发的Django项目pro(pro是Django项目名)拷贝到服务器,这里拷贝到了www用户(www是服务器可登录用户名)路径下,最后相对路径是~/work/project/pro,绝对路径是/home/www/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  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/wisesoe/Work/Project/Python/duty/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来处理静态内容。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-426785-1-1.html 上篇帖子: Nginx 的两种认证方式 下篇帖子: 在nginx上面部署多个项目
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表