目录
1 一些概念
1.1 项目部署
1.2 WSGI
1.3 uWSGI
1.4 Nginx
2 安装环境与迁移项目
2.1 项目内容
2.2 项目配置
2.2.1 DEBUG
2.2.2 STATIC_ROOT
2.2.3 ALLOWED_HOST
3 uWSGI
3.1 安装uWSGI
3.2 配置uWSGI
3.3 启动 uWSGI
3.4 停止 uWSGI
4 nginx
4.1 安装nginx
4.2 配置nginx
4.2.1 基础配置
4.2.2 静态文件配置
4.3 启动nginx
5 常见错误
6 其他
6.1 自定义错误码页面
6.2 邮件告警
6.2.1 屏蔽post信息
6.2.2 屏蔽其他变量
1 一些概念
1.1 项目部署
项目部署是指将开发好的网站,放到专门的服务器上。一般服务器是具有公网IP的(从华为云,阿里云这些地方买)。部署一般有下面几步
-
将需要的环境全部装好,比如mysql,python相关环境等。
-
使用 sudo scp命令,将开发文件复制到云服务器上,比如
- sudo scp /home/tarena/django/mysite1 username@88.77.66.55:/home/username/xxx
username@88.77.66.55 是用户名和公网IP,输入完敲回车后会询问你username的密码,这个在你购买的时候客服都会告诉你
- 用uWSGI替代python manage.py runserver方法启动服务器
- 配置nginx反向代理服务器
- 用nginx配置静态文件路径,解决静态路径问题
1.2 WSGI
WSGI(Web Server Gateway Interface)web服务器网关接口,是python与web的一种接口
浏览器只能处理http协议,django只能处理WSGI协议,runserver既能处理HTTP协议,也可以处理WSGI协议,runserver是浏览器与django通讯的桥梁
1.3 uWSGI
我们之前是使用python manage.py runserver启动服务,使用runserver启动的服务性能不好。所以我们使用uWSGI替代runserver启动服务,uWSGI性能好
uWSGI是WSGI的一种,uWSGI既可以处理http协议,也可以处理WSGI协议,相当于替代了runserver。除了http与WSGI,uWSGI也可以处理很多其他的协议
uWSGI是一种服务,uwsgi是一种协议,uwsgi是二进制协议,比传统http协议效率更高
1.4 Nginx
Nginx是轻量级高性能的web代理服务器(软件),有下面几个重要特点
- 可以代理HTTP
- 可以反向代理,反向代理的意思就是把来的请求转发给其他服务器
- 可以进行负载均衡,保持每个服务器的访问量都差不多
- C语言编写,执行效率高
- nginx可以接受HTTP协议,然后将其转为uwsgi协议发给uWSGI
客户会先请求nginx,然后由nginx将请求转发给uWSGI,因为uWSGI只能起一台机子的服务,当访问量过大时,需要开多台机子,这个时候就需要nginx进行分配了
2 安装环境与迁移项目
2.1 项目内容
我们仅仅为了走一遍项目部署的具体流程,我就不使用我之前的项目了,直接在Ubuntu中新建一个项目
- 使用虚拟机模拟服务器,虚拟机的使用方式在这里有写 附录三 虚拟机的使用_Suyuoa的博客-CSDN博客
- 在windows上无法安装uwsgi,在这里有验证 附录二 windows上直接安装uwsgi(不可行)_Suyuoa的博客-CSDN博客_uwsgi windows
我们这里就用安装django与创建一个新的django项目替代
像换pip源,安装pip3这些操作我就不在这里赘述了
项目里只有一个路由和一个视图
2.2 项目配置
修改setting.py中的一些内容
2.2.1 DEBUG
将DEBUG改成False
将DEBUG改为False后,静态文件就无法正常加载了,可以通过127.0.0.1/admin进行测试,发现已经不是原来的样子了,我们在最后可以让静态文件在nginx中加载
2.2.2 STATIC_ROOT
为了可以在nginx中进行加载,我们现在setting.py中添加一个新的变量 STATIC_ROOT,这个变量的值是你要储存静态文件的绝对路径,这个文件夹一般命名为 项目名_static,添加新的变量 STATIC_ROOT
- 不需要提前创建文件夹
之后输入在manage.py处打开终端,输入 python manage.py collectstatic
- 每改动一次静态文件,当你想让其生效的时候都需要重新执行python manage.py collectstatic,如果你只是想改动个别几个已经存在的文件,将新改动的文件名命名为与之前一样的文件名就可以了
会提示静态文件已经复制进去了,我当前自己写的路由没有用到静态文件,现在复制的全都是django的内置静态文件,我们打开看一下发现都是admin这个路由的内容
2.2.3 ALLOWED_HOST
ALLOWED_HOST改为域名或者使用的公网IP,我们这里都没有。如果只是本机用,就写127.0.0.1就行了,如果是内网用就写你本机192的那个IP就行了
这里如果什么都不加,到后面uwsgi的时候有可能前端会显示400
3 uWSGI
如果仅使用uWSGI,那么浏览器,uWSGI,Django的关系是这样的
3.1 安装uWSGI
uwsgi是一个python的库,使用pip install uwsgi直接安装会出问题
可能跟Ubuntu的版本有关,我当前Ubuntu是22
我们把包下载下来,然后使用python setup.py develop来搞
发现还是不行,我们使用conda安装,参考链接 Exception: you need a C compiler to build uWSGI_CV_William的博客-CSDN博客
这样uWSGI就安装完毕了
3.2 配置uWSGI
在项目路径下的项目同名文件夹下创建uwsgi.ini
之后写入如下内容,这些是uwsgi最简单的配置项,官网有uwsgi的所有配置项,有兴趣可以看一下 uWSGI选项 — uWSGI 2.0 文档
- http是部署的IP与端口,这里写127.0.0.1后,如果settings.py中的ALLOW_HOST有你当前的IP,那么别的机子访问你当前的IP也是可以的
- chdir是项目的绝对路径
- wsgi-file是项目同名文件夹下的wsgi.py文件
- process 最大进程个数,设置的值会与你当前机器的cpu核个数取最小值,所以写多了没事
- threads 最大线程个数,这个的值根据不同的任务有不同的要求,首先根据你的同时访问用户数量来看,process*threads 应该大于等于你的访问用户数量,当然也和服务器性能有关,线程数越大对服务器要求的性能就越高
- pidfile pid文件名称,uwsgi开启服务后会将主进程的信息写在这个文件中
- daemonize 日志文件名称,开启服务后一些运行的信息会写在日志中
- master 是否开启主进程管理模式
3.3 启动 uWSGI
cd到uWSGI配置文件目录,输入 uwsgi --ini uwsgi.ini
- 注意环境中一定要安装uwsgi
运行过后会自动生成uwsgi.log与uwsgi.pid
可以使用ps -ef |grep uwsgi 来看一下开没开,下面这样就是开了
3.4 停止 uWSGI
当你想关闭的时候输入 uwsgi --stop uwsgi.pid 就可以关闭了
可以使用ps -ef |grep uwsgi 来看一下开没开,下面这样就是关了
关闭会使用到uwsgi.pid文件,文件中的内容是uwsgi的主进程,有时这个数会错导致关不上,到时候用ps看一下,然后给uwsgi都kill掉就关了
如果已经打开了,这个时候用浏览器访问你指定的路由已经可以访问了
所有的日志都会在uwsgi.log中,如果项目代码有任何修改并且你想生效的话需要重新启动uwsgi
4 nginx
启动nginx的目的是使用多个uWSGI,浏览器,nginx,uWSGI,Django的关系是这样的
nginx与uWSGI之间可以使用uwsgi协议或HTTP协议,uwsgi协议是二进制协议,效率上要比HTTP高,所以一般我们使用uwsgi协议
4.1 安装nginx
sudo apt install nginx
- 这个是相当于在linux中安装一个软件,与你当前的环境没有关系
安装成功后输入 nginx -v可以查看nginx的版本
4.2 配置nginx
4.2.1 基础配置
nginx的配置文件在 /etc/nginx/sites-available 中,这个default就是默认配置文件
- nginx中有sites-available与sites-enabled,我们一般在sites-available中进行修改,修改后重新运行nginx,可以使site-enabled与sites-available中正在使用的配置文件相同
我们可以通过浏览器访问127.0.0.1:80,会出现这个页面,这个页面的配置文件,就是上面的default
- 浏览器访问80端口会自动隐藏,我们看url中如果没有端口,那么实际上端口都是默认的80
双击打开default可以看到default的全貌
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
当前这个是80端口的配置,我们先不要在上面直接改,复制一份搞个备份
然后再到default上进行修改,首先删掉所有注释(只是看起来比较碍眼,已经有备份了,注释删掉也无所谓了)
之后在server中加入两组值,然后把try_files这一行注释掉
- uwsgi_pass是你输入80端口后自动给你重定向到那个地址,这里写127.0.0.1后,如果settings.py中的ALLOW_HOST有你当前的IP,那么别的机子访问你当前的IP也是可以的
- include是引用的文件,引用/etc/nginx/uwsgi_params这个文件,这个文件安装nginx后就自带的
- try_files是将路由搞成一个文件,他尝试去在上面的root中找这个文件,如果没找到就给你404,我们是不希望nginx找文件的,所以屏蔽掉try_files
可以用sudo nginx -t 检测配置文件的语法有没有问题,如果语法没有问题会这样显示
nginx的配置并非只有上面提到的default,nginx包含内容较多,遇到什么问题要具体情况具体分析
搞完上面哪些配置你的nginx就可以运行了
4.2.2 静态文件配置
添加location /static并在其中中加入root,指定root的路径为在项目配置中 STATIC_ROOT的路径(static前一级)
之后修改 /etc/nginx/nginx.conf 中的user,将其改为你当前的用户名
4.3 启动nginx
修改nginx配置后,必须重启nginx才能生效
- 如果未对nginx进行修改,那么只需要重新启动uwsgi就可以了
启动 sudo /etc/init.d/nginx start
停止 sudo /etc/init.d/nginx stop
重启 sudo /etc/init.d/nginx restart
- 在Ubuntu中也可以输入 sudo service nginx start|stop|restart 来启动,停止,重启
我们平时就直接用restart启动了,restart可以在未启动的时候启动
如果我们使用nginx并且想让nginx与uWSGI的通信协议为uwsgi,那么需要在uwsgi.ini中的http改为socket
- 改完之后需要重启uWSGI
socket启动uwsgi与http启动uwsgi的进程数是不一样的,http一共4个进程,socket一共3个进程
这个时候用浏览器直接访问 127.0.0.1/hello_world就可以看到我们的页面了
- 不给端口浏览器默认访问80端口
在响应头中可以看到服务信息
5 常见错误
首先查看日志
在 /etc/nginx/nginx.conf 中有写nginx的两个日志的保存位置
- 异常信息 /var/log/nginx/error.log
- 正常访问信息 /var/log/nginx/access.log
uwsgi的日志我们之前提到过,是uwsgi.log
- 访问127.0.0.1:80,响应502,表示nginx反向代理配置成功,但是uWSGI未启动
- 访问127.0.0.1:80/url,响应404,nginx配置未禁止try_files或者路由不对
- 只开uWSGI时就访问不到,检查uwsgi.ini是否用了http,如果仅用uWSGI使用socket是访问不了的
- 开uWSGI前端显示400,检查setting.py中的ALLOWED_HOST是否有你当前的地址 uWSGI启动后,前端出现400 Bad Request_gymaisyl的博客-CSDN博客
- nginx开后无法访问静态文件,总的来讲是nginx权限不够,检查 /etc/nginx/nginx.conf 的user是否为当前的用户 Django项目部署Nginx后静态文件报403状态码_陈大憨的博客-CSDN博客
6 其他
6.1 自定义错误码页面
- 自定义错误码页面一定要将settings.py中的debug改为False
我们现在的404是这样的
感觉不是很好看,我们可以自己搞一个html,放在模板层中,然后将其命名为404.html
重新启动服务后发现已经换成了我们自定义的页面
除了404之外,400,403,500都可以定制,但我没试过
6.2 邮件告警
- 需要将settings.py中的DEBUG改为False
设置一下django邮箱,不了解的可以看一下这个 30.django发送邮件_Suyuoa的博客-CSDN博客_django 发送邮件
之后加入AMDINS(给谁发),SERVER_EMAIL(email配置的邮箱)
- ADMINS是一个列表,里面可以有多个元组,也就是可以给很多人发。元组的第一个元素是昵称,第二个是元素是邮箱
加入这些配置之后重新启动,之后在网站遇到问题后就自动给你发邮件了
6.2.1 屏蔽post信息
sensitive_post_parameters 是过滤post传参的装饰器
比如现在我有这样一个视图
由于有password / 0 所以肯定会报错,我们用postman发一下
邮件会告诉你详细的信息,包含POST提交了什么,现在我不想让邮件中包含username与password
那么我们就要使用到上面的装饰器 sensitive_post_parameters
重新启动服务后再次用postman发送,发现邮箱里的post中的username与password信息被屏蔽掉了
6.2.2 屏蔽其他变量
你可以加上 sensitive_variables 装饰器来屏蔽一些变量,如果该视图有多个装饰器,需要将 sensitive_variables放在最上面
- 可以不给参数,不给参数就是屏蔽该视图中的所有局部变量
这个就是从数据库中拿出来的信息,这个我就先不做例子了,其实你如果想到不让收件人看直接加上就行了,完事儿你给你自己发一下看看,满意不满意就行了,后面我如果用到了会再补充