zzxworld

使用 Fabric 部署服务端项目

Fabric 是一个 Python 工具库,它基于 SSH(Secure Shell) 协议,可以用来在线上服务器上执行一些 Shell 命令。但同时它也提供了 fab 命令,所以也可以拿来作为一个服务端项目部署工具。

我最早使用 Fabric 的时间可以追溯到它的主版本号还是 1 的时候,在还不太流行 Git 自动化流程部署时简化了我的项目部署工作。而随着之后开始尝试 Git 自动化部署,我就慢慢放弃了使用 Fabric。直到自己又开始折腾一些小项目,又重新拾起了它。在资源有限的条件下,它依然是一件不可多得的利器。目前 Fabric 的主版本号已经到 3。这个版本跟我最早接触的版本相比,在使用方式上已经有了很大变化,所以又得重新了解一遍。

安装 Fabric

首先是安装。作为 Python 库,默认推荐使用 pip 命令:

pip install fabric

不过我是准备作为所有项目的部署工具使用,所以我个人推荐使用系统安装方式。比如在 macOS 上,我使用的是 brew 命令:

brew install fabric

安装结束后,执行一下命令确认是否安装成功:

fab --version

fab 是 Fabric 提供的命令,如果能输出版本号信息,那就没问题了。

小试牛刀

Fabric 的使用很简单,在需要使用它来执行部署命令的项目根目录下创建一个 fabfile.py 文件,然后在这个文件中定义自己的部署任务即可。不过为了使用的更舒服,建议先配置好本机与目标服务器的证书登录。

先来看一个简单的示例:

from fabric import task

@task
def ls_home(server):
    server.run('ls -l')

上面的代码定义了一个查看服务器上用户主目录下文件列表的任务。把上面的代码保存为 fabfile.py 文件,然后打开终端,转入到和这个文件同级的目录下,运行 fab -l 命令,它会输出当前可用的任务列表。

> fab -l
Available tasks:

  ls-home

可以看到,命令输出了一个名称为 ls-home 的可用任务。注意名称中间的横线,看来是 Fabric 转换了任务函数名中的下划线。在命令端使用时需要使用这个输出的名称:

fab ls-home

命令会输出本机当前目录下的文件列表。如果要查看指定服务器的,需要使用 -H 选项指定服务器:

fab -H my-server ls-home

上面的命令如果 SSH 部分配置无误的话,应该会输出服务器上默认登陆用户的主目录文件列表。

注意上面的 my-server 是在 .ssh/config 文件中配置的,这属于 SSH 配置,和 SSH 证书登陆一样,可以简化 Fabric 的操作。

实际使用

以上是比较简单的试用,实际使用时需要根据自己的需求来定义各种任务。比如直接在 fabfile.py 中定义好项目对应的主机:

from fabric import task

hosts = ['my-server']

@task(hosts = hosts)
def deploy(server):
    with server.cd('/projects/zzxworld'):
        server.run('git pull origin master')

这样每次使用 fab 命令时就可以省略掉 -H 选项。

另外为了节省服务器上的硬件资源,对于前端打包这种比较消耗 CPU 的事情,我会放到本地执行,然后再把打包好的代码传到服务器上。执行本地命令的任务示例如下:

from fabric import task
from invoke import run as local

hosts = ['my-server']

@task(hosts = hosts)
def deploy-frontend(server):
    local('rm -rf public/assets')
    local('npm run prod')
    local('scp -r public/assets {}:/projects/zzxworld/public/'.format(hosts[0]))

上面这个前端打包并上传的任务演示了在本地机器上执行命令的方法。搭配线上服务器端的命令执行方式,就可以满足各种部署和运维场景的需求。