博客迁移之旅
前言
之前博客是直接托管到 Github
上的,由于它不是很稳定经常挂掉,而且访问速度也很慢,所以后面就干脆把它部署到自己的服务器上,顺便记录一下整个部署的流程,方便以后查看。
关于服务器
服务器我选的是腾讯云(主要是新用户有折扣,比较便宜,之前买过阿里云的,就不是新用户了),个人服务器,考虑到服务器主要是用作个人博客(静态页面),没啥并发量,对性能没有太高的要求,所以就选了一个最低配置。
服务器配置清单

流程
博客的整个部署流程分为服务端与客户端(本地)两个部分,具体的步骤会后面会描述,这里先说一下整体的流程。
- 创建博客的远程仓库
- 本地安装配置 hexo
- 推送本地生成的静态页面到远程仓库
- 服务端获取最新博客文件并部署上线
这里可能会产生一个疑问:博客的远程仓库在哪创建?是 Github
还是在服务器上。为了解答这个疑问,我们先介绍下这两种方式:
远程仓库建在 Github 上
发布博客时,只要登录到服务器,通过 git
工具去仓库上拉取最新的文件,然后部署上线即可。如果需要集成自动部署功能(在本地执行完 hexo deploy
命令后,服务器能够自动去拉取最新静态页进行部署,不用再登录服务器手动操作),则需要使用到 Github
给我们提供的 Webhooks
勾子,来实现对 push
事件的监听。
远程仓库建在服务器上
发布博客时,服务器可以直接拿到最新的静态页进行部署,如果想自动部署,则可以使用 git
工具给我们提供的 post-receive
钩子文件,来实现对 push
事件的监听。
比较一下上述的两种方式,我个人是推荐第二种,即:在服务器上创建博客的远程仓库,Why?
在集成自动部署时,如果仓库建在 Github
上,则需要在 Github
中新增一个 webhook
钩子,并配置好回调地址,当仓库监测到 push
事件后,会调用这个回调地址,来通知服务器进行后续的操作。
服务器端需要完成以下四件事:
- 提供一个服务来让
Github
调用,也就是webhook
上配置的的回调地址所对应的服务。- 安装
git
工具,然后创建一个博客仓库与远程仓库进行关联,用来拉取远程仓库中的博客文件。- 当服务被调用时,需要使用
git pull
命令去拉取最新的博客文件。- 在获取到最新的博客文件后,通过
nginx
反向代理博客静态页(部署)。

这里涉及到服务器与 Github
的通信,而 Github
又不是很稳定,可能存在信息丢失的风险,导致博客不能被即时部署。
如果是将远程仓库建在服务器上,当我们提交完最新的博客页后,服务器就能拿到本地提交的文件,而且可以通过 git
工具的 post-receive
钩子文件,来监听本次的 push
事件,从而进行后续的操作。另外,由于这些操作都是在服务器内部完成的,不需要与外部进行通信,所以就不存在部署不及时的问题。
步骤
我采用的是第二种方式(在服务器搭建远程仓库),后续也是基于这种方式来进行介绍。

具体拆解下来,分为服务器端与本地客户端两个部分的操作。
服务器
注:服务器上的操作都是在
root
权限下进行的。
- 安装并配置 Docker
博客是通过 Docker
容器来部署的,所以需要在服务器上下载安装 Docker
。也可以不用 Docker
,直接使用 nginx
来部署。这里主要是为了以后迁移方便(如果以后需要更换服务器,只需要将 Docker
脚本以及相关的配置文件打包走即可,不用再重新配置 nginx
),同时自己也想熟悉一下 Docker
的相关用法。1
2
3
4
5
6
7
8# 安装 docker,因为我的服务器预装了 CentOS 系统,所以可以直接使用 yum 命令
yum install docker -y
# 启动 docker
service docker start
# 配置开机启动
chkconfig docker on
国内访问 Docker Hub
较慢,可以添加国内的镜像源来加速访问 Docker Hub
,我这里使用的是腾讯云提供的镜像源。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 1. 创建 docker 配置文件目录
mkdir /etc/docker
# 2. 添加新的镜像源
cat >> /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
# 3. 加载配置文件
systemctl daemon-reload
# 4. 重启 docker
service docker restart
配置好 Docker
的镜像源后,我们就可以通过 Docker
来拉取 nginx
镜像。1
2# 拉取 nginx 镜像
docker pull nginx
安装 docker-compose
。
注:
docker-compose
在这里不是必需的,它是用来解决多个容器编排的一种方案。因为这里只用到了nginx
镜像,完全可以用一个Dockerfile
文件来进行定制。
1 | # 下载安装 docker-compose |
接下来需要修改一下 nginx
相关的配置。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
46
47
48
49
50
51
52
53
54
55
56# 1. 在 /home 目录底下新建一个 blob 目录,并进入到该目录底下。
# 这个目录就是博客的部署目录,里面存放着博客的静态文件以及与 nginx 相关的配置文件。
cd /home && mkdir blob && cd blob
# 2. 创建 docker-compose.yml 文件
vim docker-compose.yml
# 3. 在 docker-compose.yml 文件中输入以下内容
version: '3'
services:
nginx:
restart: 'always'
image: 'nginx'
ports:
- '80:80'
- '443:443'
volumes:
# a. volumes 将物理主机目录挂载到容器中
# b. 以 : 为分隔符,前半部分为服务器目录,后半部分是容器中的目录
# c. 挂载建立的是双向关联,类似于软连接
# d. 当修改了服务器中的文件,则容器中所关联的文件也会同步更新,无需重新构建
#
# /home/blob/www/public 为服务器目录,里面存放的是博客的静态文件
# 将它挂载到容器内的 /usr/share/nginx/html 目录中,将来服务器中的博客文件更新后,容器内会同步更新
- '/home/blob/www/public:/usr/share/nginx/html'
# 挂载 nginx 的日志文件
- '/home/blob/log:/var/log/nginx'
# 挂载 nginx 的配置文件
- '/home/blob/conf:/etc/nginx/conf.d'
# 4. 创建 nginx 相关的配置文件
# 在 conf 目录底下创建一个 default.conf 文件,此文件将来会被挂载到 nginx 容器中并作为它的配置文件
cd /home/blob/conf && vim default.conf
# 5. 在 default.conf 文件中输入以下内容(注:此处没有配置 https)
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# 6. 启动容器
cd /home/blob && docker-compose up -d
至此,所有与 nginx
相关的步骤都已经完成,接下来就是 git
相关的配置了。
- 安装并配置 Git
因为博客的远程仓库是在服务器上创建的,所以需要在服务器上安装 git
工具。1
2# 下载安装 git
yum install git -y
安装完 git
后,在 /home
目录底下创建一个 blob.git
的仓库,该仓库就是博客的远程仓库。
注:博客的远程仓库以及上文中提到的博客的部署目录,并不一定要在
/home
目录下创建,可以根据自己的需要在服务器上选择一个合适的目录即可。
1 | # 创建博客的远程仓库 |
创建 post-receive
钩子文件。
注:
post-receive
是git
在收到push
事件以后执行的一个脚本文件,通过它可以实现对push
事件的监听,从而达到自动部署的目的。
参考:自定义-Git-Git-钩子
1 | # 1. 进入到 blob.git 仓库中的 hooks 目录中,所有的钩子文件都在这个目录下 |
- 创建一个新用户,用来维护 git 仓库
前面所创建的 git
仓库,是在 root
权限下操作的。当外界访问仓库时(本地的 push
),就需要拥有 root
权限,而直接使用 root
账号来操作并不是一个很好的选择,所以我们需要单独创建一个用户来维护 git
仓库,以保证服务器的安全。
1 | # 添加 git 用户(这里的 git 是用户名,可以随意命名) |
执行完上述命令后,会在 /home
目录底下生成一个 git
的目录,该目录就是 git
用户的家目录。
接下来是给 git
用户分配相应的操作权限,这里只需给它分配 git
仓库和博客部署目录的使用权限即可。
1 | # 1. 设置 git 仓库的拥有者为 git 用户 |
注:这里没有禁用掉
git
账户的shell
登录权限,因此本地可以通过shell
来登录服务器上的git
账户。这样做的目的是为了方便后续添加ssh
密钥,从而实现服务器的免密登录。如果直接禁掉了git
账户的登录权限,后面在服务器上添加ssh
密钥时会比较麻烦。
至此,服务器上的所有操作都已经完成,剩下的就是本地客户端的操作了。
- 服务器目录结构图
本地
- 配置 ssh 密钥,实现服务器的免密登录
ssh
可以基于密码进行认证,也可以基于密钥去认证用户,基于密钥认证时可以实现免密码登录服务器。
1 | # 生成密钥对 |
注:直接执行
ssh-keygen
命令,会进入交互模式,并等待用户输入生成密钥文件的路径,在不输入任何路径的情况下,私钥与公钥默认生成在当前用户家目录下的.ssh
目录中,如果不指定其他路径,直接回车即可。随后,会提示我们输入密码,如果设置了密码,则每次在使用的时候,都会提示我们输入密码,因为我们想实现的就是免密码登录,所以这里直接回车,不设置密码,最后再次回车即可。
当生成完密钥对后,就可以在当前用户的家目录(~/.ssh
)中找到这队密钥文件(id_rsa
、id_rsa.pub
),现在只需将公钥(id_rsa.pub
)上传到服务器上的 git
账户中,就可以免密登录服务器上的 git
账户了,本地 push
文件到服务器上的远程仓库时就不用再输密码。1
2# 上传公钥到服务器(请将 IP 替换成你服务器的公网IP(主机名))
ssh-copy-id -i ~/.ssh/id_rsa.pub git@IP
注:传输公钥时,会要求我们输入
git
账户的密码,这种密码验证只需要进行一次即可。
- 安装并配置 hexo
注:关于
hexo
的安装和使用请参考 文档 | Hexo ,这里我们只讨论_config.yml
文件的配置。
当执行 hexo deploy
命令时,hexo
会将生成的 public
目录中的文件和目录推送至 _config.yml
中指定的远端仓库和分支中,并且完全覆盖该分支下的已有内容。所以,只需要将 _config.yml
文件中的 deploy
参数进行修改,就可以将本地生成的静态文件推送到服务器上的 git
仓库中。
1 | # 1. 进入到本地博客根目录中,编辑 _config.yml 文件 |
至此,所有的迁移工作全部完成。