一、基础概念

项目部署是指在软件开发完成后,将开发机器上运行的软件实际安装到服务器上进行长期运行

  1. 在安装机器上安装和配置同版本的环境【py、数据库等】

  2. django项目迁移

    sudo scp /home/tarena/django/mysite1 # 复制本地目录下文件夹
    root@88.77.66.55:/home/root/xxx # 复制到指定ip目录
    请输入root密码: # 输入root密码
    
  3. uWSGI代替python3 manage.py runserver方法启动服务器

  4. 配置nginx反向代理服务器

  5. 用nginx配置静态文件路径,解决静态路径问题

二、uWSGI网关接口配置

2.1. WSGI定义

WSGI(Python Web Server Gateway Interface)Web服务器网关接口,是Python应用程序或框架和Web服务器之间的一种接口,被广泛使用

使用python3 manage.py runserver通常只在开发和测试环境中使用

当开发结束后,完善的项目代码需要在一个高效稳定的环境中运行,这时可以使用WSGI

24. Django部署:项目部署_python

24. Django部署:项目部署_python_02

2.2. uWSGI定义

uWSGI是WSGI的一种,它实现了HTTP协议WSGI协议以及uwsgi协议

uWSGI协议功能完善,支持协议众多,在python web圈热度极高

uWSGI学习以学习配置为主

2.3. uWSGI安装

Ubuntu执行:

sudo pip3 install uwsgi==2.0.18 -i https://pypi.tuna.tsinghua.edu.cn/simple/

24. Django部署:项目部署_静态文件_03

检查是否成功安装

sudo pip3 freeze|grep -i 'uwsgi'

如果成功安装,则会输出uWSGI==2.0.18

24. Django部署:项目部署_python_04

2.4. 配置uWSGI

添加配置文件项目同名文件夹/uwsgi.ini

如:mysite7/mysite7/uwsgi.ini

24. Django部署:项目部署_配置文件_05

文件以[uwsgi]开头,有如下配置项:

  • 套接字方式的 IP地址:端口号 【此模式需要有nginx】:socket=127.0.0.1:8000

  • Http通信方式的 IP地址:端口号:http=127.0.0.1:8000

  • 项目当前工作目录:chdir=/home/tarena/…/my_project

  • 项目中wsgi.py文件的目录,相对于当前工作目录【相对路径】:wsgi-file=my_project/wsgi.py

  • 进程个数:process=4

  • 每个进程的线程个数:threads=2

  • 服务的pid记录文件:pidfile=uwsgi.pid

  • 服务的日志文件位置:daemonize=uwsgi.log

  • 开启主进程管理模式:master=true

24. Django部署:项目部署_django_06

特殊说明:Django的setting.py需要做如下配置

  1. 修改setting.py将DEBUG=True改为DEBUG=False
  2. 修改setting.py将ALLOWED_HOSTS=[]改为ALLOWED_HOSTS = [‘网站域名’] 或者 [‘服务监听的ip地址’]

2.5. 启动uwsgi

cd 到 uWSGI配置文件所在目录

uwsgi --ini uwsgi.ini

24. Django部署:项目部署_python_07

2.6. 停止uwsgi

cd 到 uWSGI配置文件所在目录

uwsgi --stop uwsgi.pid

24. Django部署:项目部署_静态文件_08

2.7. 说明

  1. 无论是启动还是关闭,都需要执行ps aux|grep 'uwsgi'确认是否符合预期
  2. 启动成功后,进程在后台执行,所有日志均输出在配置文件所在目录的uwsgi.log
  3. Django中代码有任何修改,都需要重新启动uwsgi

2.8. 测试

在浏览器端输入http://127.0.0.1:8000进行测试

注意:

  • 此时端口8000被uWSGI进程监听,而非runserver

如果当前有预期返回,则uWSGI启动成功

2.9. 常见问题

  1. 启动失败:端口被占用

    原因:有其他进程占用uWSGI启动的端口

    解决方案:可执行sudo lsof -i:端口号查询出具体进程,杀掉进程后,重新启动uWSGI即可

  2. 停止失败:stop无法关闭uWSGI

    原因:重复启动uWSGI,导致pid文件中的进程号失准

    解决方案:ps出uWSGI进程,手动kill掉

三、Nginx

3.1. 定义

  • Nginx是轻量级的高性能Web服务器,提供了诸如HTTP代理和反向代理、负载均衡等一系列重要特征

  • C语言编写,执行效率高

  • Nginx作用

    • 负载均衡,多台服务器轮流处理请求
    • 反向代理
  • 原理:客户端请求Nginx,再有Nginx将请求转发uWSGI运行的Django

    24. Django部署:项目部署_django_09

3.2. 安装

sudo apt install nginx

如果下载速度很慢,考虑更换为国内源

vim /etc/apt/sources.list
更改国内源
sudo apt-get update

安装完毕后,ubuntu终端输入nginx -v显示如下:

24. Django部署:项目部署_django_10

3.3. 配置

  • 修改nginx的配置文件/etc/nginx/site-enable/default;sudo vim该文件

    sudo vim /etc/nginx/site-enable/default

    # 在server节点下添加新的location项,指向uwsgi的ip与端口
    server{
        ...
        location / {
            uwsgi_pass 127.0.0.1:8000 # 所有/开头的请求均重定向到127.0.0.1到8000端口
            inclue /etc/nginx/uwsgi_params; # 将所有的参数转到uwsgi下
        }
        ...
    }
    

    24. Django部署:项目部署_nginx_11

一定带有;

3.4. 启动/停止

$ sudo /etc/init.d/gninx start|stop|restart|status
# 或者
$ sudo service nginx start|stop|restart|status
  • 启动 - sudo /etc/init.d/nginx start
  • 停止 - sudo /etc/init.d/nginx stop
  • 重启 - sudo /etc/init.d/nginx restart
  • 注意:nginx配置只要修改,就需要进行重启,否则配置不生效

24. Django部署:项目部署_配置文件_12

3.5. 修改uWSGI启动模式

说明nginx负责接收请求,并把请求转发给后面的uWSGI

此模式下,uWSGI需要以socket模式启动

样例:

24. Django部署:项目部署_django_13

24. Django部署:项目部署_静态文件_14

uWSGI配置变化后,也需要重启

24. Django部署:项目部署_nginx_15

四、nginx + uwsgi排错

排错问题宗旨 → 看日志!看日志!看日志

nginx日志位置:

  • 异常信息 /var/log/nginx/error.log
  • 正常访问信息/var/log/nginx/access.log

uwsgi日志位置:

项目同名目录下,uwsgi.log

4.1. 常见问题

  1. 访问127.0.0.1:80地址,502响应

    502响应,代表Nginx反向代理配置成功,但是对应的uWSGI未启动

  2. 访问127.0.0.1:80/url,404响应

    • 路由的确不在Django配置中
    • Nginx配置错误,未禁止掉try_files
五、Nginx静态文件配置
  1. 创建新路径,主要存放Django所有静态文件。

    如:/home/tarena/项目名_static/

    24. Django部署:项目部署_django_16

  2. 在Django setting.py中添加新配置

    STATIC_ROOT = '/home/tarena/项目名_static/static'# 注意 此配置路径为存放所有正式环境中需要的静态文件
    

    24. Django部署:项目部署_django_17

  3. 进入项目,执行

    $ python3 manage.py collectstatic
    

    执行该命令后,Django将项目中所有的静态文件复制到STATIC_ROOT中,包括Django内建的静态文件

    24. Django部署:项目部署_配置文件_18

  4. Nginx配置中添加新配置

    # file : /etc/nginx/sites-enabled/default
    # 新添加location /static 路由配置,重定向到指定的 第一步创建的路径即可
    server{
    	...
    	location /static {
    		# root 第一步创建文件夹的绝对路径,如:
    		root /home/tarena/项目名_static;
    	}
    }
    

    24. Django部署:项目部署_配置文件_19

    24. Django部署:项目部署_静态文件_20

  5. 重启Nginx

    24. Django部署:项目部署_python_21

六、404/500界面

定义和配置

在模板文件夹内添加404.html模板,当视图出发HTTP404异常时将会被显示

404.html仅在发布版(即setting.py中的DEBUG=False时)才起作用

当响应处理函数出发HTTP404异常时就会跳转到404界面

七、邮箱告警

定义和配置

当正式服务器上代码运行有报错时,可以将错误追溯信息发送至指定的邮箱

setting.py中 - 在基础邮箱授权后 添加如下配置:

# 关闭调试模式
DEBUG = False

# 错误报告接收方
ADMINS = [('name1', 'name1@example.com'), ('name2', 'name2@example.com')]

# 发送错误报告放,默认为root@localhost账户,多数邮件服务器会拒绝
SERVER_EMAIL = 'eamil配置中的邮箱'
八、过滤敏感信息

报错邮件中会显示一些错误的追踪,这些错误追踪会出现如password等敏感信息,Django已经将配置文件中的敏感信息过滤修改为多个星号,但是用户自定义的视图函数需要用户手动过滤敏感信息

可过滤信息如下:

  • 局部变量
  • POST提交数据

8.1. 局部变量

from django.views.decorators.debug import sensitive_cariables

@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
	pw = user.pass_word
	cc = user.credit_card_number
	name = user.name
	...

说明:

  1. 若报错邮件中牵扯到user、pw、cc等局部变量的值,则会将其替换成*****,而name变量还显示其真实值
  2. 多个装饰器时,需要将其放在最顶部
  3. 若不传参数,则过滤所有局部变量的值

8.2. POST数据

from django.views.decorators.debug import sensitive_post_parameters

@sensitive_post_parameters('password', 'username')
def index(request):
	s = request.POST['username'] + request.POST['abcd']
	...
	# 'abcd'并不存在,此时引发error
	# POST中username及password的值会被替换成*****