项目部署是指在软件开发完成后,将开发机器上运行的软件实际安装到服务器上进行长期运行
-
在安装机器上安装和配置同版本的环境【py、数据库等】
-
django项目迁移
sudo scp /home/tarena/django/mysite1 # 复制本地目录下文件夹 root@88.77.66.55:/home/root/xxx # 复制到指定ip目录 请输入root密码: # 输入root密码
-
用
uWSGI
代替python3 manage.py runserver
方法启动服务器 -
配置nginx反向代理服务器
-
用nginx配置静态文件路径,解决静态路径问题
2.1. WSGI定义
WSGI(Python Web Server Gateway Interface)Web服务器网关接口,是Python应用程序或框架和Web服务器之间的一种接口,被广泛使用
使用python3 manage.py runserver
通常只在开发和测试环境中使用
当开发结束后,完善的项目代码需要在一个高效稳定的环境中运行,这时可以使用WSGI
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/
检查是否成功安装
sudo pip3 freeze|grep -i 'uwsgi'
如果成功安装,则会输出uWSGI==2.0.18
2.4. 配置uWSGI
添加配置文件项目同名文件夹/uwsgi.ini
如:mysite7/mysite7/uwsgi.ini
文件以[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
特殊说明:Django的setting.py需要做如下配置
- 修改setting.py将DEBUG=True改为DEBUG=False
- 修改setting.py将ALLOWED_HOSTS=[]改为ALLOWED_HOSTS = [‘网站域名’] 或者 [‘服务监听的ip地址’]
2.5. 启动uwsgi
cd 到 uWSGI配置文件所在目录
uwsgi --ini uwsgi.ini
2.6. 停止uwsgi
cd 到 uWSGI配置文件所在目录
uwsgi --stop uwsgi.pid
2.7. 说明
- 无论是启动还是关闭,都需要执行
ps aux|grep 'uwsgi'
确认是否符合预期 - 启动成功后,进程在后台执行,所有日志均输出在配置文件所在目录的
uwsgi.log
中 - Django中代码有任何修改,都需要重新启动uwsgi
2.8. 测试
在浏览器端输入http://127.0.0.1:8000进行测试
注意:
- 此时端口8000被uWSGI进程监听,而非runserver
如果当前有预期返回,则uWSGI启动成功
2.9. 常见问题
-
启动失败:端口被占用
原因:有其他进程占用uWSGI启动的端口
解决方案:可执行
sudo lsof -i:端口号
查询出具体进程,杀掉进程后,重新启动uWSGI即可 -
停止失败:stop无法关闭uWSGI
原因:重复启动uWSGI,导致pid文件中的进程号失准
解决方案:ps出uWSGI进程,手动kill掉
3.1. 定义
-
Nginx是轻量级的高性能Web服务器,提供了诸如HTTP代理和反向代理、负载均衡等一系列重要特征
-
C语言编写,执行效率高
-
Nginx作用
- 负载均衡,多台服务器轮流处理请求
- 反向代理
-
原理:客户端请求Nginx,再有Nginx将请求转发uWSGI运行的Django
3.2. 安装
sudo apt install nginx
如果下载速度很慢,考虑更换为国内源
vim /etc/apt/sources.list
更改国内源
sudo apt-get update
安装完毕后,ubuntu终端输入nginx -v
显示如下:
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下 } ... }
一定带有;
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配置只要修改,就需要进行重启,否则配置不生效
3.5. 修改uWSGI启动模式
说明nginx负责接收请求,并把请求转发给后面的uWSGI
此模式下,uWSGI需要以socket模式启动
样例:
uWSGI配置变化后,也需要重启
四、nginx + uwsgi排错排错问题宗旨 → 看日志!看日志!看日志
nginx日志位置:
- 异常信息
/var/log/nginx/error.log
- 正常访问信息
/var/log/nginx/access.log
uwsgi日志位置:
项目同名目录下,uwsgi.log
4.1. 常见问题
-
访问127.0.0.1:80地址,502响应
502响应,代表Nginx反向代理配置成功,但是对应的uWSGI未启动
-
访问127.0.0.1:80/url,404响应
- 路由的确不在Django配置中
- Nginx配置错误,未禁止掉try_files
-
创建新路径,主要存放Django所有静态文件。
如:/home/tarena/项目名_static/
-
在Django setting.py中添加新配置
STATIC_ROOT = '/home/tarena/项目名_static/static'# 注意 此配置路径为存放所有正式环境中需要的静态文件
-
进入项目,执行
$ python3 manage.py collectstatic
执行该命令后,Django将项目中所有的静态文件复制到STATIC_ROOT中,包括Django内建的静态文件
-
Nginx配置中添加新配置
# file : /etc/nginx/sites-enabled/default # 新添加location /static 路由配置,重定向到指定的 第一步创建的路径即可 server{ ... location /static { # root 第一步创建文件夹的绝对路径,如: root /home/tarena/项目名_static; } }
-
重启Nginx
定义和配置
在模板文件夹内添加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
...
说明:
- 若报错邮件中牵扯到user、pw、cc等局部变量的值,则会将其替换成*****,而name变量还显示其真实值
- 多个装饰器时,需要将其放在最顶部
- 若不传参数,则过滤所有局部变量的值
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的值会被替换成*****