张天昀的个人博客

基于云存储和CDN的廉价博客部署方案

2019年10月31日

先把重要的东西放在前面:

可行性结论

  • 价格:每个月不超过1块钱
    • 腾讯家的对象存储前6个月免费,收费开始后买预付费plan每个月平摊不到半毛钱
    • 腾讯家的FaaS在单次运行内存限制128MiB的情况下可以免费运行300万+次(其实100万次封顶),根本不要钱
    • 内容分发网络(CDN)每个月免费额度基本用不完,超过了也可以白菜价买流量,几乎不要钱
    • 没有自家的GitLab可以用GitLab或者GitHub代替,反正都有DevOps而且不要钱
  • 维护:不归自己管
    • CDN速度很快(比GitHub Pages好多了),不需要担心小水管问题,更不用担心404问题
    • CDN和存储维护不归自己管,不用担心垃圾学生机内存不够挂了之类的问题
  • 可用性:非常通用
    • 所有静态网站都可用(Jekyll、Hexo、Hugo)
    • 外挂评论插件不受任何影响

使用IDC云服务

  • COS(Cloud Object Storage):对象存储,用于存储网站文件
  • FaaS(Function as a Service):对象存储更新后触发CDN刷新缓存
  • CDN(Content Delivery Network):缓存静态内容,加速访问

实现方式

购买云服务

首先购买所有的云服务,随便丢一个index.html看看能否访问。

创建代码仓库

不管是哪种静态博客生成器,首先把所有的代码塞到仓库里,然后写一个持续集成脚本(以GitLab CI/CD为例):

variables:
  TZ: Asia/Shanghai
  COS_USERID: "******"
  COS_SECRET: "******"
  COS_BUCKET: "******"
  COS_REGION: "******"
 
image: doowzs/hugo-qcloud-ci:latest

stages:
  - deploy

before_script:
  - echo "Configuring timezone..."
  - ln -fs /usr/share/zoneinfo/$TZ /etc/localtime
  - echo "Current server time is '$(date)'."

deploy_job:
  stage: deploy
  script:
    - echo "Generating the site..."
    - hugo # generate the site
    - echo "Publishing..."
    - cd public
    - coscmd config
      -a $COS_USERID
      -s $COS_SECRET
      -b $COS_BUCKET
      -r $COS_REGION
    - coscmd upload -rs ./ /
    - echo "Deploy finished."
  • 首先安装各种依赖(此处预编译了一个docker image来避免每次都安装,节省时间)
  • 接着调用网站生成器生成网站文件
  • 最后调用对象存储工具(或者rsync等)将生成出来的网站上传到服务端

docker image的创建脚本(可自己添加所需的各种依赖):

FROM ubuntu:latest

RUN apt-get update -yqq
RUN DEBIAN_FRONTEND=noninteractive apt-get -yqq install tzdata
RUN apt-get install -yqq git wget curl python3 python3-pip
RUN apt-get clean
RUN pip3 install coscmd
RUN curl -LSo hugo.deb https://github.com/gohugoio/hugo/xxx.deb
RUN dpkg -i hugo.deb
RUN rm -f hugo.deb

启用持续集成

将代码push到GitLab上,查看持续集成运行效果:

Continuous Integration

FaaS Callback

在IDC提供的FaaS中添加由COS事件触发的函数,通过访问API来触发CDN缓存更新。腾讯云开发者文档有已经写好的函数脚本,直接抄过来用就行了(太爽了)。

文档链接:使用 SCF 自动刷新被 CDN 缓存的 COS 资源

FaaS

偶尔会出现4xx错误,可能是由于Node执行过程中内存超限或者时间超限,属于运气问题。可以通过调节内存和时间限制来减少错误,不过多次更新中同一个文件多次出现错误的概率极低,几乎可以忽略。也可以每隔一段时间执行一次全部更新,来避免函数执行错误导致页面过旧。

push --force

最后本地写好然后git push等一两分钟就可以看到内容更新了。