uwsgi+nginx部署django项目
Posted silence_cho
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uwsgi+nginx部署django项目相关的知识,希望对你有一定的参考价值。
1. 概念解析(wsgi协议,uwsgi协议,uWSGI)
参考:https://www.cnblogs.com/wspblog/p/8575101.html
1.1 现实世界的web请求:
1.2 wsgi协议,uwsgi协议和uWSGI
a. WSGI(wsgi): 全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。
总结:WSGI(wsgi)只是一种规范,描述web server如何与web application通信的规范
b. uWSGI: uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。
c. uwsgi: 与WSGI一样是一种通信协议,但与WSGI协议是两种东西,uwsgi协议是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型的描述.
下图简单描述在web请求过程中三者的位置:
2. web请求流程
1,首先客户端请求服务资源,
2,nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析,如果是静态文件请求就根据nginx配置的静态文件目录,返回请求的资 源,如果是动态的请求,nginx就通过配置文件,将请求传递给uWSGI;
3,uWSGI 将接收到的包进行处理,并转发给wsgi, wsgi根据请求调用django工程的某个文件或函数,处理完后django将返回值交给wsgi,wsgi将返回值进行打包,转发给uWSGI, uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端(如浏览器)。
*注:不同的组件之间传递信息涉及到数据格式和协议的转换
整个流程如下图所示:
nginx的作用:
1. 第一级的nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程;
2. 在nginx上加上安全性或其他的限制,可以达到保护程序的作用;
3. uWSGI本身是内网接口,开启多个work和processes可能也不够用,而nginx可以代理多台uWSGI完成uWSGI的负载均衡;
4. django在debug=False下对静态文件的处理能力不是很好,而用nginx来处理更加高效。
3. 部署环境及准备
购买服务器(国外谷歌云,亚马逊aws;国内阿里云,腾讯云等),需安装:python,django,uwsgi、nginx、libmysqld-dev、mysql-server;
3.1. 安装和测试uWSGI
安装 sudo pip install uwsgi 测试: 新建test.py,内容如下 #/usr/bin/python def application(env, start_response): start_response(\'200 OK\', [(\'Content-Type\',\'text/html\')]) return "Hello World" 运行 uwsgi --http 0.0.0.0:8000 --wsgi-file test.py 浏览器访问 http://127.0.0.1:8000 页面出现Hello World,则安装成功
(问题:若8000端口被占用,换其他端口; uwsgi找不到命令,建立软连接 sudo ln -s /your-python-dir/bin/uwsgi /usr/bin/uwsgi)
3.2 安装和测试nginx
安装:sudo yum install nginx
启动:sudo nginx (ps -aux| grep nginx 查看nginx进程)
测试:浏览器访问http://127.0.0.1:80 (命令行 curl http://127.0.0.1:80),返回nginx则运行正常
其他nigix命令:
启动:nginx
退出或重启:nginx -s stop(quit, reload)
命令帮助: nginx -h
验证配置文件 nginx -t
3.3 建立django 项目和测试
创建项目:django-admin.py startproject notebook (找不到命令时 :/usr/local/python-3.5.2/bin/django-admin.py startproject notebook)
创建app:python manage.py startapp planlist (并在settings.py文件的INSTALLED_APPS中添加planlist.apps.PlanlistConfig)
运行测试: python manage.py runserver 127.0.0.1:8000 (浏览器打开http://127.0.0.1:8000, 出现django页面,项目创建成功)
3.4 uWSGI运行django项目测试
关闭上述django项目后,运行命令:uwsgi --http :8000 --module notebook.wsgi
(notebook为django项目名称,创建django项目时notebook文件夹下自动创建wsgi.py文件)
测试:在浏览器访问http://127.0.0.1:8000,出现django页面,表示web-client <-> uWSGI <-> Django 是连通的。(就剩下nginx了)
(注意:1. --http和 :8000之间有空格,否则会报错unrecognized ...
2. 在项目根目录下运行上述命令,即notebook项目文件夹下,否则报错import error notebook.wsgi)
3.5 nginx配置和测试
找到nginx默认的配置文件路径:/etc/nginx/nginx.conf( 通过命令可以查看:sudo nginx -t),确保nginx.conf的同目录下有uwsgi_params文件(/etc/nginx/uwsgi_params),没有的话根据链接获取。
在django项目目录下,创建单独的nginx配置文件notebook.conf (notebook/notebook/notebook.conf),将nginx.conf的内容复制到notebook.conf,将其中的server部分全部替换成下面:
server {
listen 80;
server_name localhost;
charset utf-8;
access_log /home/gCloud/djangoProject/notebook/notebook/nginx_access.log;
error_log /home/gCloud/djangoProject/notebook/notebook/nginx_error.log;
client_max_body_size 75M;
# Load configuration files for the default server block.
location /static {
alias /home/gCloud/djangoProject/notebook/collect_static;
}
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:9090;
}
}
其中的 listen 80代表服务器开放80端口;
access_log 和error_log是定义nginx访问日志和错误日志的存放路径。
location [目录名]代表项目路径的引导;
“location /static”中的”/static”是自己定义的项目引用静态文件时,浏览器中显示的静态资源所在的根目录名;这样的话,用户在浏览器中查看到的所有 image,css或js资源都是处在http://127.0.0.1/static下的。(django静态文件的绝对路径是根据自己的实际情况来确定的,一般在自己的django的app/static目录下,或自己python manage.py collectstatic后的路径下。)
如果还有media文件之类的静态目录,仿照static的写法,自己补充。
“location /”是指访问项目根目录时,nginx要做的事。其中需要指定 uwsgi_params文件的绝对路径,上面已经提到了;
127.0.0.1:9090是指uWSGI绑定的监听地址,这里使用了9090端口。
nginx配置参考及含义:
# ocean_monitor.conf # the upstream component nginx needs to connect to upstream django_ocean_monitor { # server unix:///path/to/your/mysite/mysite.sock; # for a file socket # for a web port socket (we\'ll use this first) server 127.0.0.1:8108; } # configuration of the server server { # the port your site will be served on listen 8008; # the domain name it will serve for # substitute your machine\'s IP address or FQDN # Django 的 settings.py 文件中的 ALLOWED_HOSTS 要加上这里设置的 server_name server_name localhost; charset utf-8; gzip on; gzip_min_length 1000; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 3; gzip_vary on; # 禁用对 IE 6 使用 gzip 压缩 gzip_disable "MSIE [1-6]\\."; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/xml+rss application/json; ## Individual nginx logs access_log /var/log/nginx/ocean_monitor_access.log; error_log /var/log/nginx/ocean_monitor_error.log; # max upload size client_max_body_size 8M; # adjust to taste # Django media location /media { # your Django project\'s media files - amend as required alias /home/python/ocean_monitor/media; } location /static { # your Django project\'s static files - amend as required alias /home/python/ocean_monitor/static; } # Finally, send all non-media requests to the Django server. location / { uwsgi_pass django_ocean_monitor; # the uwsgi_params file you installed # 增加 nginx 配置, uwsgi_params 文件在 /etc/nginx/ 目录下 include /etc/nginx/uwsgi_params; } }
3.6 django配置
3.6.1静态文件
在settings.py文件中设置:
STATIC_URL = \'/static/\'
STATIC_ROOT = os.path.join(BASE_DIR,\'collect_static\')
运行命令:python manage.py collectstatic (所有静态文件会储存到collect_static文件夹中)
关于STATIC_ROOT和STATIC_URL及STATICFILES_DIRS作用和区别,参见下面
本文主要给大家介绍关于Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 详细如下: 首先,我们配置静态文件,要在setting.py里面加入如下几行代码: settings.py # the settings above # STATIC SETTINGS STATIC_URL = \'/static/\' # BASE_DIR 是项目的绝对地址 STATIC_ROOT = os.path.join(BASE_DIR, \'collect_static\') #以下不是必须的 STATICFILES_DIRS = ( os.path.join(BASE_DIR, \'common_static\'), ) 1.STATIC_ROOT STATIC_ROOT 是在部署静态文件时(pyhtonmanage.pycollectstatic)所有的静态文静聚合的目录,STATIC_ROOT要写成绝对地址,在这里,比如我的项目mysite是/home/mysite/ 那么STATIC_ROOT 为 /home/mysite/collect_static/ 当部署项目时,在终端输入: ? 1 python manage.py collectstatic django会把所有的static文件都复制到STATIC_ROOT文件夹下 2.STATICFILES_DIRS STATIC_ROOT 是在部署的时候才发挥作用, 而实际情况下,静态文件的一般安放位置有两种: 1.一种就是在每个app里面新建一个static文件夹,将静态文件放到里面,在加载静态文件时,比如要在模板中用到静态文件,django会自动在每个app里面搜索static文件夹(所以,不要把文件夹的名字写错哦, 否则django就找不到你的文件夹了) 2.另一种,就是在所有的app文件外面,建立一个公共的文件夹, 因为有些静态文件不是某个app独有的,那么就可以把它放到一个公共文件夹里面,方便管理(注意,建立一个公共的静态文件的文件夹只是一种易于管理的做法,但是不是必须的,app是可以跨app应用静态文件的,因为最后所有的静态文件都会在STATIC_ROOT里面存在) 那现在的问题是如何让django知道你把一些静态文件放到app以外的公共文件夹中呢,那就需要配置STATICFILES_DIRS了 STATICFILES_DIRS = ( os.path.join(BASE_DIR, \'common_static\'), ) STATICFILES_DIRS告诉django,首先到STATICFILES_DIRS里面寻找静态文件,其次再到各个app的static文件夹里面找(注意, django查找静态文件是惰性查找,查找到第一个,就停止查找了) 3.STATIC_URL 那么到此为止,静态文件的机制就可以运作了,但是有一个问题,我能不能通过url直接访问我在项目中的静态文件呢,答案肯定是啦,但是,注意,你是在浏览器是访问,你不可能输入你的静态文件的本地绝对地址吧,比如我的一种图片的本地地址 为 /home/mysite/common_static/myapp/photo.png 那么别人不可能在浏览器上直接输入: http://192.168.1.2:8000/home/mysite/common_static/myapp/photo.png 这样子,浏览器会报错, 没有该页面 那么django是如何让浏览器也可以访问服务器上的静态文件呢,前面已经说了,直接访问服务器本地的地址是不行的,那就需要一个映射,django利用STATIC_URL来让浏览器可以直接访问静态文件,比如: ? 1 STATIC_URL = \'/static/\' 那么可以在浏览器上输入: http://192.168.1.2:8000/static/common_static/myapp/photo.png 那么就相当与访问/home/mysite/common_static/myap/photo.png 所以在浏览器上,利用前缀 STATIC_URL的具体内容,来映射STATIC_ROOT, HTTP://192.168.1.2:8000/static 相当于 本地地址的STATIC_ROOT 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
3.6.2 ALLOWED_HOSTS和DEBUG设置
修改settings.py文件中的ALLOWED_HOSTS和DEBUG (https://www.cnblogs.com/restran/p/4412708.html)
DEBUG = False #关闭debug模式 ALLOWED_HOSTS = [ # 加上本机的IP地址 \'192.168.137.146\', \'127.0.0.1\', \'localhost\' ] #或者设置 #ALLOWED_HOSTS = [\'*\']
3.7 uWSGI配置 (官方文档:https://uwsgi-docs.readthedocs.io/en/latest/Management.html#signals-for-controlling-uwsgi)
在项目目录下创建配置文件uwsgi.ini,内容如下:
[uwsgi] socket = 127.0.0.1:9090 chdir=/home/gCloud/djangoProject/notebook module=notebook.wsgi master = true processes=2 threads=2 max-requests=2000 chmod-socket=664 vacuum=true daemonize =/home/gCloud/djangoProject/notebook/uwsgi.log
pidfile=%(chdir)/uwsgi.pid
其中的socket字段值”127.0.0.1:9090”必须要和上面写的notebook.conf配置文件中的uWSGI监听地址完全一样;
chdir指自己工程的绝对路径;
module指的是wsgi.py在自己工程中的相对路径,”.”指代一层目录;我的django工程的wsgi.py文件是在”/home/gCloud/djangoProject/notebook/notebook /wsgi.py”,所以写notebook.wsgi;
daemonize指定uWSGI日志的存储路径
pidfile设置后,通过下面--ini命令启动uwsgi时,会在该目录下自动创建uwsgi.pid文件,里面存储了uwsgi的pid号(进程号)
uwsgi配置参考及含义:
# uwsgi.ini file [uwsgi] # Django-related settings # the base directory (full path) chdir = /home/python/ocean_monitor # Django\'s wsgi file wsgi-file = /home/python/ocean_monitor/ocean_monitor/wsgi.py # module = index.wsgi:application # the virtualenv (full path) # home = /path/to/virtualenv daemonize = /home/python/ocean_monitor/ocean_monitor.log # process-related settings # master master = true pidfile = /tmp/ocean_monitor_master.pid # maximum number of worker processes processes = 3 # the socket (use the full path to be safe # socket = /home/python/ocean_monitor/ocean_monitor.sock socket = 127.0.0.1:8108 # ... with appropriate permissions - may be needed chmod-socket = 664 # clear environment on exit vacuum = true
3.8 启动uWSGI
sudo uwsgi --ini /home/gCloud/djangoProject/notebook/uwsgi.ini
其他命令:
停止uwsgi服务器:sudo uwsgi --stop /home/gCloud/djangoProject/notebook/uwsgi.pid
重启:sudo uwsgi --reload /home/gCloud/djangoProject/notebook/uwsgi.pid
(如果出现错误 signal_pidfile()/kill(): No such process [core/uwsgi.c line 1627],是由于uwsgi.pid中进程pid号不正确,通过命令 ps -aux | grep uwsgi 查看进程pid号,修改uwsgi.pid文件为该pid号即可)
3.9 启动 nginx
sudo nginx -c /home/gCloud/djangoProject/notebook/notebook/notebook.conf
(注意若nginx正在运行,先关闭:sudo nginx -s stop)
最后打开浏览器输入 http://127.0.0.1,就能访问django项目的网页了,每次修改django项目文件的代码需要重启uwsgi和nginx才生效。
3.10 相关的文件路径梳理
django项目路径: /home/gCloud/djangoProject/notebook (项目名为notebook)
工程静态文件路径: /home/gCloud/djangoProject/notebook/collect_static
wsgi.py的路径: /home/gCloud/djangoProject/notebook/notebook/wsgi.py
uwsgi.ini的路径: /home/gCloud/djangoProject/notebook/uwsgi.ini
uwsgi日志路径: /home/gCloud/djangoProject/notebook/uwsgi.log
uwsgi.pid路径:/home/gCloud/djangoProject/notebook/uwsgi.pid
nginx配置文件notebook.conf的路径: /home/gCloud/djangoProject/notebook/notebook/notebook.conf
uwsgi_params的路径: /etc/nginx/uwsgi_params
nginx访问日志路径:/home/gCloud/djangoProject/notebook/notebook/nginx_access.log
nginx错误日志路径: /home/gCloud/djangoProject/notebook/notebook/nginx_error.log
项目路径完整显示如下:
[gCloud@instance-1 notebook]$ ls -R .: collect_static db.sqlite3 manage.py notebook planlist templates uwsgi.ini uwsgi.log uwsgi.pid ./collect_static: admin ./collect_static/admin: css fonts img js ./collect_static/admin/css: base.css changelists.css dashboard.css fonts.css forms.css login.css rtl.css widgets.css ./collect_static/admin/fonts: LICENSE.txt README.txt Roboto-Bold-webfont.woff Roboto-Light-webfont.woff Roboto-Regular-webfont.woff ./collect_static/admin/img: calendar-icons.svg icon-calendar.svg icon-no.svg inline-delete.svg selector-icons.svg gis icon-changelink.svg icon-unknown-alt.svg LICENSE sorting-icons.svg icon-addlink.svg icon-clock.svg icon-unknown.svg README.txt tooltag-add.svg icon-alert.svg icon-deletelink.svg icon-yes.svg search.svg tooltag-arrowright.svg ./collect_static/admin/img/gis: move_vertex_off.svg move_vertex_on.svg ./collect_static/admin/js: actions.js cancel.js core.js popup_response.js SelectBox.js vendor actions.min.js change_form.js inlines.js prepopulate_init.js SelectFilter2.js admin collapse.js inlines.min.js prepopulate.js timeparse.js calendar.js collapse.min.js jquery.init.js prepopulate.min.js urlify.js ./collect_static/admin/js/admin: DateTimeShortcuts.js RelatedObjectLookups.js ./collect_static/admin/js/vendor: jquery xregexp ./collect_static/admin/js/vendor/jquery: jquery.js jquery.min.js LICENSE-JQUERY.txt ./collect_static/admin/js/vendor/xregexp: LICENSE-XREGEXP.txt xregexp.js xregexp.min.js ./notebook: __init__.py nginx_access.log notebook.conf settings.py wsgi.py mime.types nginx_error.log __pycache__ urls.py ./notebook/__pycache__: __init__.cpython-35.pyc settings.cpython-35.pyc urls.cpython-35.pyc wsgi.cpython-35.pyc ./planlist: admin.py apps.py __init__.py migrations models.py __pycache__ tests.py views.py ./planlist/migrations: __init__.py __pycache__ ./planlist/migrations/__pycache__: __init__.cpython-35.pyc ./planlist/__pycache__: admin.cpython-35.pyc apps.cpython-35.pyc __init__.cpython-35.pyc models.cpython-35.pyc views.cpython-35.pyc ./templates: index.html
4. 管理进程
https://code.ziqiangxuetang.com/django/django-deploy-base.html
https://code.ziqiangxuetang.com/django/django-nginx-deploy.html
5.阿里云部署
1.远程连接设置:https://www.jianshu.com/p/962ff16a951c
2.部署:按上述配置好django,uwsgi,nginx,本地通过127.0.0.1能访问网页,表示配置成功。
3.入站和出站规则设置(安全组):https://blog.csdn.net/A11085013/article/details/79486731
设置完成后通过实例公网ip地址就能访问网页(公网ip地址在django的allowed_host,nginx的端口80加入了入站规则)
参考:https://blog.csdn.net/c465869935/article/details/53242126
https://www.cnblogs.com/restran/p/4412708.html
https://www.cnblogs.com/simplezy/p/6705340.html
以上是关于uwsgi+nginx部署django项目的主要内容,如果未能解决你的问题,请参考以下文章