工作流

目前我的工作流是:本地hexo d推送部署到github上,然后通过github action部署到github pages 和vercel上。同时通过脚本将public文件夹下的静态文件同步推送到我的ECS服务器上。

也就是说,可以通过三个域名访问到我的博客,一个是https://lloyd-kai.github.io/ 源站点,一个是https://blog.lloydkai.top/ 部署到vercel上的(我已解析为自己购买的域名),一个是https://lloydkai.cn/ 部署到阿里云的ECS上的(方便国内的用户访问)。

部署时参考的教程

部署到vercel上

零成本免备案部署博客——vercel与zeabur搭建hexo主题博客 , 第2期:Vercel部署并绑定自定义域名+安装Butterfly主题 。这两个视频互相补充,主要参考第二个视频即可部署成功

部署到gihub的pages上

请看hexo博客系列(二)博客创建指南 ,严格来说我不是将hexo博客项目中所有的内容推送到github的,而是用hexo-deployer-git插件在本地生成public下的html文件,再推送到github pages上的。所以你会看到其他的的教程中它是先将整个hexo项目先推送到github,然后再将分支推送到github pages上,而我只上传必要的文件到github pages上,所有的文件都在我的本地电脑里面。主要的参考教程:Fomalhaut的博客,核心就在于是否下载了hexo-deployer-git插件以及配置ssh密钥等

官方hexo-deployer-git教程

部署到阿里云ECS上

主要参考的教程:链接

以下是根据我自己的实际使用情况修改


作者购买的是阿里云的ECS服务器,ubuntu版本


二、安装和准备环境部分中的2. 连接你的阿里云服务器(使用 SSH)

没有上传SSH密钥之前要登录就用

1
ssh -l root 你购买的ECS的公网IP -p 22

再输入密码即可SSH远程登录(注意要在登录之前先再ECS中重置密码,自己设置)

等之后上传SSH密钥就可以使用下方的命令行远程登录

1
ssh root@你购买的ECS的公网IP(比如192.168.240.243)

四、设置阿里云防火墙与安全组

如果要备案的话,注意停止你的域名解析。


三、配置 Nginx 启用 HTTPS

这里的内容我修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;

root /var/www/html;
index index.html;

location / {
}
}

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name 域名 www.域名;
ssl_certificate /etc/nginx/ssl/域名.cn.pem;
ssl_certificate_key /etc/nginx/ssl/.cn.key;
root /var/www/html;
index index.html;

location / {
}
}

用快捷键ctrl+s保存,ctrl+x退出。

后面我就不用他的github action


自动续签(Let’s Encrypt)

自动续签等ICP备案下来了才能配置,所以要先跳过


三、添加 GitHub Actions 工作流配置

从这里开始我就没有采用他的方案了,

我的实现思路是:

  1. 自定义 deployAfter 钩子执行 scp,把 public/* 上传到 ECS /var/www/html/
  2. 上传后自动修复目录与文件权限(目录 755,文件 644)
  3. Nginx 直接托管 /var/www/html 的静态文件

这样就无需借助github action,但是缺点就是以后hexo d推送的时候会比较慢,大概一分钟左右。

首先,先在_config.yml 文件中添加配置

1
2
3
4
5
6
# 本地执行 `hexo d` 后,自动通过 scp 上传到阿里云 ECS
ecs_deploy:
enable: true
host: 你的ECS公网IP
user: root
target: /var/www/html/

在hexo项目根目录下新建脚本 scripts/deploy-ecs.js

文件内容如下(可直接使用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
'use strict';

const { spawnSync } = require('child_process');

function runOrThrow(command, errorMessage) {
const result = spawnSync(command, {
shell: true,
stdio: 'inherit',
cwd: process.cwd()
});

if (result.status !== 0) {
throw new Error(`${errorMessage} (exit code ${result.status})`);
}
}

hexo.on('deployAfter', function () {
const cfg = hexo.config.ecs_deploy || {};
if (cfg.enable === false) {
hexo.log.info('[ecs-deploy] disabled by config');
return;
}

const host = cfg.host;
const user = cfg.user || 'root';
const target = cfg.target || '/var/www/html/';

if (!host) {
hexo.log.warn('[ecs-deploy] skip: missing ecs_deploy.host in _config.yml');
return;
}

const source = 'public/*';
const destination = `${user}@${host}:${target}`;
const scpCommand = `scp -r ${source} ${destination}`;
const remoteFixPermsCommand = `ssh ${user}@${host} "find ${target} -type d -exec chmod 755 {} \\; ; find ${target} -type f -exec chmod 644 {} \\;"`;

hexo.log.info(`[ecs-deploy] uploading via scp: ${source} -> ${destination}`);

runOrThrow(scpCommand, '[ecs-deploy] scp failed');
hexo.log.info('[ecs-deploy] fixing file permissions for nginx');
runOrThrow(remoteFixPermsCommand, '[ecs-deploy] permission fix failed');

hexo.log.info('[ecs-deploy] upload finished');
});

为什么要有权限修复:

  • 你这类 scp 上传在某些环境会导致目录权限变成 700
  • Nginx 无法读取 css/js/font 目录时,就会出现页面样式与 GitHub Pages 差异很大

以后只需要正常在终端中输入以下命令

1
hexo cl;hexo g;hexo d

就可以同步将public下生成的静态文件直接传到ECS服务器上。

如何备案

官方文档

总体来说流程有五个——填表申请、阿里云初审、短信验证、管理审核、ICP出结果和公安备案,ICP出结果之后就要马上将备案信息添加到首页之下,包括公安的备案(出结果后30天内),如果不添加就会有罚款。

官方表述

ICP备案成功后,您需要在网站首页底部悬挂ICP备案号并生成链接指向工信部网站(https://beian.miit.gov.cn/),否则被相关部门核查出来,将会面临罚款。