django部署:nginx+virtualenv+uwsgi+supervisor


visibility 561 message 0 schedule 2018年2月27日 18:20 account_circle huazhaozhe


前言

        django是一个旨在快速开发的web框架,django为我们已经做好了大多数工作,通过MVT模型,我们可以快速的搭建出自己所需的项目.然而另一方面,django强大的同时其配置项目比较多.django的部署步骤也不算少,本文主要记录django部署到Ubuntu16.04上的主要步骤.

 

基本流程

  1. 使用Nginx+uwsgi+supervisor
    这样大体的流程是:nginx作为服务器最前端,负责接收client的所有请求,统一管理.静态请求由Nginx自己处理.非静态请求通过uwsgi传递给django,由django来进行处理,从而完成一次web请求.而supervisor用来管理uwsgi进程,包括启动停止重启,服务器开机启动,意外情况错误尝试重启进程.
  2. 通信请求流程
    web client <-> web server(nginx) <-> socket <-> uwsgi <-> django

 

环境配置

        安装nginx, supervisor, python3,git

sudo apt-get install nginx supervisor python3 git

        安装virtualenv

        服务器不安装virtualenvwrapper,为每个网站单独创建虚拟环境env.本地调试安装了virtualenvwrapper

pip install virtualenv

        创建存放网站的文件夹,这里我push到github,再把项目clone到服务器上所以不需要创建项目目录了

mkdir ~/django
cd ~/django

         将项目clone到服务器django目录下,进入项目主目录:

git clone https://github.com/huazhaozhe/django-myblog.git
cd django-myblog
ls -la    #查看clone的项目

        创建虚拟环境

        django用python3编写,这里需要指定python版本

virtualenv env python=python3
source env/bin/activate

        此时终端前面提示有(env)字样,不同终端可能不同,检查python版本是否为python3

python -V    #输出看到Python 3.x.x即可

        安装项目依赖

pip install -r requirements.txt
pip list   #查看虚拟环境安装的依赖

  

项目配置

      编辑config.py

        我将settings中的配置写到了config.py中比较方便,更安全的方法是设置环境变量了

vi config.py

#config.py填入以下代码并保存,敏感信息已经隐去

from socket import gethostname, gethostbyname

django_data = {
    'SECRET_KEY' : 'xxxxxxxxxxxxxxxxxx',
    'DEBUG' : False,
    'ALLOWED_HOSTS' : ['x.x.x.x', 'x.x.x.x'],
    'GITHUB_ID' : 'xxxxxxxx',
    'GITHUB_KEY' : 'xxxxxxxxxxxxxxxxxxxx',
    'SITE_URL' : 'xxxxxxxx',
    'ADMINS_NAME' : 'xxxxx',
    'ADMINS_EMAIL' : 'xxxxxxx',
    'EMAIL_HOST_USER' : 'xxxxxx',
    'EMAIL_HOST_PASSWORD' : 'xxxxxxxxxx',
}

        收集静态文件创建数据库

        注意django调试时(DEBUG=True)和部署关闭调试时(DEBUG=False),静态文件不一样

python manage.py collectstatic    #以后再次执行这个命令需要你输入yes确认覆盖以前的静态文件
python manage.py makemigrations   #创建/更新数据库迁移
python manage.py migrate          #创建/更新数据库
python manage.py createsuperuser  #创建管理员

        至此可以先试一下项目是否能够运行,在你的浏览器输入你的域名或者IP地址:8000,就能够访问了你的django网站了

python manage.py runserver 0.0.0.0:8000      #允许外网访问,当config.py中DEBUG为False时,还需要配置config.py中的ALLOWED_HOSTS

        这个命令只是调试时使用的测试命令,虽然django能够正常运行,要网站稳定运行,要考虑服务器故障,重启时django尽量不受影响,还需要使用进程管理,nginx或者Apache专业服务器.

 

uWSGI部分

        编写uwsgi.ini文件

        这里注意不需要配置daemonize选项, supervisor只能监控前台任务,所以supervisor启动的程序需要能够输出到控制台,否则出现错误BACKOFF  Exited too quickly (process log may have details), supervisor的stdout_logfile和stderr_logfile选项将控制台输出的信息输出到指定的文件中.

[uwsgi]

chdir = /home/ubuntu/django/django-myblog                        #项目根目录
module = djangoblog.wsgi:application                             #wsgi模块,django已经生成的有了
socket = /home/ubuntu/django/django-myblog/uwsgi.sock            #这里使用了socket,没有固定端口
master = true                                                    #
processes = 4                                                    #进程个数
pidfile = /home/ubuntu/django/django-myblog/uwsgi.pid            #pid文件
vaccum = true                                                    #结束时清理环境
#daemonize = /home/ubuntu/django/django-myblog/log/uwsgi.log     #控制台输出,使用supervisor这个就不需要了

         测试

uwsgi --ini uwsgi.ini          #此时能够看到控制台输出无错误提示

 

配置nginx

        前面已经安装了nginx,可以先试试直接访问服务器出现Welcome nginx!即说明nginx安装成功.接下来配置nginx

sudo service nginx start/restart/stop      #nginx服务启动/重启/停止

        在nginx中,/etc/nginx/sites-enabled/下的文件是nginx需要nginx提供服务的网站,这些文件都是/etc/nginx/sites-available/文件夹下配置文件的软连接,即/etc/nginx/sites-available文件夹下的文件才是网站配置文件存放的地方

sudo rm /etc/nginx/sites-enabled/default           #删除nginx默认软连接

        新建django的nginx配置文件

sudo vi /etc/nginx/sites-available/djangoblog

#在djangoblog文件中填入以下内容并保存:

server {
    charset utf-8;
    listen 80;                                                                   #监听80端口

    access_log /home/ubuntu/django/django-myblog/log/access.log;                 #访问记录log文件路径            
    error_log /home/ubuntu/django/django-myblog/log/nginx.error.log error;       #错误记录log文件路径

    location /static {
        alias /home/ubuntu/django/django-myblog/collected_static;                #网站静态文件路径,部署时django处理动态网页,静态文件都交给nginx处理
    }

    location / {
        include uwsgi_params;                                                    #nginx自带有uwsgi接口
        uwsgi_connect_timeout 30;                                                #uwsgi接口超时时间
        uwsgi_pass unix:/home/ubuntu/django/django-myblog/uwsgi.sock;            #将动态请求转发给uwsgi,这里与前面uwsgi.ini文件一致
   }
}

        创建软连接,让网站配置生效

sudo ln -s /etc/nginx/sites-availabe/djangoblog /etc/nginx/sites-enabled/djangoblog
sudo service nginx restart           #重启nginx服务,检查配置文件是否有错误

        测试

        再次运行uwsgi,此时浏览器访问服务器不需要加上端口号即可正常访问

uwsgi uwsgi.ini

        到这里部署已经完成三分之二了clap

 

使用supervisor

        supervisor只能监控前台进程,当进程出现错误或者服务器重启时,supervisor都能够自动拉起进程,保证uwsgi随时能够提供服务

sudo supervisorctl start programname        #启动program
sudo supervisorctl stop programname         #停止program
sudo supervisorctl reload                   #重新载入配置文件并启动那些设置了自启动的program

        配置supervisor的django任务文件

sudo vi /etc/supervisor/conf.d/djangoblog.conf

在djangoblog.conf中填入以下内容并保存

[program:django]

user = ubuntu       #执行进程的用户
command = /home/ubuntu/django/django-myblog/env/bin/uwsgi /home/ubuntu/django/django-myblog/uwsgi.ini   #启动命令

autostart = true            #自动启动
autorestart = true          #自动重启
stopasgroup = true          #进程杀死时,向进程组发送stop信号,包括子进程
killasgroup = true          #向进程发送kill信号,包括子进程
stdout_logfile = /home/ubuntu/django/django-myblog/log/supervisor_uwsgi_out.log       #控制台输出log文件路径,其实是uwsgi的控制台输出log
stderr_logfile = /home/ubuntu/django/django-myblog/log/supervisor_uwsgi_err.log       #控制台错误log文件路径

        最后一步,启动django任务,提示django started说明启动成功

sudo supervisorctl start django

        这时使用浏览器访问你的网站应该能够正常访问了.部署到此overok_hand

 

部署中出现的问题

        因为Linux发行版本不同,甚至提供服务器的不同厂商提供的同一个Linux发行版本之间也可能不同,另外同一Linux发行版本自家也有不同的版本,同一版本每个厂商初始安装时环境也可能不一样,搭建环境时可能出现问题,一般根据错误提示即即可解决,不行就先百度,看两分钟没解决,就直接Google,别再百度那浪费时间.

        pip安装uWSGI中失败

        一开始时没有安装gcc,build时失败了,意思是没有C语言库?,索性gcc和g++一起安装了

sudo apt-get install gcc g++

        然后执行到import wheel某个地方错误,明明创建虚拟环境时就已经安装了wheel,怎么会出错,搜索得知安装python3-dev即可解决

sudo apt-get install python-dev python3-dev    #这里我python-dev和python3-dev都安装了

        DEBUG为False时400 Bad request

        检查settings中ALLOWED_HOSTS的值,这里设置在config.py中,调试时可以设置为['*'],正式运行一般设为允许本地和自己服务器访问即可,即['127.0.0.1', 'localhost', '服务器域名或者ip地址']

        nginx权限不足

        使用nginx+uwsgi时,nginx和uwsgi之间通过socket通讯时,nginx可能权限不足或者nginx运行的用户不对,解决方法:

  1. nginx以root方式运行,修改/etc/nginx/nginx.conf中的user,默认为www-data,新安装的服务器可能都没这个用户的
  2. 一样是修改nginx运行用户,修改成启动uwsgi进程的用户,使用supervisor时supervisor配置文件中的user设置与nginx配置文件user运行用户一样即可
  3. 启动uwsgi进程过后,修改uwsgi.sock文件的读写权限,比如:sudo chmod 0666 /home/ubuntu/django/django-myblog/uwsgi.sock
  4. 使用固定端口方式,同样需要nginx中uwsgi_pass和uwsgi.ini文件中一样,比如nginx中uwsgi_pass 127.0.0.1:8080;,uwsgi.ini中socket=127.0.0.1:8080

        静态文件400       

        能够访问网站,网站只有文字没有任何样式图片动画,不能获取所有的静态文件,在浏览器调试模式发现下静态文件都是400.

        django本地调试时和部署上线静态文件处理时不一样的,使用nginx时,只需要将动态请求转发给django,静态文件交给nginx处理,处理静态文件也是nginx优势所在.

        django部署时需要执行python manage.py collectstatic命令,这个命令将django用到的静态文件收集起来放到settings中STATIC_ROOT所指定的文件夹中,这个文件夹不需要在django项目目录下,在nginx中将静态文件使用alias指定到到STATIC_ROOT即可,比如

    location /static {
        alias /home/ubuntu/django/django-myblog/collected_static;       #网站静态文件路径,部署时django处理动态网页,静态文件都交给nginx处理,media文件亦可参照
    }

 

总结

        如前言中所述,django强大但设置项目多,部署django也是比较麻烦一点,不过自己亲自动手实践,困难是不存在的.

        另外使用fabric和git结合自动部署也很快的,部署过一次django过后就很轻松了,哈哈sunglasses



共有0条评论
登录 发表评论
    account_balance