背景

最近有一个Django项目需要部署到服务器,这之前没搞过这个啊,历经一番查询之后,决定使用supervisor+gunicorn+nginx来部署这个Django项目,然后经过一番折腾,总算是顺利跑起来了,于是便有了这篇文章,全当是做个记录了

操作步骤

  • 使用gunicorn运行django项目
  • 使用supervisor管理gunicorn进程
  • 使用nginx配置web

有了以上思路,那么接下来就一步步搞定就完事了

  • 先测试Django项目是否运行正常

    • 首先进入项目所在位置(假设为/var/www/site): cd /var/www/site
    • 创建虚拟环境(假设为venv):virtualenv venv
      • 如果没有安装 virtualenv, 则先安装:pip3 install virtualenv
    • 激活虚拟环境: source venv/bin/activate
    • 安装所需依赖(假设都已经在requsetments.txt里面了):pip install -r requestments.txt
    • 运行Django项目:python manage.py runserver
    • 此时会在命令行窗口显示运行信息,没有问题的话会显示默认的ip和port(http://127.0.0.1:8000),可以把127.0.0.1替换为服务器地址,访问看是否正常。如果一切正常,那么测试OK,有问题的话先修复相应的问题再继续接下来的操作。
  • 安装gunicron并测试
    Gunicorn 绿色独角兽’是一个Python WSGI UNIX的HTTP服务器。这是一个pre-fork worker的模型,从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器大致与各种Web框架兼容,只需非常简单的执行,轻量级的资源消耗,以及相当迅速。

    • 安装:sudo apt install gunicron
    • 简单测试
      • 进入到项目目录:cd /var/www/site
      • 测试:gunicorn siteapp.wsgi:application -b 127.0.0.1:8000 (siteapp根据自己的项目修改)
      • 进行测试,看看有没有问题,有问题则根据报错修改,没问题继续
    • 为了方便操作,决定使用shell脚本启动supervisor来运行Django项目,参考脚本如下:
      #!/bin/bash
      
      NAME="siteapp"
      USER=root # 用户配置,需要有项目的读写权限,对log的写入权限
      WORKERS=2
      DJANGODIR=/var/www/site
      ENV_ACTIVATE_PATH=$DJANGODIR/venv/bin/activate
      DJANGO_WSGI_MODULE=${NAME}.wsgi
      PID_PATH=/tmp/gunicorn.${NAME}.pid
      
      source $ENV_ACTIVATE_PATH
      #cd ${DJANGODIR}
      
      exec gunicorn ${DJANGO_WSGI_MODULE}:application \
      	--name $NAME \
      	--user $USER \
      	--pid $PID_PATH \
      	--workers $WORKERS \
      	--bind=127.0.0.1:5785 \ # 指定绑定端口
      	--log-level=info \ # 日志级别
      	--access-logfile=${DJANGODIR}/logs/gunicorn.access.log \
      	--error-logfile=${DJANGODIR}/logs/gunicorn.error.log
      
    • 将以上脚本内容保存为run.sh,并给与执行权限chmod +x run.sh,执行查看是否正常: ./run.sh
    • 一切OK的话,就完成了gunicron的配置了,继续下一步
  • 安装supervisor并测试
    supervisor就是用Python开发的一套通用的进程管理程序.能将一个普通的命令行(supervisorctl start appname)进程变为后台驻留程序(daemon),并监控进程状态,异常退出时能自动重启。

    • 安装:sudo apt install supervisor
    • supervisor配置文件: sudo vim /etc/supervisor/conf.d/siteapp.conf,内容如下
      [program:siteapp]
      autorestart=True                                        ; 程序异常退出后自动重启
      autostart=True                                          ; 在 supervisord 启动的时候也自动启动
      redirect_stderr=True                                    ; 把 stderr 重定向到 stdout,默认 false
      environment=PATH="/var/www/site/venv/"                  ; 可以通过 environment 来添加需要的环境变量,一种常见的用法是使用指定的 virtualenv 环境
      command=/var/www/site/run.sh                            ; 启动命令,与手动在命令行启动的命令是一样的
      user=root                                               ; 用哪个用户启动
      directory=/var/www/site                                 ; 程序的启动目录
      stdout_logfile_maxbytes=20MB                            ; stdout 日志文件大小,默认 50MB
      stdout_logfile_backups=20                               ; stdout 日志文件备份数
      stdout_logfile=/var/www/site/logs/supervisor.log        ; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
      
    • 运行supervisor:sudo supervisorctl start siteapp
      • 运行时会输出状态:siteapp: started
      • 查看状态:sudo supervisorctl status siteapp,例如:
        siteapp                             RUNNING   pid 39764, uptime 0:59:39
        
        状态对照表如下:
        STOPPED:进程因为停止请求而停止,或从未启动过
        STARTING:过程因为启动请求,正在启动中
        RUNNING:进程正常运行中
        BACKOFF:进程进入了STARTING状态,但随后退出太快而无法转移到RUNNING状态。
        STOPPING:进程由于停止请求正在停止中
        EXITED:进程从RUNNING状态退出(可能正常,也可能异常)
        FATAL:进程无法成功启动
        UNKNOWN:未知状态(考虑supervisor出错)
        
      • 一切OK的话,就完成了supervisor的配置了,继续下一步
  • 安装nginx并测试
    Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。

    • 安装:sudo apt install nginx
    • 输入IP便能看到Nginx的测试界面,表明没有问题
    • 配置网站: vim /etc/nginx/sites-enabled/siteapp.conf,参考内容如下:
      server {
      	listen 80;
      	# listen 443 ssl; # 配置443端口
      	server_name example.com;
      	
      	access_log /var/www/site/logs/access.log;
      	error_log /var/www/site/logs/error.log;
      	
      	location / {
      		proxy_pass http://127.0.0.1:5785;
      		proxy_set_header Host $host;
      		proxy_set_header X-Real-IP $remote_addr;
      		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      	}
      	
      	# 静态资源目录
      	location /static/ {
      		alias /var/www/site_static/;
      		expires 30d;
      	}
      	
      	location ~ /\. {
      		access_log off; log_not_found off; deny all;
      	}
      }
      
    • 执行nginx -t,检查配置是否正确,输出successful代表配置没问题,例如:
      # 输出successful代表配置没问题
      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      nginx: configuration file /etc/nginx/nginx.conf test is successful
      
      # 输出failed代表配置有问题,此时按照提示修改
      nginx: [emerg] invalid parameter "server_name" in /etc/nginx/sites-enabled/default:14
      nginx: configuration file /etc/nginx/nginx.conf test failed
      
    • 如果检查没问题,重新载入nginx配置,使其生效:nginx -s reload

至此,项目部署完成,部署完成,一步步走下来,多多少少会有些问题,按照提示解决就行了。

参考文章

Django项目部署: supervisor+gunicorn+Nginx
supervisor 状态state汇总

更多推荐