第14章 Django项目部署
本章主要介绍如何把开发的Django项目部署到服务器上。
14.1 uWSGI
服务器操作系统以Ubuntu为例。
14.1.1 uWSGI介绍
WSGI,Web Server Gateway Interface,是为python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。
WSGI是Web服务器与Web应用程序或应用框架之间的一种低级别的接口,用以提升可移植Web应用开发的共同点。
许多Python Web框架都自带WSGI服务,eg:Flask、webpy、Django等。
大多数情况使用生产环境的WSGI服务或者联合Nginx做uwsgi。
uWSGI是一个Web 服务器,它实现了WSGI、uwsgi、HTTP等协议,在Nginx中,ngx_http_uwsgi_module的作用是与uWSGI服务器进行交换。
WSG、uwsgi、uWSGI三个概念的区分:
WSGI是Web服务器与Web应用程序或应用框架之间的接口,也可以看作一个协议;
uwsgi是一种传输协议;
uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
14.1.2 安装uWSGI
使用命令:pip install uwsgi
创建uWSGI测试文件:test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b"Hello World"]
执行命令:uwsgi --http :8001 --wsgi-file test.py
通过浏览器访问:http://127.0.0.1:8001,效果如图:
14.1.3 uWSGI运行Django
需要指定好我们之前建立的Django项目的路径,运行如下命令:
uwsgi --http :8000 --chdir /home/test/guest/ --wsgi-file guest/wsgi.py --master --processes 4 --stats 127.0.0.1:9191
uwsgi命令常用参数如下:
http:协议类型和端口号
processes:开启的进程数量
workers:开启的进程数量,等同于processes
chdir:指定运行目录
wsgi-file:载入wsgi-file(加载wsgi.py文件)
stats:在指定的地址上开启状态服务
threads:开启的线程数量
master:允许主进程存在
daemonize:使进程在后台运行,并将日志输出到指定的日志文件或者UDP服务器
pidfile:指定PID文件的位置,记录主进程的PID号(PID,服务进程ID)
vacuum:当服务器退出时自动清理环境,删除Unix Socket文件和PID文件
14.2 Nginx
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。
采用Nginx+uWSGI的组合来部署Django是较为常见的部署方式。
Nginx作为服务器最前端,用它来接收Web的所有请求,统一管理请求,Nginx可用来处理所有静态请求,然后,Nginx将所有非静态请求通过uWSGI传递给Django,由Django来进行处理,从而完成一次Web请求。uWSGI的作用类似一个桥接器,起到连接Nginx与Django的作用。
14.2.1 安装Nginx
使用如下命令安装nginx:apt-get install nginx
但是我在安装过程中,出现了错误:
……
E: Sub-process /usr/bin/dpkg returned an error code (1)
前面其实还有好长一段错误,这句应该最关键了,于是问了下度娘,估计是自己之前升级Ubuntu系统失败还原后遗留的错误,还好比较好解决:
cd /var/lib/dpkg
mv info/ info.bak/
mkdir info
dpkg --configure -a
apt-get install -f
mv /var/lib/dpkg/info/* info.bak/
rm -rf /var/lib/dpkg/info
mv info.bak/ info/
apt remove --purge nginx
apt-get install nginx
按照上述步骤即可解决此问题。
Nginx基本操作:
/etc/init.d/nginx start # 启动Nignx
/etc/init.d/nginx stop # 关闭Nginx
/etc/init.d/nginx restart # 重启Nginx
nginx -v # 查看版本
修改Nginx默认端口号,编辑文件:/etc/nginx/sites-available/default
……
server {
listen 8088 default_server;
listen [::]:8088 default_server;
……
}
14.2.2 Nginx+uWSGI+Django
将三者整合,之前建立的发布会签到系统的目录结构如下:
guest/
|--manage.py
|--guest/
| |--__init__.py
| |--settings.py
| |--urls.py
| |--wsgi.py
|----django_uwsgi.ini
在创建guest项目时,在guest目录下默认已经生成了wsgi.py文件,所以我们只需要创建django_uwsgi.ini文件,配置uWSGI参数,uWSGI支持多种类型的配置文件,eg:xml、ini等,这里使用的是ini格式。
[uwsgi]
# 请求方式与端口号
socket = :8000
# Django项目路径
chdir = /home/test/guest
# wsgi文件
module = guest.wsgi
# 允许主进程存在
master = true
# 开启进程数
processes = 3
# 当服务器退出时自动清理环境
vacuum = true
这个配置文件,其实就相当于把“uwsgi”命令运行Django项目的参数给文件化了:
socket:指定请求的方式和端口号。这里要特别注意,如果想直接通过uWSGI访问Django项目,那么这里要配置为http;如果想通过Nginx请求uWSGI来访问Django项目,那么这里就要配置为socket;这里的8000为通过uWSGI访问Django项目的端口号;
chdir:指定Web项目的根目录;
module:配置guest.wsgi,可以这样理解这个配置,对于django_uwsgi.ini文件来说,与它评级的有一个guest目录,这个目录下有一个wsgi.py文件;
运行命令:uwsgi --ini django_uwsgi.ini
接下来配置Nginx配置文件,编辑文件:/etc/nginx/sites-available/default,添加如下配置:
server {
listen 8089;
listen [::]:8089;
server_name 127.0.0.1 192.168.1.1;
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
}
这是一个极简配置:
listen:指定的是Nginx代理uWSGI对外的端口号;
server_name:指定Nginx代理uWSGI对外的IP地址,可以指定多个IP或域名,127.0.0.1指向的是本机,192.168.1.1为本机的IP地址,配置这个IP地址是为了给局域网内的其他主机访问;
location:实现的是Nginx将请求转发给uWSGI,其中,include必须指定为uwsgi_params文件,如果启动失败,则需要指定该文件的绝对路径,通常是在/etc/nginx/目录下;而uwsgi_pass所指的本机IP端口号与django_uwsgi.ini配置文件中的IP端口号必须一致;
配置完成后,重启Nginx,然后访问:http://127.0.0.1:8089或http://192.168.1.1:8089
注意: 前面的uwsgi进程必须也同时启动,否则会报502网关错误。
14.2.3 处理静态资源
如何处理静态资源呢,需要编辑文件:/etc/nginx/sites-avaiable/default,添加Web项目的静态资源。
server {
listen 8089;
listen [::]:8089;
server_name 127.0.0.1 192.168.1.1;
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
# 配置静态文件目录
location /static {
alias /home/test/guest/sign/static;
}
}
再次重新启动Nginx,再次访问签到页面就能战胜出样式文件等静态资源了。
14.3 创建404页面
在项目部署上线,404页面里的详细信息是不能让用户看到的,不安全会暴露Django的详细报错信息,也不友好,所以,打开settings.py配置文件,关闭Django的DEBUG状态。
当DEBUG设置为“False”时,必须修改ALLOWED_HOSTS,只有列表中的host才能访问,但不建议使用“*”通配符去配置,当DEBUG设置为False时必须设置这个配置,否则会抛出异常。
但在没有申请网址时,只能暂时先使用“*”,表示允许所有host访问。
当访问一个不存在的页面时,会显示如下页面:
虽然屏蔽了debug信息,但这个页面依然不友好,接下来创建默认的404页面,创建文件:/home/test/guest/sign/templates/404.html
<html lang="zh-CN">
<head>
<title>404</title>
</head>
<body>
<div>
<img src="/static/image/404error.jpg"/>
</div>
</body>
</html>
如果没有image目录就手工创建,并且在里面放一个名为404error.jpg就可以了。
总结
本章内容不多,主要就是告诉大家,主流的Django项目的部署方式,这里只对部署做了简单的讲解,并不深入,但足以让你支撑起一个项目部署上线,可以说是相当实用了,终于知道不用runserver也能启动的是咋弄的了。