Nginx+uWSGI+Django部署web服务器
环境说明
- 进行本文操作前需己搭建好的环境
- linux系统,我用的是openSUSE
- 使用了operation用户的家目录做为测试环境
- python3.5.6
- virtualenv 16.0
- pip3 18.0
- nginx 1.13.1
- 后面进行安装的环境
- django 1.11
- uwsgi-2.0.17.1
前言
在多年前,基于python的web项目,常见的部署方法有:
- fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务互动。
- wsgi:利用http服务的mod_wsgi模块来跑各个project。
不过uwsgi出现后,大部份部署就不会使用以上的两个协议了。
因为uwsgi它既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据作者说该协议大约是fcgi协议的10倍那么快。uWSGI的主要特点如下:
- 超快的性能。
- 低内存占用(实测为apache2的mod_wsgi的一半左右)。
- 多app管理。
- 详尽的日志功能(可以用来分析app性能和瓶颈)。
- 高度可定制(内存大小限制,服务一定次数后重启等)。
所以在uwsgi协议的基础上,配合nginx来做python(类如django的框架)的web项目部署就很常见了。
uwsgi 实际上也是一个 http 服务器,只不过它只面向 python 的网络应用程序。
虽然 uwsgi 也是 http 服务器,但是却不便直接使用它部署 python web 应用程序。
uwsgi 所扮演的的角色是后端 http 服务器,nginx 扮演的角色是前端 http 服务器,django项目 是客户所真正要访问到的提供数据方。 用户从网页浏览器中发出请求,nginx 服务器收到请求后,会通过它的 uwsgi 模块将用户的请求转发给 uwsgi 服务器,uwsgi 服务器通过django处理完毕后将结果返回给 nginx,浏览器将最终的结果展现给用户。
搭建项目
建立一个虚拟环境
- 建议个人学习和测试的话,直接建在家用户目录下,以避免权限引起的各种拒绝问题
- 或者正式点,系统再建一个dev用户,在专门的工作目录下给好dev用户的权限去运行。
- 虚拟环境的目录名建议就带个env点明是虚拟环境,如果和后面的项目取相同的名字你会看到三重同名的串在一起,有点不太好认。
virtualenv -p python3 py3env
启动虚拟环境
source py3env/bin/activate
安装django1.11,之所以装这个版本是学习所需要,后面自己的项目最好与时俱进。
pip install django==1.11
直接使用django-admin命令创建一个django项目
- 建议不要放在py3env目录下,而是在专门的工作目录下建立
django-admin startproject luffy
- 建议不要放在py3env目录下,而是在专门的工作目录下建立
如下,己经初步搭建好简单的项目:
cd luffy
(py3env) operation@opensuse-wordpress:~/work/luffy> tree -L 2
.
├── luffy
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
- 创建新应用,例如app01
python3 manage.py startapp app01
结构如下
(py3env) operation@opensuse-wordpress:~/work/luffy> tree -L 2
.
├── app01
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── luffy
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Django部署
编辑luffy/luffy/settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*', ]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
]
如上,主要是:
- 将DEBUG由True改成False(虽然只是在学习和测试搭建的,也要顾及好安全)
- 在ALLOWED_HOSTS 默认的空列表中填入你自己打算使用的域名,我这里测试的时候填的是
*
,真正上线部署的时候不建议填成通配符的*
,而是要填允许访问的主机域名。一般django用于做后端服务器,而前端会有一个域名。详情可见django官方文档。 - INSTALLED_APPS 列表下增加
appo1
,表示将app01应用给安装注册上。 - 补充,后面配置好nginx和新建好域名之后,我将
ALLOWED_HOSTS = ['*', ]
修改成ALLOWED_HOSTS = ['luffy.tielemao', ]
了,通过域名访问仍然正常。而直接敲ip地址则会报400错误。
编辑luffy/app01/views.py
from django.shortcuts import render,HttpResponse
# Create your views here.
def index(request):
return HttpResponse('Hello Hero')
由于只是简单演示,所以上面只是让用户访问index页面后,得到一个显示Hello Hero
的页面。
编辑luffy/luffy/urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
]
运行并测试
首先是运行,由于是单独对django进行运行测试,所以只是在进入项目根目录后命令行敲以下命令:
python manage.py runserver 0.0.0.0:8083
其中0.0.0.0
表示捆绑监听服务器上的所有网卡IP地址,当然也就包括了127.0.0.1和外网的公网ip了。
最初我测试的是ALLOWED_HOSTS填的允许的HOSTS是自己的域名.tielemao.com
,结果直接在浏览器上敲IP加8083端口接index当然是报错:
Bad Request(400)
而由于我将DEBUG值设为了False,所以也不会将调试信息暴露出来。
然后我将