使用 Nginx 和 Gunicorn 部署 Django 博客

搭建服务器

本教程使用的本地环境为 Windows 10,服务器环境为 ubuntu 14.04(64 位)。如果你的环境和我的有所差异导致一些命令无法执行,将这些命令转换为你所在环境的命令执行即可。

安装软件

 

顺利连接到远程服务器了。如果是一台全新服务器的话,通常我们是以 root 用户登录的。在 root 下部署代码不安全,最好是建一个新用户(如果你已经以非 root 用户登录的话可以跳过这一步)。下面的一些列命令将创建一个拥有超级权限的新用户:

 
root@localhost:~# useradd -m -s /bin/bash jmp
 
# 把新创建的用户加入超级权限组
root@localhost:~# usermod -a -G sudo jmp
 
# 为新用户设置密码
# 注意在输密码的时候不会有字符显示,不要以为键盘坏了,正常输入即可
root@localhost:~# passwd jmp
 
# 切换到创建的新用户
root@localhost:~# su - jmp
 
# 切换成功,@符号前面已经是新用户名而不是 root 了
jmp@localhost:~$
 
新用户创建并切换成功了。如果是新服务器的话,最好先更新一下系统,避免因为版本太旧而给后面安装软件带来麻烦。运行下面的两条命令:
jmp@localhost:~$ sudo apt-get update
jmp@localhost:~$ sudo apt-get upgrade
 
接下来就可以安装必要的软件了,这里我们需要用到的软件有 Nginx、Pytohn3、Git、pip 和 virtualenv。
jmp@localhost:~$ sudo apt-get install nginx
jmp@localhost:~$ sudo apt-get install git python3 python3-pip
jmp@localhost:~$ sudo pip3 install virtualenv
 

启动 Nginx 服务

Nginx 是用来处理静态文件请求的。比如当我们访问一个博客文章详情页面时,服务器会接收到下面两种请求:

  • 显示文章的详情信息,这些信息通常保存在数据库里,因此需要调用数据库获取数据。
  • 图片、css、js 等存在服务器某个文件夹下的静态文件。

对于前一种请求,博客文章的数据需要借助 Django 从数据库中获取,Nginx 处理不了,它就会把这个请求转发给 Django,让 Django 去处理。而对于后一种静态文件的请求,只需要去这些静态文件所在的文件夹获取,Nginx 就会代为处理,不再麻烦 Django。

用 Django 去获取静态文件是很耗时的,但 Nginx 可以很高效地处理,这就是我们要使用 Nginx 的原因(当然其功能远不止这些)。

通过前面的步骤我们已经安装了 Nginx,并且已经把服务器 IP 绑定了。运行下面的命令启动 Nginx 服务: 
jmp@localhost:~$ sudo service nginx start
 
在浏览器输入域名,看到如下页面说明 Nginx 启动成功了。
 图片


部署代码

部署前的项目配置

Django 项目中会有一些 CSS、JavaScript 等静态文件,为了能够方便地让 Nginx 处理这些静态文件的请求,我们把项目中的全部静态文件收集到一个统一的目录下,这个目录通常位于 Django 项目的根目录,并且命名为 static。为了完成这些任务,需要在项目的配置文件里做一些必要的配置:

blogproject/settings.py
 
# 其他配置...
 
STATIC_URL = '/static/'
# 加入下面的配置
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 

STATIC_ROOT 指明了静态文件的收集目录,即项目根目录(BASE_DIR)下的 static 文件夹。

为了安全起见,在生产环境下需要关闭 DEBUG 选项以及设置允许访问的域名。打开 settings.py 文件,找到 DEBUG 和 ALLOWED_HOSTS 这两个选项,将它们设置成如下的值:

blogproject/settings.py

DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1', 'localhost ', '你个人的IP地址或者域名']
 

项目还会依赖一些第三方 Python 库,为了方便在服务器上一次性安装,我们将全部依赖写入一个叫 requirements.txt 的文本文件中。激活本地的虚拟环境(如果你使用了虚拟环境的话),并进入项目的根目录,运行 pip freeze > requirements.txt 命令:

 这时项目根目录下会生成了一个 requirements.txt 的文本文件,其内容记录了项目的全部依赖。

将代码上传到 GitHub

将代码上传到 GitHub 等代码托管平台,这样我们就可以方便地把代码拉取到服务器了。Git 和 GitHub 的使用相信你已经很熟悉了,这里就不赘述过程。如果不知道如何使用地话可以自行百度相关教程。

注意数据库文件不要上传!

设置服务器目录结构

接下来需要把代码上传到服务器了。我服务器上存放代码的目录结构一般是这样的:

/home/jmp/
    sites/
            env/
            blogproject/
 

 接下来创建虚拟环境,先进入到 sites 目录下,然后运行 virtualenv 命令创建虚拟环境:

jmp@localhost:~/sites$ virtualenv --python=python3 env

注意这里使用 --python=python3 来指定克隆 Python3 的环境。因为 ubuntu 系统默认安装了 Python2,如果不特别指定的话 Virtualenv 默认克隆的是 Python2 的环境。

检查一下虚拟环境是否创建成功,运行 ls 命令列出当前目录下的文件和文件夹,看到 env 这个文件夹说明虚拟环境创建成功。

 接着再从代码仓库把项目代码拉取过来,把 git clone 后的地址换成你自己的 GitHub 仓库地址!

jmp@localhost:~/sites$ git clone https://github.com/jipeng1986/blogproject.git
 
 
多了 blogproject 文件夹(文件夹名称由你的 GitHub 仓库名决定),说明拉取成功了。

安装项目依赖

激活虚拟环境,再进入到项目根目录,即 requirements.txt 所在的目录,安装项目的全部依赖:

jmp@localhost:~/sites$ source env/bin/activate
(env) jmp@localhost:~/sites$ cd django-blog-tutorial/
(env) jmp@localhost:~/sites/blogproject$ pip install -r requirements.txt




 

收集静态文件

虚拟环境下继续运行 python manage.py collectstatic 命令收集静态文件到 static 目录下:

(env) jmp@localhost:~/sites/blogproject$ python manage.py collectstatic
 

生成数据库

虚拟环境下继续运行 python manage.py migrate 命令创建数据库文件:

(env) jmp@localhost:~/sites/blogproject$ python manage.py migrate
 

创建超级用户

虚拟环境下继续运行 python manage.py createsuperuser 命令创建一个超级用户,方便我们进入 Django 管理后台。

(env) jmp@localhost:~/sites/blogproject$ python manage.py createsuperuser
 

配置 Nginx

接下是配置 Nginx 来处理用户请求。

先在服务器的 /etc/nginx/sites-available/ 目录下新建一个配置文件。写上下面的配置内容:

 

/etc/nginx/sites-available/blogproject
 
server {
    charset utf-8;
    listen 80;
    server_name IP地址;
 
    location /static {
        alias /home/jmp/sites/blogproject/static; 
    }
 
    location / {
        proxy_set_header Host $host;
        proxy_pass http://unix:/tmp/IP地址.socket;
    }
}
 
我们在 /etc/nginx/sites-available/ 放置了配置文件,接下来需要创建一个符号链接,把这个配置文件加入到启用的网站列表中去,被启用网站的目录在 /etc/nginx/sites-enabled/,你可以理解为从 sites-available/ 目录下发送了一个配置文件的快捷方式到 sites-enabled/ 目录。具体命令如下:
(env) jmp@localhost:~/sites/blogproject$ sudo ln -s /etc/nginx/sites-available/blogproject /etc/nginx/sites-enabled/blogproject
 
然后需要删除 /etc/nginx/sites-enabled/ 目录下的 default,因为不删除的话,默认找的是 default,导致配置不生效。

 

使用 Gunicorn

Gunicorn 一般用来管理多个进程,有进程挂了Gunicorn 可以把它拉起来,防止服务器长时间停止服务,还可以动态调整 worker 的数量,请求多的时候增加 worker 的数量,请求少的时候减少。

在虚拟环境下,安装 Gunicorn:

(env) jmp@localhost:~/sites/blogproject$ pip install gunicorn
 
用 Gunicorn 启动服务器进程:
(env) jmp@localhost:~/sites/blogproject$ gunicorn --bind unix:/tmp/IP地址.socket blogproject.wsgi:application
 
浏览器输入域名,可以看到访问成功了!


自动启动 Gunicorn

现在 Gunicorn 是我们手工启动的,万一哪天服务器崩溃重启了又得重新手工启动。为此我们写一个自动启动脚本,这样当服务器重新启动后,脚本会帮我们重启 Gunicorn。先按 Ctrl + c 停止刚才启动的服务器进程。

写一个启动脚本,这样当服务器重启后能自动引导 Gunicorn 的启动。脚本位于 /etc/init/ 目录下,且脚本文件名必须以 .conf 结尾:

/etc/init/gunicorn-blogproject.conf
 
start on net-device-up
stop on shutdown
 
respawn
 
setuid jmp
chdir /home/jmp/sites/blogproject
 
exec ../env/bin/gunicorn --bind unix:/tmp/IP地址.socket blogproject.wsgi:application
 

① start on net-device-up 确保只在服务器联网时才启动 Gunicorn。

② 如果进程崩溃了(比如服务器重启或者进程因为某些以外情况被 kill),respawn 将自动重启 Gunicorn。

③ setuid 确保以 jmp用户的身份(换成你自己的用户名)运行 Gunicorn 进程。

④ chdir 进入到指定目录,这里进入项目的根目录。

⑤ exec 执行进程,即开启服务器进程。

现在可以用 start 命令启动 Gunicorn 了:

sudo start gunicorn-blogproject
 
以后如果更新了代码,只要运行下面的命令重启一下 Nginx 和 Gunicorn 就可以使新的代码生效了:
 
sudo service nginx reload
sudo restart gunicorn-blogproject
posted @ 2018-09-07 15:41  黒貓  阅读(318)  评论(0编辑  收藏  举报