部署 GitHub Pages 博客到私有服务器

博客托管在 GitHub Pages 上,不是我的错觉,它在大陆的访问速度正变得越来越不稳定,有时甚至要等 5 秒以上才能打开,这让我无法接受。博客是沉淀知识阅历的地方,应该触手可及而非无意义等待。

镜像

几年前 GitHub Pages 并不是这样,当时我很满意才会把博客托管给它,可是物是人非,必须做些尝试尽可能提高一个非备案域名在大陆的访问速度。不备案意味着无法使用大陆的服务器和 CDN,而这两项正是网站加速的最佳途径,所以成年人的标志之一便是根据好恶作出选择然后坦然面对后果。

为减少 GitHub 仓库容量,毕竟速度那么慢,我把网页之外的资源都放在阿里云杭州节点的 OSS 对象存储上,这个只需实名无须备案。关于费用,不少人会因为“免费额度”选择小服务商的对象存储,但实际上阿里云的报价表只是看起来复杂,流量不大的个人博客账单其实每月不过零点几元,充 5 元已经是“巨款”。

2024 年 03 月 07 日更新:注意 OSS 可能被流量攻击引起的高额账单风险

解决资源托管后瓶颈只剩下对 GitHub 本身的连接速度,而其在大陆没有数据中心,又不能使用国内 CDN,唯一可行的方法是在一台靠近大陆的服务器上创建博客镜像,把域名指向它。付出一台服务器费用解决访问速度问题,承载博客之外,随着我的想法越来越多它也会发挥更大作用。

实施

GitHub Pages 托管的博客本身是一个 Git 仓库,Jekyll 工程的目录结构如下:

jekyll

其中,_drafts_posts分别存放用 Markdown 格式撰写的草稿和文章,assets存放媒体资源,已经把它们迁移到阿里云 OSS 上,所以这里是空的。_includes_layoutscssfontjs是与网站模版、布局、样式相关的东西,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

ssl certificate

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

ping

arrow_upward