内容网格(Content Mesh) 是 Gatsbyjs 联合创始人 Sam Bhagwat 提出的依靠多种微服务弹性构建内容项目的开发方式,它弥补了单一工具短板影响项目整体性能的短板。基于内容网格理念,选择各类最佳工具,可以快速构建上线项目,并使访问者获得极致体验。

随着 Headless CMS、JAMstack、CI/CD 等技术的成熟,我们通过简单的集成各类工具,便可以搭建一套简单、高效、快速的内容网格系统。

项目构思

核心诉求

  1. 博客的目的是思考和写作,要尽量采用有专业团队或开源社区维护的基础工具构建,并且部署方式也应尽可能简单,无需过多二次开发。
  2. 本地和网络要有合适的内容编辑器,方便内容生产。
  3. 网络访问体验要快速极致,并天然适应移动互联网。
  4. 内容生产、管理和分发彼此独立,一个环节微调,不必全局调整,内容便于整理、存储和迁移。
  5. 资源复用:对于文字、图片、视频等内容,可实现复用、节约空间。

整体框架

基于内容网格的内容管理系统

  1. 本地内容生产:对于写文字比代码多的,推荐使用所见即所得,对中文友好的 Markdown 编辑器 Typroa,还可通过插件集成图床,一键上传图片。
  2. 后端:JAMstack 站点支持直接渲染 MD 文件,很多人也喜欢直接把 MD 文件发布到静态网站,供访客访问。但这存在一个问题,一旦更换主题或更换前端,需要重写 Yaml 文件设置标题、标签、日期等元数据来适应新主题。采用一个具有固定格式的 Headless CMS,统一管理文章,看似笨重,长远却是一劳永逸。另外,无头CMS 还有诸如自动社交分享、内容付费、RSS、订阅辅助等功能。 Ghost 自2013年发布以来,已经在 Github 上获得 35.2k Star,Ghost 后台界面简洁,支持富文本编辑和MD, 可以方便的插入图片、视频,并可作为内容源,发布内容到 Gatsby、Eleventy、Hexo 等静态网站生成器。
  3. 前端:JAMstack 是前端趋势,访问快速安全、部署方便。Gatsby.js 是基于 React 的静态网站生成器,运行速度极快,是 JAMstack 优秀代表 。自2015年 Kyle Mathews 在 Github 上发布第一个版本以来,已经从简单的开源项目成长为商业产品,并拿到了几轮大额融资,这对核心团队稳定、产品优化升级具有重要意义,完全靠个人开发者或开源社区支持的纯开源软件走不长久。另外,Gatsby 丰富的插件库、影子系统、高人气开发社区,非常有利于二次开发。
  4. 云服务:云服务作为基础设施,大厂技术差异不大,我们主要用服务器作为内容网格数据存储和管理后台,日常并无访问压力,选择 Ghost 需要的最低配服务器即可。腾讯云被一毛不拔的 MJJ 亲切称为良心云,值得拥有。
  5. 代码托管:如果 Github 说自己是这个星球上最大的同性社交网站,恐怕没人反对,背靠微软,人多艳美,福利多多,个人开发者白嫖各种功能,Fork Repo、可以满足日常需要。
  6. 内容托管:静态网站托管(Website Hosting)是由云厂商提供的便捷、稳定、高拓展性的托管服务,无需自建服务器,即可一键部署网站应用,将静态网站发布到全网节点,实现稳定、高并发、快速访问等能力。腾讯云的对象存储和静态网站托管均可用于内容网格体系的内容托管
  7. 持续集成和自动部署: 使用内容网格发布内容时,由于内容管理、代码托管和内容发布分别在 Ghost、Github 和静态网站托管平台三个独立微服务上,需要借助三者的 API 功能,利用持续集成/持续部署(CI/CD) 实现内容的自动发布。 GitHub Actions 是 GitHub 的持续集成服务,云函数是腾讯云开发的 Serverless 执行环境,搭配使用两者,串联 Ghost、Github 和静态网站托管平台,可实现内容的自动发布。
  8. 如果喜欢国产的话, Coding 背靠腾讯,可无缝对接腾讯云,并且支持从 Github 导入代码,也有持续集成和自动部署 Gatsby 静态网站功能。
  9. 评论系统:知名 Blogger Pat Flynn 说“Without comments, a blog isn’t really a blog. To me, blogging is not just about publishing content, but also the two-way communication and community building aspects behind it.”(没有评论系统的博客不是真正的博客,对我而言,博客不仅是发布内容,还有背后的互动交流和社群建设)。内容网格需要的评论系统要适配静态托管,有评论数据存储、管理、导出等功能,还要有通知支持,及时通知评论者和博主评论情况,满足要求的有 ValineCommento等。

内容规则

  1. 本地内容文件夹命名规则为:"年-iNote-Posts"单位命名,如“2020-iNote-Posts”。

  2. 本地文章命名规则:“年月日-标题”,如“20201005-基于内容网格的博客构思与实践”。

  3. 本地内容 Yaml 元数据

    template: post
    title: 基于内容网格的内容管理系统
    slug: content-mesh
    date: 2020-10-26T05:58:20.522Z
    category: 生活
    tags:
      - 生活
    description: 利用 Ghost、Gihutb、云函数、Gatsby 服务,可以搭建基于内容网格(Content Mesh)的 JAMstack 内容管理系统。项目搭建简单迅速,并使访问者获得极致体验。
    draft: false
    featuredImage: https://static.inote.xyz/img/2020102601.png
    
  4. CMS数据标签与本地内容元数据对应规则:Post Title=title,URL=slug,tag=tags,Excerpt=Mata Data=description

  5. 图片/视频命名规则:“年月日+当日编号”。

  6. 域名分配

    主域名:https://inote.xyz
    CMS: https://cms.inote.xyz
    comment: https://cmt.inote.xyz
    静态资源:https://static.inotexyz
    

项目部署

Typroa 配置

文字编辑不需要特殊配置,只需要在主题中选择自己喜欢的主题即可快速上手,对 PicGo 插件进行图像配置,可快速上传图片至图床,减少发布时的编辑量。

在文件-图像-下载或更新中,安装picgo-core插件,然后在配置文件中进行相关配置:

{
  "picBed": {
    "uploader": "tcyun",
    "tcyun": {
      "secretId": "<SecretId>",
      "secretKey": "<SecretKey>",
      "bucket": "<存储桶名称>",
      "appId": "<APPID>",
      "area": "<区域>",
      "path": "<目录>",
      "customUrl": "<自定义域名>",
      "version": "v5"
    }
  },
  "picgoPlugins": {},
}

服务器配置

  1. 服务器选择

    选择基本满足 Ghost 部署需求的服务器或轻量应用服务器即可, 需要用到的云函数、静态托管、COS等,最好与服务器位于同一个地区,以加快访问速度。

  2. 参考官方教程创建root用户

    # 为 root 用户创建密码 
    sudo passwd root
    # 放通 root 用户登录,设置 PermitRootLogin yes
    sudo vi /etc/ssh/sshd_config 
    # 重启 service ssh 服务
    sudo service ssh restart
    # 以 root 登录
    su root
    
  3. 端口:放通 TCP:22,3389,80,443,8086,20,21,465,587 等入站规端口。腾讯云默认限制云服务器 TCP 25 端口连接外部地址,在安全管控中解封 25 端口。

  4. 存储桶映射

    存储桶名称映射功能
    ghostGhost 图床
    static静态资源
    codingCoding 静态网站

Ghost 部署

Ghost 官方教程非常详细,按流程操作即可安装成功。由于我们只把 Ghost 作为数据源,为保证主站 SEO,在设置中勾选 Make this site private,禁止搜索引擎爬取和收录。

设置腾讯云 COS 作为 Ghost 图床

使用腾讯云 COS 作为图床,有两种方法。

方法一:使用腾讯云 COSFS 将 COS 存储桶挂载到服务器 Ghost 安装目录

COSFS 工具支持将 COS 存储桶挂载到本地,像使用本地文件系统一样直接操作腾讯云对象存储中的对象,COSFS 提供的主要功能包括:文件读写、目录操作、链接操作、权限管理、uid/gid 管理等功能。使用该方式配置图床,图片实际存储在 COS 中,但图片访问路径像把图片存储在本地一样。根据官方教程进行如下操作:

此方法并不适合用作 ghost 图床,在 ghost 升级、数据读取等存在不稳定性,建议采用第二种方法,用 ghost 图床插件进行设置。

  1. 获取源码

    git clone https://github.com/tencentyun/cosfs /usr/cosfs
    
  2. 安装依赖

    sudo apt-get install automake autotools-dev g++ git libcurl4-gnutls-dev libfuse-dev libssl-dev libxml2-dev make pkg-config fuse
    
  3. 编译和安装 COSFS

    cd /usr/cosfs
    ./autogen.sh
    ./configure
    make
    sudo make install
    cosfs --version  
    
  4. 配置

    a. 登录腾讯云 - 控制台 - 对象存储 - 存储桶获取相关信息

    • BucketName-APPID : test-1250000000 为存储桶名称
    • 区域地址 : https://cos.ap-shanghai.myqcloud.com 存储桶所在的区域域名.

    b. 登录腾讯云 - 控制台 - 访问管理,创建子账号并赋予 COS 相关权限,生成SecretIdSecretKey.

    • SecretId : AKI2mW1G4Owjuq5zOCWEgt68ua0EIo5nBq6
    • SecretKey : AdqxqFOJ3ZLqA6mCLuc86J2h5C9O1MQf

    c. 配置密钥文件,在文件/etc/passwd-cosfs中,写入您的存储桶名称(格式为 ),以及该 存储桶对应的 ,三项之间使用半角冒号隔开。为了防止密钥泄露,COSFS 要求将密钥文件的权限设置成640,配置/etc/passwd-cosfs密钥文件的命令格式如下:

    # 官方样本
    # sudo su  # 切换到 root 身份,以修改 /etc/passwd-cosfs 文件;如果已经为 root 用户,无需执行该条命令。
    echo <BucketName-APPID>:<SecretId>:<SecretKey> > /etc/passwd-cosfs
    chmod 640 /etc/passwd-cosfs
    # 设置权限
    chmod 640 /etc/passwd-cosfs
    
  5. 挂载 COS 到 Ghost 图片目录

    将已经在密钥文件中配置好信息的存储桶挂载到指定目录

    # 官方样本
    cosfs <BucketName-APPID> <MountPoint> -ourl=<CosDomainName> -odbglevel=info -oallow_other
    -o nonempty # 挂载到本地的目录不为空时.
    -oallow_other # 允许其他用户访问,允许Web直连下载.
    

    其中:

    • 为本地挂载目录(例如/mnt)。
    • 为存储桶对应的访问域名,形式为http://cos.<Region>.myqcloud.com (适用于 XML API,请勿在该参数中携带存储桶名称),其中 为地域简称, 例如 ap-guangzhou 、 eu-frankfurt 等。更多地域信息,请参见 可用地域
    • -odbglevel 指定日志级别。
    • -oallow_other 允许非挂载用户访问挂载文件夹。
  • -ononempty 文件夹有内容

具体到 Ghost ,配置如下

cosfs XXX-12500000 /var/www/ghost/content/images -ourl=https://cos.ap-shanghai.myqcloud.com -odbglevel=info -onoxattr -oallow_other
  1. 卸载

    # 官方
    umount -l /mnt/cosfs
    # 本地
    umount -l /var/www/ghost/content/images
    
  2. 设定 COSFS 开机自动挂载,在 /etc/fstab 文件中添加如下的内容,其中,_netdev 选项使得网络准备好后再执行当前命令

    sudo vim /etc/fstab
    # 官方
    cosfs#examplebucket-1250000000 /mnt/cosfs fuse _netdev,allow_other,url=http://cos.ap-guangzhou.myqcloud.com,dbglevel=info
    # 本地
    cosfs#文件夹有内容  /var/www/ghost/content/images fuse _netdev,allow_other,url=http://cos.ap-shanghai.myqcloud.com,dbglevel=info
    
  3. 挂载成功后,可以看到 COS 中对应目录中的图片成功加载到 /var/www/ghost/content/images 中。

方法二:使用 Ghost-qcloud-cos 插件把 COS 设置为图床

  1. 图床使用 ZhelinCheng 开发的 ghost-qcloud-cos 插件。

  2. 安装过程与 ZhelinCheng 给出的方法略有出入。

    a. cd 到 Ghost 安装目录

    cd /var/www/ghost
    

    b. 安装cos模块

    sudo npm install ghost-qcloud-cos
    

    c. 创建存储文件夹(如果不存在)

    sudo mkdir -p content/adapters/storage
    //设置文件夹权限
    sudo chown <user>:<user> content/adapters/storage
    sudo chown ubuntu:ubuntu content/adapters/storage
    sudo chmod 775 content/adapters/storage
    
  3. 将模块文件复制到该文件夹

       sudo cp -vR node_modules/ghost-qcloud-cos content/adapters/storage/ghost-qcloud-cos
    
  4. 创建名为“ cos-store.js”的脚本文件,并录入以下内容

       sudo touch  content/adapters/storage/cos-store.js
       sudo vim  content/adapters/storage/cos-store.js
       // 填写以下内容
       module.exports = require('ghost-qcloud-cos');
    
  5. 配置 config.[env].json

    cd /var/www/ghost/
    sudo vim config.production.json
    // 用你的COS信息替换,记得 COS 访问权限在后台设置为“公有读私有写”
         "storage": {
         "active": "cos-store",
         "cos-store": {
           "rename": "true",
           "secretId": "<SecretId>",
           "secretKey": "<SecretKey>",
           "bucket": "<存储桶名称>",
           "Region": "<区域>"
           }
        },
    
  6. 重启生效。

       ghost restart
    
  7. 运行 ghost restart 常见错误及解决方法

    # Message: The content folder is not owned by the current user.Ensure the content folder has correct permissions and try again.运行:
    sudo chown -R <user>:<user> ./content
    #  Message: Systemd process manager has not been set up or is corrupted.
    #如果再次错误,Run ghost setup linux-user systemd and try again.运行:
    ghost setup linux-user systemd 
    ghost restart
    

设置 Gmail 邮箱为后台 SMTP 服务器

  1. 启用 Gmail IMAP

    在 Gmail 邮箱 → 设置 → 转发和 POP/IMAP → IMAP访问中启用 IMAP

  2. 启用 Gmail 安全性较低的应用的访问权限

    打开链接Less secure,将“不够安全的应用访问权限"设置为"启用"。

    如果 Google 账户已启用两步验证,则需要使用应用专用密码才能访问不够安全的应用。

    转到 Google 帐号,在左侧导航面板中,选择安全性,再选择其他应用,生成应用专用密码。

  3. 配置 Ghost 服务器

    编辑根目录下 config.production.json,修改mail{}部分,如果没有启用两步验证,pass 赋值 Gmail 密码,如果启用了两步验证,pass 赋值 第2步生成的应用专属密码,重启生效。

     "mail": {
        "transport": "Direct"
      },
      # 修改为: 
      "mail": {
        "transport": "SMTP",
        "options": {
            "service": "Gmail",
            "auth": {
                "user": "<Gmail 邮箱地址>",
                "pass": "<Gmail 邮箱密码或应用专属密码>"
    			}
    		}
    	},
    

部署 Commento 评论

  1. 用 root 用户, 安装 postgresql 和 postgresql-contrib

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt install postgresql postgresql-contrib
    
  2. 用 root 用户,创建系统用户 commento,数据库用户 commento 和数据库 commento。Ubuntu系统利用 apt 安装 PostgreSQL 时,默认已安装 postgres 用户,利用其创建新用户 commento , 并为其配置数据库 commento,完成配置后,打开 PostgreSQL 的后台

    # 用root用户,创建系统用户commento,并赋予sudo权限
    adduser commento
    usermod -aG sudo commento
    # 用 commento 用户, 利用 postgres ,创建新用户 commento,并为其配置数据库 commento。
    sudo -u postgres createuser commento
    sudo -u postgres createdb -O commento commento
    # 用 commento 用户,为数据库用户 commento 创建数据库密码
    psql
    commento=# ALTER ROLE commento with PASSWORD '<commento-passwd>';
    commento=# \q
    # 打开PostgreSQL的后台
    sudo systemctl enable postgresql
    
  3. 利用 root 用户,在官网下载 commento 最新二进制文件,解压到 /usr/local/bin/commento文件夹中

    sudo su
    wget https://dl.commento.io/release/commento-v1.8.0-linux-glibc-amd64.tar.gz
    mkdir /usr/local/bin/commento
    tar xvf commento-v1.8.0-linux-glibc-amd64.tar.gz -C /usr/local/bin/commento
    
  4. 利用 ghost 用户和 acme.sh 为 commento 域名签发 ssl 证书,并配置反向代端口

    sudo -i -u ubuntu
    cd /var/www/ghost
    ghost config url https://cmt.inote.xyz
    ghost setup nginx ssl
    ghost config url https://cms.inote.xyz
    # 把cms.inote.xyz 的端口改回2368
    cd /var/www/ghost
    vim config.production.json
    "port": 2368,
    # 找到location中proxy_pass一项,把端口号改成喜欢的端口号<commento_port>比如:8086
    sudo vim /var/www/ghost/system/files/cmt.inote.xyz.conf
    sudo vim /var/www/ghost/system/files/cmt.inote.xyz-ssl.conf
    # commento目前不兼容nosniff, 搜索nosniff,切换到 root 用户,删除或注释掉它
    sudo vim /etc/nginx/snippets/ssl-params.conf
    //add_header X-Content-Type-Options nosniff;
    
  5. 用 root 用户,创建 commento.service 服务

    sudo vim /etc/systemd/system/commento.service
    [Unit]
    Description=Commento daemon service
    After=network.target postgresql.service
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/commento/commento
    Environment=COMMENTO_ORIGIN=<域名>
    Environment=COMMENTO_PORT=8086
    Environment=COMMENTO_POSTGRES=postgres://commento:commento@127.0.0.1:5432/commento?sslmode=disable
    
    
    # 用户注册完成后,再取消注释
    # Environment=COMMENTO_SMTP_HOST=smtp.gmail.com
    # Environment=COMMENTO_SMTP_PORT=587
    # Environment=COMMENTO_SMTP_USERNAME=<gmail 邮箱>
    # Environment=COMMENTO_SMTP_PASSWORD=Gmail 邮箱密码或应用专属密码
    # Environment=COMMENTO_SMTP_FROM_ADDRESS=<gmail 邮箱>
    
    # 用户注册完成后,再取消注释
    # Environment=COMMENTO_FORBID_NEW_OWNERS=true
    
    # 反垃圾邮件设置
    # Environment=COMMENTO_AKISMET_KEY=<AKISMET_KEY>
    
    [Install]
    WantedBy=multi-user.target
    
  6. 启动服务

    # 用 commento 用户,运行如下命令
    sudo chmod u+x /etc/systemd/system/commento.service
    sudo systemctl start commento
    sudo systemctl enable commento
    # 用 commento 用户,重启 NGINX 路由
    sudo nginx -s reload
    #检查 commento 是否在运行中
    sudo lsof -i -n|grep LISTEN|grep commento
    
  7. 通过浏览器访问 https://cmt.inote.xyz/signup 完成相关配置

  8. 登录 commento 用户重新配置 commento.service,包括 SMTP,取消注释新用户注册、AKISMET反垃圾评论设置等,配置完后,重启服务。

    su - commento
    sudo systemctl enable --now commento
    

制作镜像或快照,以备不时之需

完成以上步骤后,一个运行 Ghost 博客和 Commento 评论系统的服务器已经搭建完成。为了减少重装麻烦,可以利用腾讯云快照和镜像功能,定期备份。

使用 Gatsby 作为博客前端

在本地部署,完成二次开发

  1. 安装 Nodejs、Github Desktop、Gatsby CLI,配置本地开发环境。

  2. npm,yarn 设置淘宝源,加速国内访问速度,为保证依赖安装成功率,建议使用 yarn 命令。

    # 移除 npm 代理
    npm config rm proxy
    npm config rm https-proxy
    # 查看当前配置
    npm config get registry
    # npm 设置淘宝源
    npm config set registry https://registry.npm.taobao.org
    # yarn 设置淘宝源
    yarn config get registry
    yarn config set registry https://registry.npm.taobao.org -g
    # 安装 cnpm
    npm install -g cnpm
    # 清理缓存
    npm cache clean --force
    yarn cache clean
    # 切换回 npm 源
      npm config set registry  https://registry.npmjs.org
    
  3. 选择 Gatsby-Starter-Try-Ghost ,部署在本地。

    # clone repo 到本地
    git clone https://github.com/<user-name>/<repo-name>.git <local-dir>
    # 安装依赖
    cd <loacl-dir> 
    yarn
    # 运行开发模式
    yarn develop
    # 运行生产模式
    yarn build
    
  4. 在本地通过 http://localhost:8000 浏览站点,修改调试。

利用组件影子(Component Shadowing)功能,更换字体

利用 Gatsby 主题的组件影子功能,对字体进行替换。比如,替换主题 Gatsby-starter-try-ghost 的字体,只需要在src目录下新建gatsby-theme-try-ghost文件夹, 从Gatsby-starter-try-ghost使用的主题gatsby-theme-try-ghost 复制对应目录和文件,进行字体栈替换,然后运行 Gatsby bulid,字体替换成功。

常用的中文字体站如下:

# 使用中文字体栈,在 CSS 中用以下配置替换 font-family
font-family: "lucida grande", "lucida sans unicode", lucida, helvetica, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;

配置 Commento 插件

yarn add gatsby-theme-ghost-commento
// In your gatsby-config.js
plugins: [
    {
        resolve: `gatsby-theme-ghost-commento`,
        options: {
            url: `<commento-url>`,
        },
    },
]

配置 Google 统计

yarn add gatsby-plugin-google-analytics
// In your gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        trackingId: "YOUR_GOOGLE_ANALYTICS_TRACKING_ID",
        head: false,
        exclude: ["/preview/**", "/do-not-track/me/too/"],
        pageTransitionDelay: 0,
        // Defers execution of google analytics script after page load
        defer: false,
      },
    },
  ],
}

配置 Google adsense,在静态文件夹stacit中添加 ads.txt,然后安装依赖,并完成设置

yarn add @isamrish/gatsby-plugin-google-adsense
// In your gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `@isamrish/gatsby-plugin-google-adsense`,
      options: {
        googleAdClientId: "YOUR_GOOGLE_ADSENSE_TRACKING_ID",
        head: true
      }
    }
  ]
};

把 Gatsby 数据源替换为自己的数据,在根目录建立.ghost.json

touch .ghost.json
// In your .ghost.json
{
  "development": {
    "apiUrl": "<Your_Ghost-URL>",
    "contentApiKey": "<Your_Ghost_Content——API>"
  },
  "production": {
    "apiUrl": "<Your_Ghost-URL>",
    "contentApiKey": "<Your_Ghost_Content——API>"
  }
}

利用 Github Desktop 把本地开发完成的 Gatsby 目录文件 push 回 repo。

Gatsby 部署常见错误

  1. Windows Powersell 无法将“apt-get”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。用管理员模式,运行以下命令,并选A
Set-ExecutionPolicy Unrestricted
  1. 解决 raw.githubusercontent.com 被污染 ,利用站长工具找对应IP地址,然后再修改本地 host

  2. node_modules缺少个别安装包,可利用 cnpm 单独安装

    cnpm i -g mozjpeg@7.0.0
    yarn add gatsby-2.24.67.tgz
    

自动部署和持续集成

方法一:利用 Github 实现自动部署和持续集成

当 Ghost 中发生内容变化(内容发布、更新、删除)时,利用 Ghost API 向 Gatsby 的 Github Repo 发送 Github Action 触发通知,通过 Github Action 更新 Gatsby,然后再把 Gatsby Build的新 public同步到静态站点。 由于 Ghost API 只是一个简单的 Webhook , 而触发 Github Action repository_dispatch 需要包含 header、repo owner 、Gihhub 个人令牌等信息的 cURL 作为外部事件。因此,我们利用云函数作为中间件,把 Ghost 的 Webhook 通知转换为可以触发 repository_dispatch的通知。

  1. 创建腾讯云函数,运行环境选择 python,编辑函数代码内容,创建 API 网关触发器,复制访问路径,添加到 Ghost Integrations 的 wenbhook中 , Event 选择 Site changed。

    # -*- coding: utf8 -*-
    # 替换 <owner>、<repo>、<access-token>
    import requests
    def main_handler(event, context):
        r = requests.post("https://api.github.com/repos/<owner>/<repo>/dispatches",
        json = {"event_type": "update from cms"},
        headers = {"User-Agent":'<owner>}',
                  'Content-Type': 'application/json',
                  'Accept': 'application/vnd.github.everest-preview+json',
                  'Authorization': 'token <access-token>})
        if r.status_code == 204:
            return "This's OK!" 
        else:
            return r.status_code
    
  2. 在 Gatsby Repo 创建 Github Action,变量在各服务的获取后,配置在 repo的 Secrets 中。在静态托管环节,有两种方案:a. 把 Gatsby 部署到腾讯云静态网站托管,当Ghost 删除文章后,本方法目前不能同步执行删除静态文件。b. 把 Gatsby 部署到 COS,本方法可以利用cosmd 命令自动删除ghost cms 删除对应静态文件。并完成相关配置。

    # push 代码、repository_dispatch 时触发 workflow
    on: [push, repository_dispatch]
    
    jobs:
      deploy:
      
        # 指定运行所需要的虚拟机环境
        runs-on: ubuntu-latest
        name: Ghost-SCF-Github-Gatsby-Static
        steps:
        
    	  # 获取源码
          - name: Checkout
            uses: actions/checkout@v2
            
    	 # 设置 Nodejs
          - name: Set Node.js
            uses: actions/setup-node@master
            with:
              node-version: 10.x
              
         # 安装依赖
          - name: Install dependencies
            run: yarn install --prod --pure-lockfile
            
         # 运行生产模式
          - name: Build
            run: yarn run build
            env:
              GHOST_API_URL: "https://gatsby.ghost.org"
              GHOST_CONTENT_API_KEY: ${{ secrets.ghost_content_api_key }}
              GATSBY_ENV: "prod"
              
         # a. 利用云开发 Github Action 扩展,把静态文件目录 public 部署到云端。     
          - name: Deploy static to Tencent CloudBase
            id: deployStatic
            uses: TencentCloudBase/cloudbase-action@v1.1.1
            with:
              secretId: ${{ secrets.SECRET_ID }}
              secretKey: ${{ secrets.SECRET_KEY }}
              envId: ${{ secrets.ENV_ID }}
              staticSrcPath: public
              
          # b. 利用云开发 Github Action 扩展,把静态文件目录 public 部署到 COS。 
          - name: Install coscmd
            run: sudo pip install coscmd
            
           # 利用云开发 Github Action 扩展,把静态文件目录 public 部署到云端。   
          - name: Configure coscmd
            env:
              SECRET_ID: ${{ secrets.SecretId }}
              SECRET_KEY: ${{ secrets.SecretKey }}
              BUCKET: front-gatsby-1250000000
              REGION: ap-nanjing
            run: coscmd config -a $SECRET_ID -s $SECRET_KEY -b $BUCKET -r $REGION
            
          # 利用云开发 Github Action 扩展,把静态文件目录 public 部署到云端。    
          - name: Upload to Cos
            run: coscmd upload -rs --delete -f ./public/ /    
    

方法二:利用 Coding 实现自动集成和自动部署

  1. 将 Github Repo 设置为公开,通过 https://<team>.coding.net/import导入代码。
  2. 在项目设置开发者选项关联 Github Repo。这时候,可以再将 Github Repo 设置为隐私模式。
  3. 按照 定时同步私有代码库到 CODING方法,设置代码更新自动同步(代码源更新-代码更新时自动执行)。
  4. 在持续部署静态网站中选择选择部署 Gatsby 静态网站,网站即可自动部署到腾讯云 COS,设置自定义域名,一个 Gatsby 网站就部署完成了。
  5. 为了在 Ghost 更新时,Coding 静态网站也同步更新,我们还需要通过 Ghost webhook 、腾讯云函数(SCF)、Coding API 触发进行持续集成设置。点击部署列表-立即触发-前往参数默认值设置,进入静态网站持续部署设置页面,在触发规制,API 触发中选择生成 curl 命令触发示例 设置项目令牌过期时间,并复制代码。
  6. 在腾讯云函数中新建云函数,运行环境选择 CustomRuntime,模板选择 shell函数示例,把从 Coidng API 触发复制来的代码,贴入 index.sh, 删除config.jsonserverless.yaml保存函数。在触发管理中,创建 API 触发管理器,复制访问路径。
  7. 把从 SCF 复制的访问路径,粘贴到 Ghost Webhook中,设置完成触发规则,当 Ghost 更新时,Coding 静态网站即可完成自动部署,并同步到 腾讯云对应 COS 中。
  8. 在 COS 的函数计算中设置好 CDN缓存刷新函数 确保 CDN 边缘及时更新最新内容。
  9. 为节约调用 SCF 费用,把触发 Coding API 对应函数,运行内存设置为64MB,执行超时设置为1秒。CDN 刷新函数的时间类型选择全部创建全部删除,触发条件前缀设置为index.html(只有当index.html发生变化时,才触发 CDN 刷新函数执行刷新任务。)运行内存设置为256MB,执行超时时间设置为1秒。

利用Gatsby Cloud 监控静态网站运行情况。

Gatsby Cloud 中添加 Github Repo,进行CMS预览、Lighthouse 评分,部署异常信息,运行状态监测等。

Gatsby 评分

资源费用

名称配置费用
域名.xyz69/年
Ghost开源免费
云服务器1核2G3M, 轻量服务器588元/3年
Commento开源免费
Github个人版:无限个私人Repo免费
Github Action私人版:2核CPU, 7G RAM,14G SSD硬盘虚拟机, 每月 2000分钟构建时间免费
Gatsby开源免费
Gatsby Cloud个人版:每月100次RTEs免费
SCF每月免费额度:资源使用量40万GBs,调用次数100万次。
COS每月免费额度:标准存储容量50GB,外网下行流量10GB,CDN 回源流量10GB,读请求数100 万次,写请求数:100 万次。免费