第 9 章 使用 Fabric 自动部署

手动部署过渡服务器的意义通过自动部署才能体现出来。部署的过程能重复执行,我们才能确信部署到生产环境时不会出错。

使用 Fabric 可以在服务器中自动执行命令。可以系统全局安装 Fabric,因为它不是网站的核心功能,所以不用放到虚拟环境中,也不用加入 requirements.txt 文件。在本地电脑中执行下述命令安装 Fabric:pip install fabric

在 Windows 中安装 Fabric

Fabric 依赖于 pycrypto,而这个包需要编译。在 Windows 中编译相当痛苦,所以使用别人预先编译好的二进制安装程序往往更快捷。Michael Foord 提供了一些预先编译好的 pycrypto Windows 二进制安装程序arrow-up-right

在 Windows 中安装 Fabric 的过程如下:

  • 从前面提供的地址下载并安装 pycrypto

  • 使用 pip 安装 Fabric

还有一个预编译好的 Python 包 Windows 安装程序源arrow-up-right也很棒,由 Christoph Gohlke 维护。

Fabric 的使用方法一般是创建一个名为 fabfile.py 的文件,在这个文件中定义一个或多个函数,然后使用命令行工具 fab 调用:fab function_name, host=SERVER_ADDRESS。这个命令会调用名为 function_name 的函数,并传入要连接的服务器地址 SERVER_ADDRESS。fab 命令还有很多其他参数,可以指定用户名和密码等,详情可执行 fab --help 命令查阅。

9.1 分析一个 Fabric 部署脚本

Fabric 的用法,通过实例来说明,以下这个脚本自动执行前一章用到的所有部署步骤。在这个脚本中,主函数是 main,我们在命令行中要调用的就是这个函数。除此之外,脚本中还有多个辅助函数。从命令行传入的服务器地址保存在 env.host 中。

from fabric.contrib.files import append, exists, sed
from fabric.api import env, local, run

__author__ = '__L1n__w@tch'

# 要把常量 REPO_URL 的值改成代码分享网站中你仓库的 URL
REPO_URL = "https://github.com/L1nwatch/PythonWeb.git"


def deploy():
    # env.host 的值是在命令行中指定的服务器地址,例如 watch0.top, env.user 的值是登录服务器时使用的用户名
    site_folder = "/home/{}/sites/{}".format(env.user, env.host)
    source_folder = site_folder + "/source"

    _create_directory_structure_if_necessary(site_folder)
    _get_latest_source(source_folder)
    _update_settings(source_folder, env.host)
    _update_virtualenv(source_folder)
    _update_static_files(source_folder)
    _update_database(source_folder)

创建目录结构的方法如下,即便某个文件夹已经存在也不会报错:

然后拉取源码:

为了让这个脚本可用,你要执行 git push 命令把本地仓库推送到代码分享网站,这样服务器才能拉取仓库,再执行 git reset 命令。如果你遇到 Could not parse object 错误,可以执行 git push 命令。

然后更新配置文件,设置 ALLOWED_HOSTSDEBUG,还要创建一个密钥:

有些人,建议使用环境变量设置密钥等,你觉得在你的环境中哪种方法安全,就使用哪种方法。

接下来创建或更新虚拟环境:

更新静态文件只需要一个命令:

最后,执行 manage.py migrate 命令更新数据库:

9.2 试用部署脚本

可以在现有的过渡服务器中使用这个部署脚本——这个脚本可以在现有的服务器中运行,也可以在新服务器中运行。如果再次运行,这个脚本不会做任何操作。

配置 Fabric

如果使用 SSH 密钥登录,密钥存储在默认的位置,而且本地电脑和服务器使用相同的用户名,那么无需配置即可直接使用 Fabric。如果不满足这几个条件,就要配置用户名、SSH 密钥的位置或密码等,才能让 fab 执行命令。

这几个信息可在命令行中传给 Fabric。更多信息可执行 fab --help 命令查看,或者阅读 Fabric 的文档arrow-up-right

9.2.1 部署到线上服务器

下面在线上服务器中试试这个脚本:

【个人实践】

9.2.2 使用 sed 配置 Nginx 和 Gunicorn

把网站放到生产环境之前,根据配置笔记,还要使用模板文件创建 Nginx 虚拟主机和 Upstart 脚本。使用 Unix 命令行工具完成:

sed(stream editor, 流编辑器)的作用是编辑文本流。Fabric 中进行文本替换的函数也叫 sed,这并不是巧合。这里,使用 s/replaceme/withthis/g 句法把字符串 SITENAME 替换成网站的地址。然后使用管道操作(|)把文本流传给一个有 root 权限的用户处理(sudo),把传入的文本流写入一个文件,即 sites-available 文件夹中的一个虚拟主机配置文件。

现在可以激活这个文件配置的虚拟主机:

然后编写 Upstart 脚本:

最后,启动这两个服务:

成功运行后可以提交把 fabfile.py 添加到仓库中:

9.3 使用 Git 标签标注发布状态

最后还要做些管理操作。为了保留历史标记,使用 Git 标签(tag)标注代码库的状态,指明服务器中当前使用的是哪个版本:

现在,无论何时都能轻易地查看当前代码库和服务器中的版本有何差异。看一下提交历史中的标签:

9.4 延伸阅读

可以考虑使用 Fabric 的替代品 Ansible。

自己的测试:

自己编写的 fabfile.py 能够完成从 git 库一直到配置 nginx 和 gunicorn 了,以下完整的步骤(假定当前是一个刚装好的 Ubuntu 系统):

Last updated