部署 GitHub Pages 博客到私有服务器
立泉博客托管在 GitHub Pages 上,不是我的错觉,它在大陆的访问速度正变得越来越不稳定,有时甚至要等 5 秒以上才能打开,这让我无法接受。博客是沉淀知识阅历的地方,应该触手可及而非无意义等待。
镜像
几年前 GitHub Pages 并不是这样,当时我很满意才会把博客托管给它,可是物是人非,必须做些尝试尽可能提高一个非备案域名在大陆的访问速度。不备案意味着无法使用大陆的服务器和 CDN,而这两项正是网站加速的最佳途径,所以成年人的标志之一便是根据好恶作出选择然后坦然面对后果。
为减少 GitHub 仓库容量,毕竟速度那么慢,我把网页之外的资源都放在阿里云杭州节点的 OSS 对象存储上,这个只需实名无须备案。关于费用,不少人会因为“免费额度”选择小服务商的对象存储,但实际上阿里云的报价表只是看起来复杂,流量不大的个人博客账单其实每月不过零点几元,充 5 元已经是“巨款”。
2024 年 03 月 07 日更新:注意 OSS 可能被流量攻击引起的高额账单风险。
解决资源托管后瓶颈只剩下对 GitHub 本身的连接速度,而其在大陆没有数据中心,又不能使用国内 CDN,唯一可行的方法是在一台靠近大陆的服务器上创建博客镜像,把域名指向它。付出一台服务器费用解决访问速度问题,承载博客之外,随着我的想法越来越多它也会发挥更大作用。
实施
GitHub Pages 托管的博客本身是一个 Git 仓库,Jekyll 工程的目录结构如下:

其中,_drafts和_posts分别存放用 Markdown 格式撰写的草稿和文章,assets存放媒体资源,已经把它们迁移到阿里云 OSS 上,所以这里是空的。_includes、_layouts、css、font和js是与网站模版、布局、样式相关的东西,Jekyll 需要借助它们将 Markdown 文本转换为静态 HTML 网页。
内容更改后 Push 到 GitHub 上,Pages 会自动用 Jekyll 生成静态站点 Serve 到指定域名下。创建博客镜像是把这份代码 Push 到自己的服务器上,手动 Build 在_site目录生成静态网页,再配置 Nginx 进行 Serve。
我并不擅长 Linux,好在要做的事不复杂,服务器安装 Nginx 会生成默认配置文件/etc/nginx/sites-available/default,按如下方式修改:
server {
# HTTP 监听 80 端口
# ipv4
listen 80 default_server;
# ipv6
listen [::]:80 default_server;
# 域名,若无域名则使用 localhost
server_name mudan.me;
# 网站 index.html 的位置
root /home/apqx/Code/apqx.github.io/_site;
# 入口
index index.html index.htm index.nginx-debian.html;
# 404 错误页面
error_page 404 /404.html;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
重启 Nginx 即可用 HTTP 访问到博客。
sudo systemctl restart nginx
HTTPS
如今借助 Let’s Encrypt 启用 HTTPS 已经非常简单,Certbot 是一个基于 Let’s Encrypt 为域名生成 SSL 证书并配置 Nginx 的工具,支持为只有 90 天有效期的证书自动续期。
# 安装 Certbot
sudo snap install --classic certbot
# 按提示选择要加密的域名,生成证书签名,配置 Nginx,启用 SSL
# 证书目录为 /etc/letsencrypt/live/[域名]/
# Certbot 会自动执行证书更新
sudo certbot --nginx
按提示执行完成,Certbot 会更新 Nginx 配置以使用生成的证书:
server {
# 网站 index.html 的位置
root /home/apqx/Code/apqx.github.io/_site;
# 入口
index index.html index.htm index.nginx-debian.html;
# 404错误页面
error_page 404 /404.html;
# 域名
server_name mudan.me;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# 监听 443 端口的 HTTPS
# ipv4
listen 443 ssl; # managed by Certbot
# ipv6
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mudan.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mudan.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
# 监听 80 端口的 HTTP,跳转 HTTPS
if ($host = mudan.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name mudan.me;
return 404; # managed by Certbot
}
访问网站看到 HTTPS 已经启用,证书由 Let’s Encrypt 签发,有效期 90 天。
注:域名已更换为 mudan.me。

这台 Google Cloud 台湾节点的服务器网络延迟约 60ms,比 GitHub Pages 平均 300ms 好很多,虽然不如离我最近的阿里云杭州节点的 10ms,但对静态博客已经足够。
