Jekyll博客自动化部署到阿里云OSS

早在很多个月前,我就产生过将博客整体迁移到阿里云的想法。之所以迟迟没有动手,一是以为要备案,二是自动化部署有些麻烦。Netlify功能强大,部署简单,如果网络足够稳定,我也不会生二心。但近两个月来,Netlify网络延迟日益明显,丢包严重,甚至如果不采取特殊手段都无法登陆后台。这使我终于下定决心执行迁移到阿里云OSS的计划。

OSS部署静态博客

OSS的好处已无需多言:访问速度快,网络稳定,价格以我现有博客的规模和访问量可以忽略不计(此前我早已将图片资源迁到OSS上,一年半,花销大约在五角钱)。如果不需要自动化部署,也基本没什么可做的:

  • 创建一个bucket(如果不想备案,可以选香港服务器,访问速度比内地服务器也慢不了多少);
  • 在【传输管理-域名管理】中给bucket绑定一个域名(如果域名恰巧也在阿里云上,可以一键设置cname);
  • 如果需要https,可以到freessl申请一个免费的https证书,然后在OSS控制台的【域名管理】里选择【证书托管】;
  • 在【基础设置-静态页面】中配置首页和404页面,子目录首页也需要设置Redirect跳转,这样会将https://erl.im/blog/自动重定向到 https://erl.im/blog/index.html

配置301重定向

基于各方面考虑,我需要将www.erl.imyexiqingxi.comwww.yexiqingxi.com三个域名访问 重定向到 erl.im。OSS支持绑定多个域名,但不支持重定向。这倒不是什么大不了的问题,只是搜索引擎和我的评论API会受到影响。一番思索和调研后,终于通过“镜像回源”实现了重定向,实现步骤:

  • 创建一个空的bucket,按照上述说明配置好静态页面;
  • 把需要重定向的域名都绑定在这个空的bucket上;
  • 在空的bucket的【基础设置-镜像回源】中创建一条规则,回源条件设置为【HTTP 状态码404】,回源地址选择默认的【添加前后缀】,然后重定向到需要重定向的域名。

通过阿里云OSS镜像回源实现301重定向

通过这样一个trick,基本实现了301重定向功能,只是需要多花些流量钱!

自动化部署

如果无需自动化部署,那么到此即可。但我的评论系统是离不开自动化部署的(虽然我最近也在思考是不是还有保留评论功能的必要),所以还是再免不了再折腾一番。

Jekyll博客的自动化部署方案官方文档中早已有说明推荐,纵观国内外,最常用的第三方工具应是Travis,官方文档中也有完整的配置文件和说明,自动化构建这部分是没什么可讲的,重点是部署。Travis已天然支持了国外大多数的PAAS平台,至于阿里云OSS——

自然是没有的!需要自己写脚本来支持。

脚本的实现也很简单,阿里云的sdk已有详细的API文档。所谓的部署,也就是把Jekyll博客构建后的_site目录中的静态文件一一上传到阿里云OSS而已。在此之前@蛋子曾给我写过一个把本地图片资源上传到OSS的脚本,在此基础上稍作修改即可。而这家伙说什么也不肯再给我当免费劳动力,我只能捡起我那一点可怜的Ruby自己动手了!

第一版本的脚本很快便写好(一个工作日的午休时间),travis也简单按照说明文档配置好,只是第一次部署竟花费了十多分钟!虽说静态博客的构建部署需要花费一定时间,但十分钟也有些夸张了。时间花在了哪里呢?

  • bundle install 花费了不必要的过长时间——官方文档中已有方案,在配置中添加一行 cache: bundler即可;
  • 上传到阿里云花费了大部分的时间(大约有5分钟),我的博客大约3M多(仅网页,不包含图片等资源),如果每次部署都需要全部重新上传一遍,不单部署慢,流量也是冗余的开销。我的博客里如小说、首页、归档页一类变动很少,可能一年才会有一次变动,常有变动的只有博客这一部分。那就限制自动化部署时限定只上传博客这一部分即可,其他如有变动就手动跑脚本上传;
  • Travis的lifecircle中,似乎 builddeploy 不是在同一个环境下运行的, bundle install 安装完的 gemdeploy 阶段找不到,我只能在执行部署脚本前再安装一遍依赖,还不支持缓存,这样极耗时间。在翻遍文档后,找到的解决方案是把部署脚本放在 after_success ,即构建成功后立即执行,这样与构建共用一个环境,无需重复安装依赖。

在这一番整体优化后,部署时间缩减到了1分半,这于我至少是可以接受的了。

在这之后,基于不想把代码和博客内容冗杂在一起的洁癖,我又把部署脚本封装成Jekyll插件,以Jekyll命令的方式执行,同时支持可配置上传特定某(几个)目录和文件、支持设置缓存时间(这里还有些问题)、支持配置遇到同名文件是覆盖还是跳过。这样无论是本地部署还是自动化部署,执行 jekyll deploy 命令即可,源码和使用方法见 jekyll-deploy-oss

.travis.yml 配置示例:

language: ruby
rvm:
  - 2.5
script: bundle exec jekyll build
cache: bundler
after_success: bundle exec jekyll deploy

branches:
  only:
      - master

notifications:
  email: false
Sim2020-08-22 21:43

难怪博客首页图片不显示

叶夕青兮@Sim2020-08-22 22:39

哈哈,你不说我都没发现……

静水流深2020-08-23 16:02

注意到了整篇的重点—蛋子。 razz

Sim@静水流深2020-08-24 17:57

我也看到了 razz

ac2020-09-02 12:50

太棒了,解决了我的问题!

ac2020-09-02 12:51

为什么我的评论没有头像呢呜呜呜。

ac2020-09-02 13:13

保留评论吧,呜呜呜

山卜方2020-09-12 14:31

部署在 Vercel 也挺快的,再问下,您的博客评论用的什么?

叶夕青兮@山卜方2020-09-15 11:52