Hexo 的 Rsync 部署方式,实际是执行 Rsync 命令通过 SSH 连接服务器进行文件同步。下面就是 Hexo 根据默认配置实际执行的 Rsync 命令:

$ rsync --delete -v -az -e "ssh -p 端口号" /path/to/public/ 用户名@服务器IP:/path/to/root

所以,要使用这用部署方式,你要有一台服务器,本地和服务器都必须安装 Rsync,并且有一个可以通过 SSH 密钥登录服务器的账号。当然,首先需要在 Hexo 初始化的目录下安装 Rsync 插件:

$ npm install hexo-deployer-rsync --save

有关如何使用 SSH 密钥登录服务器网上有很多教程,在此不做赘述。

一、安装 Rsync

Linux 系统安装 Rsync 非常简单,使用 yum 或者 apt-get 安装即可,有的 VPS 服务商提供的系统镜像中已经默认安装了 Rsync 。可以使用 which rsync 命令查看是否已安装。

$ # 查看是否已存在
$ which rsync
$ # centOS
$ sudo yum install rsync
$ # Ubuntu & Debian
$ sudo apt-get insatll rsync

OS X 系统已经预装了 Rsync。

Windows 系统就稍微麻烦一点,Windows 上需要安装的软件是 cwRsync。cwRsync 的客户端可以与 Linux系统上的 Rsync 进行文件传输。cwRsync 官方目前已不再提供免费版,收费版 39 美元一年,不过还是可以找到以前发布的 4.1.0 免费版客户端(cwRsync 的安装程序分为客户端和服务端),另外,还可以使用 Chocolatey(类似 Linux 上的 yumapt-get)来安装 cwRsync,上面最新的免费版客户端版本是 5.5.0。安装完 cwRsync 客户端后,需要将安装目录下的 bin 目录的完整路径添加进 Windows 系统环境变量中的 path 变量(再次强调:系统环境变量,不是用户环境变量),这样才能在任意位置使用 rsync 命令。配置好环境变量后然后按 win + r 快捷键调出运行窗口,输入 cmd 回车打开命令窗口。在命令窗口输入 rsync 命令就可以看到帮助信息了。值得一提的是,可以在 cwRsync 的 bin 目录中看到 ssh-keygen 等脚本,也就是说不用安装 git 也可以使用 ssh-keygen 命令了。

二、配置 Hexo

打开 Hexo 的配置文件 _config.yml,关于部署的配置如下:

deploy:
  type: rsync
  host: <host>
  user: <user>
  root: <root>
  port: [port]
  delete: [true|false]
  verbose: [true|false]
  ignore_errors: [true|false]

参数介绍:

参数 描述 默认值 对应 Rsync 命令选项
host 远程主机的地址 服务器 IP
user SSH 用户名 用户名
root 要同步到服务器的哪个目录下 /path/to/root
port SSH 端口 22 端口号
delete 删除远程主机上的旧文件 true –delete
verbose 显示调试信息 true -v
ignore_errors 忽略错误 false –ignore-errors

其中 deletverboseignore_errors 这三个参数推荐按照默认值进行配置。

port 是服务器的 SSH 端口,系统默认的 SSH 端口都是 22,而不是文档说的 Rsync 的监听端口(默认 873)。

配置到这里,至少和服务器的通信是没有问题的。也就是说,Hexo 这时候是可以使用 Rsync 命令来启动服务器上的 Rsync命令了。如果你足够”幸运”的话,现在已经可以使用 hexo g 命令来部署你的网站了。同样,你也可以用文章最开始的那个 Rsync 命令同步你的网站到服务器了。如果失败了,接着往下看。

三、可能遇到的问题

3.1 权限问题

如果你和我一样使用非 Root 用户来登录服务器,而网站目录又必须以 Root 权限操作,那么就会出现含有 failed: Permission denied 的权限错误信息。解决方法很简单:在配置文件上追加一个 args 参数:

deploy:
  type: rsync
  host: <host>
  user: <user>
  root: <root>
  port: [port]
  delete: true
  verbose: true
  ignore_errors: false
  args: --rsync-path=sudo rsync

这个 args 参数在文档中并没有显示。我是通过查看 hexo-deployer-rsync 这个插件的源码才发现的。有了这个参数,便可以为 Rsync 命令追加选项了。

--rsync-path 选项的作用可以通过 man 1 rsync 命令查看系统文档获知:

指定如何在远程计算机上启动 Rsync。通常在当 Rsync 的命令路径不是默认路径时会使用这个选项(比如 --rsync-path=/usr/local/bin/rsync)。注意选项值在 shell 环境中运行,所以可以是你想运行的任何程序、脚本或者命令序列,只要它不破坏 Rsync 通信时的标准输入输出。

例如配合 --relative-R)选项来在远程计算机上设定一个非默认目录的小技巧:

$ rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/

通过这个选项,就可以指定以 sudo rsync 的形式来启动远程服务器上的 Rsync。

另外,稍有经验的都知道,如果命令选项中有空格,需要用引号将其括起来,以免引起歧义。就是因为这个“常识”,让我在调试这个参数时花费了很多时间。直接只用 Rsync 命令是可以同步的,但使用 Hexo 部署时却输出 sudo rsync 该文件或目录不存在,顺着 Hexo 的源码查看找到了 cross-spawn 这个包,但能力有限,没有找到怎么显示命令执行时的语句是什么,最后死马当活马医去掉了双引号,居然成功了。

3.2 另一个权限问题

如果你是以 Root 用户来登录 SSH,但却还是提示权限问题,那么需要检查系统是否启用了 SELinux

$ getenforce

要永久关闭 SeLinux,需要打开 /etc/selinux/config 文件和并设置 SELINUX=disabled。如果只是暂时关闭,可以执行命令:

$ sudo setenforce 0
(完)