Power by GeekHades

利用Nginx+gunicorn+supervisor部署django项目

0x1 前言

最近用Django小试牛刀写了这个简单的Blog。在服务器上部署Django的时候出现过许许多多的问题,网上参差不齐的智商补丁搞得我心慌慌。在看过了各种复制粘贴的技术性文章的以及不管三七二十一就上配置的引导文章,我决定还是去翻阅官方文档。我希望这篇文章可以让大家明白为什么要这样做。而不仅仅是复制配置。

0x2 环境

  • Ubuntu 16.04 LTS
  • Python 3.6
  • Nginx
  • Gunicorn
  • Supervisor

0x3 工具说明

  1. Nginx一款免费开源软件,异步框架的Web服务器,可以用作反向代理,均衡负载以及HTTP 缓存。(WiKi) 为什么部署Django要使用Nginx?在开发过程中当你敲入python3 manage.py runserver的时候Django的默认开启端口是8000。当然你也可以让他绑定其他端口例如:80。我们知道http的默认端口是80,那么是否只要我们在服务器上开启Django绑定80就可以了呢?你可以去尝试之后你就发现一切都变了模样,css找不到js找不到....。是的,这时候就需要Nginx帮我们做一部分事情,他要做的是将一切访问80端口的链接转到Django,指定/static/的目录使得浏览器能够找到我们的资源文件。顺便再帮我们缓存一下HTTP请求。在这里我们并不需要这款强大的软件做太多的事。Nginx的用意说到这里。
  2. Gunicorn Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. (Unix上Python Web服务器网关接口的HTTP服务器),简单点来说就是只要你用Gunicorn来启动Django,他会帮你管理里的项目,处理Nginx转发的请求、Django挂了帮你重新拉起。重要的是他可以帮我们处理Nginx从80端口转发过来的请求。
  3. Supervisor是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程。这里要说一下安装方法: 一般情况下使用pip3 install supervisor安装即可。 但是如果使用Ubuntu的话还可以使用apt-get install supervisor进行安装 supervisor这里的作用是用来管理我们的Gunicorn进程(搭载我们的Django项目)

0x4 配置

我希望读者可以认真阅读完工具说明再来看配置,因为配置很简单,修改几个地方粘贴上去就可以用,但是我希望你能明白原理,因为指不定你在其他地方又会遇到其他的坑,这个时候你如果明白原理就可以去调试。

工欲善其事必先利其器!

  1. 项目结构:
BlogSite
├── LICENSE
├── README.md
├── blog
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── feeds.py
│   ├── migrations
│   ├── models.py
│   ├── search_indexes.py
│   ├── static
│   ├── templatetags
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
│   └── whoosh_cn_backend.py
├── blogproject
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── sqlconfig.txt
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── requirements.txt
  1. 测试Nginx是否正常运行:正常运行输入你的域名或者服务器Ip能看到Nginx的欢迎页面!

  2. 测试你的Gunicorn是否能正常跑你的项目(以我目录结构为例子,要在BlogSite目录下): gunicorn blogproject.wsgi:application -b 0.0.0.0:8000 然后在浏览器输入ip:8000如果能看到你自己写的网页(不管长成啥样!)就是运行成功。

  3. 那么接下来就要使用SuperVisor替我们自启动Gunicorn。网上还有一些方法是配置Gunicorn 然后配置Gunicorn.sock使得能和Nginx通信,请读者自己选择任意一种方式,能跑就行。 /etc/supervisor/supervisor.conf是我的supervisor的配置文件位置 PS:这里你可以新建一个配置文件放在/etc/supervisor/conf.d/下面,也可以在配置文件后面添加。问题都不大。
[program:blogproject]
command=gunicorn blogproject.wsgi:application -b 0.0.0.0:8000  ; 被监控的进程路径
directory=/home/newblog/BlogSite/               ; 执行前要先cd到目录$
autostart=true                ; 随着supervisord的启动而启动
autorestart=true              ; 自动重启。。当然要选上了
startretries=10               ; 启动失败时的最多重试次数
exitcodes=0                   ; 正常退出代码
stopsignal=KILL               ; 用来杀死进程的信号
stopwaitsecs=10               ; 发送SIGKILL前的等待时间
redirect_stderr=true          ; 重定向stderr到stdout
stdout_logfile=/home/newblog/logfile.log        ; 指定日志文件
; 默认为 false,如果设置为 true,当进程收到 stop 信号时,会自动将该信号发给该进$
stopasgroup=true             ; send stop signal to the UNIX process
; 默认为 false,如果设置为 true,当进程收到 kill 信号时,会自动将该信号发给该进$
killasgroup=true             ; SIGKILL the UNIX process group (def false)

只需要修改command中的wsgi的选项、directory以及stdout_logfile属性即可。

  1. 测试Supervisor能够启动Gunicorn。 supervisorctl start blogproject (blogproject)是配置中的进程名称。 同样如果访问ip:8000端口还是能看到网页内容那就说明成功。(这时你的静态文件也还是加载不到的)

  2. 配置Nginx。目的是让Nginx转发所有80端口的访问到8000,配置static的路径。 这里需要注意:需要你在Django项目使用 python3 manage.py collectstatic生成静态资源。 Nginx的配置文件可以直接在/etc/nginx/sites-enabled/default中添加。 也可以新建一个conf文件。 这里我使用新建conf文件的方法 /etc/nginx/sites-enabled/blog_site

server {
    listen 80;
    server_name geekhades.cc;          # 这里需要你去修改为你自己的域名。
    server_name_in_redirect off;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_pass_header       Authorization;
        proxy_pass_header       WWW-Authenticate;
        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 /home/newblog/BlogSite/static/;   #这里改成你自己的静态目录路径
    }
}

location \ 是匹配所有访问80端口的请求 proxy_pass http://127.0.0.1:8000是将请求转发到127.0.0.1:8000

网上有一些其他的配置文件中是

location /static/ {
     root /home/newblog/BlogSite/static/;  
}

这样的。但是我亲测不行。

0x5 Run

配置完成之后使用 nginx -t && service nginx reload or nginx -t && service nginx restart 重新加载或者运行Nginx。 最后在浏览器中输入ip地址或者域名不需要加端口号就可以访问到你的Django网站。并且所有资源都能正常加载。

如果还是显示Nginx的欢迎页面,有可能是缓存的问题,刷新一下就行。

最后预祝大家新年快乐!学习进步。



* 如果你对文章有任何意见或建议请发 邮件 给我!
* if you have any suggestion that you could send a E-mail to me, Please!