本文记录这个博客本身的搭建方式。核心思路只有一句话:

仓库即站点。 推送代码 = 发布上线。

整套东西用到的免费资源:

环节 用的东西 作用
代码托管 CNB Git 仓库 + 云原生构建流水线
静态托管 EdgeOne Pages CDN 分发、自定义域名、HTTPS
构建 Node.js 把 Markdown 渲染成 HTML

为什么是这套组合

常见的静态博客方案基本是 GitHub + Actions + Pages。如果访问条件没问题,那套确实更省事。但在国内网络环境下,构建和访问都容易出状况,所以换成 CNB + EdgeOne Pages 这套纯腾讯云的链路:

  • CNB 提供 Git 托管和云原生构建,和 GitHub Actions 的定位一致,.cnb.yml 就是 workflow。
  • EdgeOne Pages 相当于 GitHub Pages,负责把构建产物分发出去。

两者接起来就是一条完整的 CI/CD:push → 构建 → 部署。

站点结构

仓库里只有一个构建脚本,没有引入任何静态站点框架:

text
.
├── .cnb.yml            # 流水线:推送后自动构建 + 部署
├── build.js            # 静态站点生成器
├── site.config.js      # 站点配置(标题、导航、分页……)
├── posts/              # 文章,一个 Markdown 文件一篇
├── pages/              # 独立页面,如 about.md
└── src/
    ├── templates.js    # 页面模板
    └── assets/         # CSS / JS / 图标

build.js 干的事情很直白:读 posts/*.md → 解析 front matter → 渲染 Markdown → 套模板 → 输出到 dist/。同时顺手生成分页、标签页、归档页、RSS 和 sitemap。

文章长这样

每篇文章是 posts/ 下的一个 Markdown 文件,开头一段 front matter:

markdown
---
title: 用 CNB + EdgeOne Pages 搭一个免费静态博客
date: 2026-10-29
tags: [工程实践, CI/CD]
summary: 仓库即站点,推送代码 = 发布上线。
---

正文从这里开始……

文件名习惯写成 YYYY-MM-DD-slug.md,日期从文件名里取,front matter 里写了就以 front matter 为准。

流水线配置

.cnb.yml 是整条链路的入口,只在推送到 main 时触发:

yaml
main:
  push:
    - imports:
        - https://cnb.cool/<组织>/<密钥仓库>/-/blob/main/envs.yml
      stages:
        - name: 构建静态站点
          image: node:20
          script: npm ci && npm run build

        - name: 部署到 EdgeOne Pages
          image: node:20
          script: npx --yes edgeone@latest makers deploy ./dist -n <项目名> -t $EDGEONE_API_TOKEN

两个容易踩的点:

  1. EDGEONE_API_TOKEN 不要写死在仓库里。单独建一个私有"密钥仓库"存放 envs.yml,用 imports 引进来。这样公开仓库里不会泄露任何凭据。
  2. npm ci 需要 package-lock.json。提交锁文件能让构建结果稳定,也能避免 CI 里因为依赖漂移导致的偶发失败。

自定义域名

EdgeOne Pages 支持绑定自己的域名。步骤是在控制台添加域名、按提示改 DNS 解析,证书会自动签发。绑定完成后记得把 site.config.js 里的 siteUrl 改成正式域名,这样 RSS 和 sitemap 里生成的就是绝对地址。

小结

这套方案的好处是维护成本接近于零:

  • 不用管服务器,不用担心证书过期,不用打补丁;
  • 内容天生是纯文本,全部在 Git 里,迁移和备份都是一条命令;
  • 本地能构建,线上能构建,结果一致,不会出现"本地好好的,线上挂了"。

坏处也有:没有评论、没有后台、没有搜索。不过对个人博客来说,这些本来也不是必需品。