前言
以下是官方对 CNB 和 Lighthouse 的简单介绍:
云原生构建(Cloud Native Build,CNB)提供代码托管、云原生构建、云原生开发、AI 代码助手和制品库等功能。基于 Docker 生态,对环境、缓存、插件进行抽象,通过声明式的语法,帮助开发者以更酷的方式构建软件。
轻量应用服务器(Tencent Cloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、AI Agent、游戏服、电商应用、云盘和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以高性价比套餐形式整体售卖云资源,将热门软件打包实现一键构建应用,提供极简上云体验。
本文将结合 CNB 和 Lighthouse 的功能,以 Hexo 和 Go 为例,从前端的静态站点部署和后端的 Docker 容器化部署两方面,讲讲 CNB 和 Lighthouse 在构建和部署上的用法。
坐稳扶好,我们发车咯~
以 Hexo 为例的静态站点构建与部署
这是我的博客,由 Hexo 驱动,目前在 CNB 和 GitHub 均有仓库且都为私有仓库:


因此我的需求很简单:
- 由于 CNB 在大陆的拉取和推送体验优于 GitHub,每次更新博客后会推送到 CNB,希望能自动同步到 GitHub;
- 推送后自动运行 Hexo 生成器进行构建并打包产物;
- 将构建产物安全部署到服务器。
下面我将通过 CNB 提供的 git-sync、attachments、tcloud-cmd 三个官方插件实现以上需求。
从 CNB 同步到 GitHub
在根目录创建 .cnb.yml,该文件用于配置 CNB 流水线。
根据语法手册,我希望在所有分支的推送事件触发流水线,应配置如下规则:
"**" 用于匹配任意分支,push 表示推送事件,即匹配任意分支的推送事件;
stages 用于定义串行的阶段任务,也是我们接下来要配置的部分。
根据插件 git-sync 的说明,我们来填写同步任务所需的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13
| "**": push: - stages: - name: Sync to GitHub image: tencentcom/git-sync imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/github.yml settings: target_url: https://github.com/zhxycn/blog.git auth_type: https username: ${username} password: ${token} force: true
|
这里出现了 imports,我们要用它来导入密钥仓库里的配置文件,导入后,可以在该阶段通过环境变量来读取对应值。关于密钥仓库的说明,可以在这里找到。
在这之前,我们需要先前往 GitHub 生成一个密钥:
在密钥仓库创建一个文件,命名为 github.yml,内容如下:
1 2
| username: 你的 GitHub 用户名 token: 刚刚从 GitHub 得到的 Token
|
然后复制地址栏的链接到 imports 下,就完成了配置导入。
比如,我可以将现在这篇写了一半的文章推送到 CNB 的 new 分支,测试是否能正常同步:
1 2 3 4
| git checkout new git add . git commit -m ":pencil: p218: CNB × Lighthouse | 解锁构建部署新姿势" git push origin new
|
从云原生构建的运行日志中可以看到,流水线成功运行:

再看看 GitHub 仓库,完美~

自动构建并打包产物
我希望仅在 main 分支推送时触发自动构建,同时由于 Hexo 依赖 Node.js,我们指定 node:24 镜像作为构建时使用的基础环境,可以这样配置:
1 2 3 4 5 6
| main: push: - docker: image: node:24 volumes: - /usr/local/share/.cache/yarn:cow
|
这里的 volumes 用来定义数据卷,我们将数据卷以 cow (copy-on-write) 类型挂载到 /usr/local/share/.cache/yarn,该目录用来存放 Yarn 的缓存,加快构建流程。
完成了基础环境的定义,接下来就该定义构建流程了。配置过程和在终端运行一样,我们只需要按步来定义需要执行的命令就可以了。
1 2 3 4 5
| stages: - name: Install dependencies script: yarn install - name: Build script: yarn build
|
Hexo 生成器会将构建后的内容存放到 /public 目录,我们将目录下的文件打个包,暂且命名为 dist.tar.gz 吧~
1 2
| - name: Pack files script: tar -C public -cf - . | gzip -9 > dist.tar.gz
|
然后使用 attachments 插件把它上传到云原生构建的附件里:
1 2 3 4 5
| - name: Upload to attachments image: cnbcool/attachments:latest settings: attachments: - dist.tar.gz
|
那么完整的配置应该是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| "**": push: - stages: - name: Sync to GitHub image: tencentcom/git-sync imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/github.yml settings: target_url: https://github.com/zhxycn/blog.git auth_type: https username: ${username} password: ${token} force: true main: push: - docker: image: node:24 volumes: - /usr/local/share/.cache/yarn:cow stages: - name: Install dependencies script: yarn install - name: Build script: yarn build - name: Pack files script: tar -C public -cf - . | gzip -9 > dist.tar.gz - name: Upload to attachments image: cnbcool/attachments:latest settings: attachments: - dist.tar.gz
|
运行一下试试效果:

部署到服务器
对于一个静态资源来说,部署方式多种多样,可以使用 scp 或 rsync,官方也提供了相应的插件。但对于博主这样禁用了公网 SSH 和 22 端口的服务器来说,显得有点麻烦。
不过,既然 CNB 和腾讯云打通了生态,那就不得不拿出自动化助手 TAT 和 tcloud-cmd 插件了~
Lighthouse 服务器自带 TAT 客户端,但在开始之前,我们还是要检查一下 TAT 是否正常安装并运行。
在轻量应用服务器详情页的最底部,我们能看到 TAT 的状态:

随后再前往 https://console.cloud.tencent.com/cam 快速新建一个子用户:

注意红色方框内的内容,我们需要设置访问方式为编程访问,仅授予 QcloudTATFullAccess 权限,取消勾选重置密码,关闭操作保护并创建。
这样,我们就拿到了能调用 TAT 的密钥:

和上文一样,在密钥仓库创建一个 tcloud.yml 文件,将刚刚拿到的密钥填入:
先贴出我的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| - name: Deploy image: tencentcom/tcloud-cmd imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/tcloud.yml settings: secret_id: ${secret_id} secret_key: ${secret_key} region: ap-shanghai instance_ids: lhins-a1b2c3d4 script: | curl -L --fail \ -H "Authorization: Bearer ${CNB_TOKEN}" \ -H "Accept: application/vnd.cnb.api+json" \ -o ~/dist.tar.gz \ "${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/commit-assets/download/${CNB_COMMIT}/dist.tar.gz" mkdir -p ~/dist tar -C ~/dist -xzf ~/dist.tar.gz rsync -avz --delete ~/dist/ /www/wwwroot/blog/ rm -rf ~/dist ~/dist.tar.gz
|
除了 imports,这里还有几个参数需要注意一下,要根据情况来修改:
| 参数 |
说明 |
region |
服务器所在地域,可以从这里查询,一般为 ap-<地区名称> |
instance_ids |
服务器实例 ID,可以在服务器详情页找到,支持以 , 分隔的多个实例 |
script |
要在服务器上执行的命令 |
由于我的仓库为私有仓库,下载构建阶段生成的附件需要鉴权,因此需要使用 curl 命令携带 Authorization 头进行下载,当然公开仓库不需要这一步。
通过查询 CNB 的默认环境变量,CNB_TOKEN 为用户临时令牌,会在流水线结束时销毁,可用于代码和制品的拉取、推送以及 API 调用。
云原生构建附件的目录也可以通过拼接得出:
1
| ${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/commit-assets/download/${CNB_COMMIT}/dist.tar.gz
|
于是很容易写出如下命令:
1 2 3 4 5
| curl -L --fail \ -H "Authorization: Bearer ${CNB_TOKEN}" \ -H "Accept: application/vnd.cnb.api+json" \ -o ~/dist.tar.gz \ "${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/commit-assets/download/${CNB_COMMIT}/dist.tar.gz"
|
接下来是解压后放到对应目录,就不用多说了:
1 2 3 4
| mkdir -p ~/dist tar -C ~/dist -xzf ~/dist.tar.gz rsync -avz --delete ~/dist/ /www/wwwroot/blog/ rm -rf ~/dist ~/dist.tar.gz
|
这样,我们就完成了一个静态站点从构建到部署的自动化流程,最后贴一下完整的流水线配置吧~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| main: push: - docker: image: node:24 volumes: - /usr/local/share/.cache/yarn:cow stages: - name: Install dependencies script: yarn install - name: Build script: yarn build - name: Pack files script: tar -C public -cf - . | gzip -9 > dist.tar.gz - name: Upload to attachments image: cnbcool/attachments:latest settings: attachments: - dist.tar.gz - name: Deploy image: tencentcom/tcloud-cmd imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/tcloud.yml settings: secret_id: ${secret_id} secret_key: ${secret_key} region: ap-shanghai instance_ids: lhins-a1b2c3d4 script: | curl -L --fail \ -H "Authorization: Bearer ${CNB_TOKEN}" \ -H "Accept: application/vnd.cnb.api+json" \ -o ~/dist.tar.gz \ "${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/commit-assets/download/${CNB_COMMIT}/dist.tar.gz" mkdir -p ~/dist tar -C ~/dist -xzf ~/dist.tar.gz rsync -avz --delete ~/dist/ /www/wwwroot/blog/ rm -rf ~/dist ~/dist.tar.gz
|
在调用 TAT 运行后,我们还可以在命令执行记录中查看运行结果,满足了调试和审计需求:

以 Go 为例的 Docker 容器化部署
这是一个由我和团队维护的 Go 语言项目:

对于这个项目,我的需求如下:
- 在
main 分支提交后,自动构建 dev 标记的 Docker 镜像,然后部署到测试环境;
- 在测试完成,创建 Tag 后,自动构建
latest 标记的 Docker 镜像,然后部署到生产环境。
下面我将通过 CNB 的 Docker 制品库和 tcloud-cmd 插件实现以上需求。
自动构建
对于一个在 Docker 运行的项目,自然少不了 Dockerfile,我们应该将程序的构建过程在 Dockerfile 中完成定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| FROM golang:alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./ RUN go mod download
COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o server ./cmd
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/server .
ENV TZ="Asia/Shanghai" ENV DATABASE=""
EXPOSE 8080
CMD ["./server"]
|
有了 Dockerfile,构建镜像就很简单了:
1 2 3 4 5 6 7 8 9
| main: push: - services: - docker stages: - name: docker build script: docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:dev . - name: docker push script: docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:dev
|
这两步会生成一个与仓库同名的镜像,并推送到仓库对应的制品库中。至于生产环境,我们只需要稍微调整一下触发条件和 Docker 镜像的标签:
1 2 3 4 5 6 7 8 9
| $: tag_push: - services: - docker stages: - name: Docker build script: docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest . - name: Docker push script: docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest
|
在运行成功后,就可以在制品库中看到构建的镜像了:

部署到服务器
和上文一样,我们依然可以使用 tcloud-cmd 插件调用 TAT 在服务器中完成镜像的拉取和部署,配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| - name: Deploy image: tencentcom/tcloud-cmd imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/tcloud.yml - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/project.yml settings: secret_id: ${secret_id} secret_key: ${secret_key} region: ap-shanghai instance_ids: lhins-a1b2c3d4 script: | sudo docker stop ${CNB_REPO_NAME_LOWERCASE} || true sudo docker rm ${CNB_REPO_NAME_LOWERCASE} || true sudo docker run -d --name ${CNB_REPO_NAME_LOWERCASE} \ -p 8080:8080 \ -e TZ="Asia/Shanghai" \ -e DATABASE="${DATABASE}" \ ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:dev query_instance: true
|
镜像拉取可以通过腾讯云内网完成,在解决了 Docker Hub 在国内无法拉取的痛点上,又提高了部署效率。
对于不同部署环境来说,只需要调整对应的定义。若仓库为私有仓库,需要多一条登录到 CNB Docker 制品库的命令:
1
| sudo docker login docker.cnb.cool -u cnb -p ${CNB_TOKEN}
|
除文中提到的流水线外,高阶用户还可以参考文档中的自定义部署流程来实现审批流程。同样的,也可以利用 YAML 语法特性来简化配置文件。
以下是经过简化的完整配置~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| .job: &job services: - docker stages: - name: docker build script: docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${image_tag} . - name: docker push script: docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${image_tag} - name: Deploy image: tencentcom/tcloud-cmd imports: - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/tcloud.yml - https://cnb.cool/CatNya/zhxycn/secrets/-/blob/main/project.yml settings: secret_id: ${secret_id} secret_key: ${secret_key} region: ap-shanghai instance_ids: ${instance_ids} script: | sudo docker stop ${CNB_REPO_NAME_LOWERCASE} || true sudo docker rm ${CNB_REPO_NAME_LOWERCASE} || true sudo docker run -d --name ${CNB_REPO_NAME_LOWERCASE} \ -p 8080:8080 \ -e TZ="Asia/Shanghai" \ -e DATABASE="${DATABASE}" \ ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${image_tag} query_instance: true main: push: - env: instance_ids: lhins-a1b2c3d4 image_tag: dev <<: *job "*": tag_push: - env: instance_ids: lhins-a1b2c3d4 image_tag: latest <<: *job
|
结语
CNB 与腾讯云生态结合带来了高效的 CI/CD 流程。无论是静态站点的自动更新,还是容器化应用的持续交付,CNB 强大的插件生态和声明式的流水线配置,无疑能简化我们的构建与部署工作。