部署前工作
1. 构建好django项目专属的虚拟环境
可参考:虚拟环境的创建方法
2. 检查:确保在开发环境下django项目能够正常访问
# 进入到django项目目录下,执行以下命令后,浏览器尝试访问
python manage.py runserver 0.0.0.0:8000
Ubuntu下部署django项目
1. 安装nginx
2. 安装uwsgi(在django项目虚拟环境下)
为什么要使用uwsgi ???
Django 所提供的是一个开发服务器,这个开发服务器,没有经过安全测试,而且使用的是 Python 自带的 simple HTTPServer 创建的,在安全性和效率上都是不行的。
而uWSGI 是一个全功能的 HTTP 服务器,他要做的就是把 HTTP 协议转化成语言支持的网络协议。比如把 HTTP 协议转化成 WSGI 协议,让 Python 可以直接使用。
uwsgi 是一种 uWSGI 的内部协议,使用二进制方式和其他应用程序进行通信。
# 使用pip安装,不要用apt安装,否则会遇到各种错
pip install uwsgi
# 测试是否安装成功,在当前目录下创建文件test.py
touch test.py
vim test.py
# 写入如下内容
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello Uwsgi"]
# 保存退出后执行命令启动, 端口号且指定为9090
uwsgi --http :9090 --wsgi-file uwsgi_test.py
从上图可以看出,uwsgi成功启动了一个服务,端口号为9090,浏览器访问结果如下:
3. nginx目录下的uwsgi_params文件拷贝到django项目根目录
# 拷贝uwsgi_params (路径经供参考)
sudo cp /etc/nginx/uwsgi_params /home/leyton/my_pro/<django_project>
uwsgi_params文件在哪里 ???
# 若不知道文件在哪里,可以通过以下命令查找uwsgi_params文件 sudo find / -name "uwsgi_params"
4. 项目根目录下,创建uwsgi配置文件
- chdir:表示项目的根目录
- wsgi-file:后者表示wsgi.py文件的位置,一般在项目根目录下有一个同名的目录
mkdir uwsgi && cd uwsgi
vim my_uwsgi.conf
# 写入以下内容
[uwsgi]
# django项目运行的端口号
socket = 127.0.0.1:8002
# django项目的根目录,同名目录的外层
chdir = /home/leyton/my_pro/<django_project>/
# django项目同名目录内层自动生成的wsgi.py的路径,如果你的项目叫taobao,就填taobao/wsgi.py
wsgi-file = mysite/wsgi.py
# 开启主进程
master = true
# 最大进程数量
processes = 4
# 最大线程数量
threads = 2
# 停止uwsgi时自动清理
vacuum = true
# 指定后台输出日志信息的文件,如果遇到不能正常使用,可以使用cat /var/log/uwsgi_log.log查看报错信息。
# 注意坑点!!!daemonize是守护进程&输出日志配置项;logto是输出日志配置项。
# - 当使用配置项daemonize时,不仅指定uwsgi输出日志,还会使得uwsgi本身以守护进程的模式运行。
# - 故而,当uwsgi要以非daemon进程运行时,需将daemonize替换成logto。
daemonize = /var/log/uwsgi_log.log
# 指定运行时候的pid文件,也可以用来停止进程, uwsgi --stop /var/run/uwsgi_pid.log
pidfile = /var/run/uwsgi_pid.log
# 指定虚拟环境目录,如果没有使用虚拟环境可以不用指定
home = /venv/
5. nginx配置
# 进入nginx配置文件所在目录:/usr/local/nginx/conf.d
cd /usr/local/nginx/conf.d
# 配置my.conf文件(若无则创建)
vim my.conf
# 写入以下内容
server {
listen 80;
server_name xxx.com www.xxx.com;
charset utf-8;
client_max_body_size 75M;
# 静态资源管理
location /static {
alias /home/leyton/my_pro/mysite/static;
}
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8002;
#include /home/leyton/my_pro/mysite/uwsgi_params;
}
}
6. 重启nginx(若已使用supervisor管理nginx,可直接通过supervisor重启nginx)
# 重启nginx
sudo /etc/init.d/nginx restart
7. 静态文件的处理(以方便nginx管理静态资源)
# 进入django项目中, 打开setting.py文件,添加如下配置项,
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
# 编辑完settings.py后,执行如下命令,以收集所有静态文件到STAICI_ROOT目录
python manage.py collectstatic
8. 直接使用uwsgi启动项目(!!!不推荐:因为无法保证稳定性)
# 进入到uwsgi配置目录,执行如下命令
uwsgi --ini my_uwsgi.ini
# 查看进程是否起来,若服务异常,则查看uwsgi的日志解决问题
ps -ef |grep uwsgi
9. 通过supervisor启动并监控守护uwsgi服务(推荐!!!)
supervisor配置进程管理的步骤, 可参考文档:supervisor: 基于python开发的通用进程管理工具
[program:customer-position]
directory = /home/ubuntu/customer-position-8901/
command = /home/ubuntu/customer-position-8901/venv/bin/uwsgi --ini uwsgi/my_uwsgi.ini
startsecs = 5
user = root
autostart = true
autorestart = true
stdout_logfile = /var/log/supervisor/customer-position.log
stderr_logfile = /var/log/supervisor/customer-position_error.log
10. 问题记录
1. 加载静态资源,报错:403
由于静态资源是由nginx进行管理的,查看nginx的日志文件,发现nginx错误日志中静态文件访问都出现 Permission denied的权限错误。
解决过程:
- 第一步,将静态资源目录赋予最高权限777,未能解决问题;
- 第二步,在nginx.conf配置文件头部添加user root,成功解决问题;
2. 通过supervisor启动uwsgi进程,发现supervisor会反复重启uwsgi进程,最终supervisor上报FATAL错误;而执行命令:ps -ef |grep uwsgi后发现,uwsgi是正常开启的。
原因:
因为supervisor无法监控以守护进程模式启动的程序,supervisor只能监控非daemon进程,然后由supervisor来将这个非daemon进程转为daemon进程。
当进程本身就是daemon进程,然后又通过supervisor启动该进程时,就会出现这种现象。
解决过程:
- 手动执行uwsgi启动的命令行,然后查看uwsgi进程是否daemon进程。
# 查看进程是否守护进程的命令
ps -axj|grep uwsgi
其中,TTY表示控制终端,TPGID表示终端前台进程组。当TTY=?,TPGID=-1时,即表示该进程是一个daemon进程。
- 手动启动uwsgi进程,发现是daemon进程,查看uwsgi的相关配置,最后定位到u的一个配置项daemonize。配置项daemonize不止设置了uwsgi的日志输出路径,还会将uwsgi以守护进程的模式启动。注释掉daemonize配置项后,问题解决。