(Ubuntu)部署django项目: supervisor + uwsgi + nginx

部署前工作

1. 构建好django项目专属的虚拟环境

可参考:虚拟环境的创建方法

2. 检查:确保在开发环境下django项目能够正常访问

# 进入到django项目目录下,执行以下命令后,浏览器尝试访问
python manage.py runserver 0.0.0.0:8000


Ubuntu下部署django项目

1. 安装nginx

请参考:ubuntu 安装 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

图片.png

从上图可以看出,uwsgi成功启动了一个服务,端口号为9090,浏览器访问结果如下:

图片.png

3. nginx目录下的uwsgi_params文件拷贝到django项目根目录

# 拷贝uwsgi_params (路径经供参考)
sudo cp /etc/nginx/uwsgi_params  /home/leyton/my_pro/

uwsgi_params文件在哪里 ???

# 若不知道文件在哪里,可以通过以下命令查找uwsgi_params文件
sudo find / -name "uwsgi_params"

图片.png

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项目同名目录内层自动生成的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

图片.png

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的权限错误。

图片.png

解决过程:

  • 第一步,将静态资源目录赋予最高权限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启动该进程时,就会出现这种现象。

解决过程:

  1. 手动执行uwsgi启动的命令行,然后查看uwsgi进程是否daemon进程。
# 查看进程是否守护进程的命令
ps -axj|grep uwsgi

图片.png

其中,TTY表示控制终端,TPGID表示终端前台进程组。当TTY=?,TPGID=-1时,即表示该进程是一个daemon进程。

  1. 手动启动uwsgi进程,发现是daemon进程,查看uwsgi的相关配置,最后定位到u的一个配置项daemonize。配置项daemonize不止设置了uwsgi的日志输出路径,还会将uwsgi以守护进程的模式启动。注释掉daemonize配置项后,问题解决。

你可能感兴趣的:((Ubuntu)部署django项目: supervisor + uwsgi + nginx)