Hexo 博客发布到 cPanel

本文最后更新于:2022年4月8日 凌晨

1. 缘起

谷月姐的 个人博客 是用 Hexo 搭建的,最早发布在 GitHub 上。但是,由于 GitHub 从墙内访问太慢,而且谷月姐又不想备案,因此又买了个墙内访问速度超快的香港虚拟主机「老薛主机」(https://www.laoxuehost.com),把个人博客同步发布到虚拟主机。

Hexo 的 FTP 发布插件有很多 Bug,动不动就出错,同时「老薛主机」的 FTP 上传系统是单线程而且不支持 UTF-8 编码,因此每次更新博客就成了梦魇。

一个偶然的机会,谷月姐发现「老薛主机」的管理系统是 cPanel,支持 Git 版本控制系统。

cPanel 支持 Git

而 Hexo 天生支持 Git,可以把博客部署到 GitHub。既然如此,能不能把 Hexo 博客发布到 Git 呢?答案是肯定的。

注意: 谷月姐把博客源码放在本地,只把编译生成的 public 文件夹发布到云端。至于另一种流行的博客部署方式——把博客源码也放在云端,只把更新过的博文推送到云端,然后通过持续部署之类的工具在云端编译发布,也是可以实现的,谷月姐将在未来的博文中讲解。

2. 操作步骤

2.1 本地准备工作

(1) 搭建好你的博客

安装 Node.js、Git 和 Hexo,并通过 Hexo 搭建站点,通过修改站点的 _config.yml 文件进行配置。详细操作参见 谷月姐的这篇博文EasyHexo网站的这篇教程

(2) 安装部署插件

在 Git Bash 中,执行以下两条命令:

$ npm install hexo-deployer-git --save
$ npm install hexo-server --save

Hexo-deployer-git 插件可以把 Hexo 博客(准确地说,是编译生成的 public 文件夹)部署并发布到 Git 版本控制系统的远程端,可以是 GitHub,也可以部署到其他安装了 Git 版本控制系统的主机。

Hexo-server 插件则是可以在本地预览实际部署后的博客。

2.2 远程准备工作

(1) 确定虚拟主机的IP地址、用户名

在此假设 IP 地址是 999.999.999.999 ,用户名是 kukmoon

(2) 配置主域、子域

「老薛主机」把用户可以通过 Web 访问的文件统一放在用户主文件夹下的 public_html 文件夹(即 ~/public_html)。谷月姐把博客的文件放在了 ~/public_html/blog 文件夹,并建立了一个子域名 blog.kukmoon.com 指向这个文件夹。

这个路径在后面还会用得到。

(3) 开通 Shell 访问权限

在远程主机上开通 Shell 访问(Shell Access)权限,是博客发布到远程主机所必须的。

如果不开通,在进行 Git 操作时,系统会提示「fatal: protocol error: bad line length character: Shel」。

$ git clone ssh://kukmoon@999.999.999.999/home/kukmoon/repositories/kukmoon_blog
Cloning into 'kukmoon_blog'
kukmoon@999.999.999.999's password:
fatal: protocol error: bad line length character: Shel

发工单给客服要求开启 Shell 访问权限即可,「老薛主机」一次性收费 10 元每主机。

让客服开通 Shell 访问

2.3 配置 SSH 免密登录

如果设置了 SSH 免密登录,下次更新博客时,只需要在本地命令行中键入发布命令 hexo deploy 就可以了;否则,每次键入发布命令时还要输入密码。所以,设置 SSH 免密登录是必要的。

(1) 本地生成 SSH 密钥

生成 SSH 密钥是为了便于后期免密登录。不需要每次部署博客时都重复输入冗长的密码。

在 Git Bash 中,执行以下命令:

$ ssh-keygen

系统会提示,将密钥保存到某个文件中:

Enter file in which to save the key (/c/Users/Kukmoon/.ssh/id_rsa)

此处按回车确认。

如果本机已经有SSH密钥,系统会提示是否覆盖:

/c/Users/Kukmoon/.ssh/id_rsa already exists.
Overwrite (y/n)?

建议按 y,覆盖已有的密钥文件,然后按回车。

接下来,系统又会提示为密钥设置密码(passphrase):

Enter passphrase (empty for no passphrase)

此处不需要设置密码,直接按回车跳过即可。如果在这里设置了密码,那么后续即使设置了 SSH 免密登录,也还是要在每次登录时输入在这里设置的密码。

随后,系统再次提示重复确认密钥的密码:

Enter same passphrase again:

仍然不需要设置,再次按回车。

最后,系统在在 C:\Users\<用户名>\.ssh 文件夹下生成两个文件:id_rsa 是私钥,id_rsa.pub 是公钥。

我们需要在后续的步骤中,将公钥上传到远程主机上。

(2) 设置 SSH 免密登录

我们需要把本地的 SSH 公钥上传到远程主机,才能实现免密登录。上传公钥有两种方法,一是通过图形界面来操作,二是通过命令行来操作。

(a) 通过 cPanel 的图形界面来操作

Step 1. 登录虚拟主机的 cPanel 管理面板,找到 「SSH 访问」。

管理面板中的 SSH 访问

Step 2. 点击「SSH 访问」,进入此页面,可以看到「管理 SSH 密钥」按钮。

管理 SSH 密钥

Step 3. 点击上述按钮,进入「管理 SSH 密钥」页面,正常情况下,这儿有一个「生成新密钥」按钮,一个「导入密钥」按钮,还列出了一个公钥和一个私钥,它们远程主机上的公钥和私钥。

管理 SSH 密钥

Step 4. 点击「导入密钥」按钮,进入「导入SSH密钥」页面。我们需要在「为此密钥选择一个名称」文本框中输入一个名称,最好不要用 id_rsa ,免得与远程主机自己的密钥混淆。

用记事本之类的文本编辑器,打开本地的公钥文件,就是我们此前创建的 C:\Users\<用户名>\.ssh\id_rsa.pub 文件,把里面的内容复制粘贴到「将公钥粘贴到以下文本框」。点击此页面底部的「导入」,再点击「返回」。

导入 SSH 密钥

Step 5. 这样我们就可以看到,上一页的「公钥」列表中,多了一个公钥。这就是我们刚才上传成功的本地公钥。它的状态是「not authorized」(未授权),接下来我们需要进行授权。

多了一个公钥

Step 6. 点击这个公钥右侧的「管理」,进入授权页面,在这里点击「Authorize」(授权)按钮,再点击「返回」即可。

授权

(b) 通过命令行来操作

方法一:在 Windows PowerShell、Windows Terminal 或者 Git Bash 中执行以下命令。注意:不能用命令提示符,因为它们没有提供 catscp 命令。

cat ~/.ssh/id_rsa.pub | ssh kukmoon@999.999.999.999 'cat >> ~/.ssh/authorized_keys;chmod 700 ~/.ssh;chmod 600 ~/.ssh/authorized_keys'

【解析】在 Linux 中, | (管道符)表示把前一个命令的输出作为后一个命令的输入。管道符后面的命令,是 sshcatchmod 的组合,ssh user@host 'COMMAND1;COMMAND2;COMMAND3' 代表在登录到远程主机以后执行单引号内的多条命令,命令之间可以用管道符或分号隔开。SSH 本身不能接受输入(从键盘输入密码不算),所以,第一个 cat 输出的内容,是本地公钥文件的内容,就变成了第二个 cat 命令的输入,第二个 cat 命令把这个本地公钥文件的内容,用重定向符 >> 添加到远程主机上授权公钥文件 ~/.ssh/authorized_keys 的末尾。然后,用 chmod 修改远程主机 ~/.ssh 目录与 ~/.ssh/authorized_keys 的权限,保证免密登录正常进行。

方法二:在 Git Bash 中执行以下命令。注意:不能用 Windows PowerShell 或 Windows Terminal,因为它们没有提供 ssh-copy-id 命令。

ssh-copy-id kukmoon@999.999.999.999

【解析】 ssh-copy-id 将本机公钥添加到远程主机上授权公钥文件 ~/.ssh/authorized_keys 的末尾,并修改此文件的权限为 rw——-,修改远程主机上 ~/.ssh 目录的权限为 rwx——,以保证免密登录正常进行

(3) 如果仍然要在登录时输入密码

如果设置过免密登录,但是登录时仍然需要输入密码,这说明还需要设置正确的权限。

  • 用户主目录:所有者具有读、写、执行权限;组和其他用户有读、执行权限,但不得写入。即rwxr-xr-x。

  • ~/.ssh 目录:所有者具有读、写、执行权限;组和其他用户不得有读、写、执行权限。即rwx——。

  • 私钥文件 id_rsa 和已授权的密钥文件 authorized_keys :所有者具有读、写权限。即rw——-。

  • 公钥文件 id_rsa.pub:所有者具有读写权限,组和其他用户只有读取权限。即rw-r–r–。

假设远程主机的用户名是 kukmoon。

用 SSH 连接到远程主机,执行以下命令:

$ chmod 755 /home/kukmoon
$ chmod 700 /home/kukmoon/.ssh
$ cd /home/kukmoon/.ssh
$ chmod 600 rd_rsa
$ chmod 600 authorized_keys
$ chmod 644 id_rsa.pub

(4) 如果仍然要在登录时输入密钥的密码

如果在登录时不需要输入用户的密码(password),但是要输入密钥的密码(passphrase),如图所示,那么需要按照「2.3 配置 SSH 免密登录」之第 (1) 小节,重新生成 SSH 密钥,一定不要设置密钥的密码(passphrase)。

要求输入 passphrase

2.4 在远程主机新建库

在远程主机新建库,也是有两种方法,一是通过图形界面,二是通过命令行。此处以图形界面为例。

Step 1. 登录虚拟主机的 cPanel 管理面板,找到 「Git™ Version Control」。

在 cPanel 面板找 Git

Step 2. 点击上述的「Git™ Version Control」,进入「Git™ Version Control」页面,直接点击右侧的「创建」,创建一个新库。

创建新库

Step 3. 在这里建立库。①关掉「Clone a Repository」开关,这个开关表示从远程克隆一个库。②在 「Repository Path」框中填上库的路径。因为谷月姐之前在「配置主域、子域」一节中把博客放在了 ~/public_html/blog 文件夹,所以在这里填写 public_html/blog 。③为库取一个名字。④点击「创建」。

创建库

Step 4. 这样,我们就创建了一个库,并且回到了「Git™ Version Control」页面,这里列出了新创建的库,在此处找到「管理」按钮。

新创建了库

Step 5. 点击上图中的「管理」按钮,进入「Manage Repository」页面。需要再次确认「Repository Path」是否与博客文件所在的文件夹一致,然后,把 Clone URL 复制出来备用。

假设 Clone URL 是 ssh://kukmoon@999.999.999.999/home/kukmoon/public_html/blog

管理库

2.5 配置站点的 _config.yml 文件

假如我的博客源文件放在 C:\Users\Kukmoon\Blog 文件夹,那么就用文本编辑器打开 C:\Users\Kukmoon\Blog\_config.yml,找到 # Deployment 节,编写新的 deploy 分支如下:

deploy:
  - type: git
    repo: ssh://kukmoon@999.999.999.999/home/kukmoon/public_html/blog
    branch: master

注意

  1. 站点的 _config.yml 文件意思是,假如我的博客源文件放在 C:\Users\Kukmoon\Blog 文件夹,那么站点的 _config.yml 文件就是 C:\Users\Kukmoon\Blog\_config.yml 。不要搞错。
  2. repo 后面是「在远程主机新建库」一节中复制出来的 「Clone URL」。此处需要把 @ 之前的 kukmoon 改成你的远程主机的用户名;999.999.999.999 改成你的远程主机的 IP 地址,当然,如果已经绑定了域名,改成域名也可以;把 home/kukmoon/public_html/blog 改成你的博客所在的实际文件夹。
  3. 不必操心绝对路径与相对路径的转换问题,「Clone URL」就是可以直接套用的绝对路径。

2.6 发布

经过以上一系列操作,我们终于完成了发布的准备。

在 Git Bash 中,执行以下两条命令:

$ hexo generate
$ hexo deploy

之后,静等 Hexo 把编译好的 public 文件夹中的内容发布到虚拟主机上就可以了。

发布成功

之后 ,可以在 cPanel 面板的文件管理器中,或者通过 SSH 远程连接到虚拟主机,看到发布到虚拟主机上的文件。

发布成功的文件

3. 下次发布

下次发布时,只需要重复执行「2.6 发布」一节中的两条发布命令即可。

$ hexo generate
$ hexo deploy

无需重复执行 2.1 ~ 2.5 节中的操作。


参考资料

  1. https://www.jb51.net/article/121180.htm
  2. https://blog.csdn.net/qq_31977125/article/details/102736460
  3. https://docs.cPanel.net/cPanel/files/git-version-control/
  4. https://docs.cPanel.net/knowledge-base/web-services/guide-to-git-how-to-set-up-deployment/#create-an-empty-repository-on-your-cPanel-account
  5. https://zhuanlan.zhihu.com/p/134349361?utm_source=cn.wiz.note&utm_medium=social&utm_oi=1005183544871772160