使用 Encore CLI 集成 CI/CD 流水线:Docker 镜像构建与自动化部署实战
2026/9/15 11:08:15 网站建设 项目流程

使用 Encore CLI 集成 CI/CD 流水线:Docker 镜像构建与自动化部署实战

【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore

Encore 提供了与任何主流 CI/CD 流水线无缝集成的 CLI 工具链,其中最核心的是encore build docker命令——一条命令即可把 Encore 应用打包为可移植的 Docker 镜像,从而接入 GitHub Actions、GitLab CI、Jenkins 等任意构建编排系统。本文基于 Encore 开源仓库中的 docs/go/self-host/ci-cd.md,结合 CLI 与镜像构建的源码实现,完整讲解 CI 环境中的 CLI 安装认证、镜像构建参数、平台差异处理与端口定制,并给出一个可直接照抄的 GitHub Actions + DigitalOcean 部署示例。读完本文,你将能够把 Encore 应用稳定地接入自己的 CI/CD 流水线,实现"代码推送即自动构建、推送、部署"的完整闭环。

一、CI/CD 集成总体思路:四个关键步骤

虽然每家 CI/CD 流水线的形态各不相同,但集成 Encore 遵循一个非常统一的流程:

  1. 安装 Encore CLI:在 CI 环境中安装 Encore CLI(runner 或构建容器内);
  2. 构建 Docker 镜像:使用encore build docker命令生成应用镜像;
  3. 推送镜像:将镜像推送到你的容器镜像仓库(Container Registry);
  4. 部署:由你的基础设施按既定策略拉取并部署新镜像。

所有主流 CI/CD 平台都能按此模式集成,差异仅在于各平台调用 CLI 的具体语法(如 GitHub Actions 的run步骤、GitLab CI 的script字段等)。具体到 CLI 工具的接入方式,可以参考你所使用平台的官方文档。

二、CI 环境中的 CLI 安装与认证

2.1 安装 Encore CLI

Encore CLI 本身就是一个静态分发的命令行工具。在你的 CI 流水线中,下载官方安装脚本并执行即可完成安装。以 GitHub Actions 为例,可以通过curl拉取安装脚本后执行:

curl --output install.sh -L https://encore.dev/install.sh bash install.sh

安装完成后,可执行文件位于/home/runner/.encore/bin/encore(不同平台的默认安装目录可能不同,建议在安装步骤中确认实际路径,并在后续步骤中统一使用该绝对路径调用)。

2.2 使用 Auth Key 进行非交互式认证

在本地开发环境中,开发者通常通过encore auth login的交互式设备授权(Device Auth)流程登录。但在 CI 环境中无法进行交互式浏览器授权,因此 Encore 提供了Auth Key(认证密钥)机制用于非交互式认证。

在 Encore Cloud(若你的应用与其关联)中,从App Settings > Auth Keys页面生成一个 Auth Key,将其作为 CI secret 存储到你的 CI 平台中,然后在构建之前执行:

encore auth login --auth-key=${{ secrets.ENCORE_AUTH_KEY }}

从源码看,该机制位于 cli/cmd/encore/auth/auth.go:

  • encore auth login支持--auth-key(短选项-k)参数,定义见 auth.go 第 76 行;
  • --auth-key非空时,CLI 调用DoLoginWithAuthKey(),内部走login.WithAuthKey()流程,将凭证写入本地配置文件(auth.go 第 123-133 行);未指定时则回退到设备授权流程。

这也意味着:如果你的自托管/自有基础设施部署不依赖 Encore Cloud,而是完全通过本地 daemon 与 Docker 交互构建,那么这一步认证可以按需省略(详见下文对--push与镜像推送的说明)。

三、GitHub Actions 完整示例:构建、推送并部署到 DigitalOcean

下面这段工作流来自 ci-cd.md,展示了完整的"提交到main分支 → 构建镜像 → 推送镜像 → 触发部署"闭环。示例中 DigitalOcean 应用被配置为:每当仓库中出现latest标签的镜像被上传时,自动重新部署

name: Build, Push and Deploy a Encore Docker Image to DigitalOcean on: push: branches: [ main ] permissions: contents: read packages: write jobs: build-push-deploy-image: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Download Encore CLI script uses: sozo-design/curl@v1.0.2 with: args: --output install.sh -L https://encore.dev/install.sh - name: Install Encore CLI run: bash install.sh - name: Authenticate with Encore run: /home/runner/.encore/bin/encore auth login --auth-key=${{ secrets.ENCORE_AUTH_KEY }} - name: Log in to DigitalOcean container registry run: docker login registry.digitalocean.com -u my-email@gmail.com -p ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - name: Build Docker image run: /home/runner/.encore/bin/encore build docker myapp - name: Tag Docker image run: docker tag myapp registry.digitalocean.com/<YOUR_CONTAINER_REGISTRY_NAME>/<YOUR_IMAGE_REPOSITORY_NAME>:latest - name: Push Docker image run: docker push registry.digitalocean.com/<YOUR_CONTAINER_REGISTRY_NAME>/<YOUR_IMAGE_REPOSITORY_NAME>:latest

拆解各步骤的作用:

步骤说明
Checkout repository拉取源码,actions/checkout@v4是官方 checkout action
Download / Install Encore CLI下载并执行官方安装脚本,安装 Encore CLI
Authenticate with Encore使用ENCORE_AUTH_KEY这个 CI secret 完成非交互式登录
Log in to DigitalOcean container registry使用DIGITALOCEAN_ACCESS_TOKEN登录 DigitalOcean 容器仓库(此处账号替换为你自己的注册邮箱)
Build Docker image调用encore build docker myapp,在本地 Docker daemon 中生成名为myapp的镜像(IMAGE_TAGmyapp
Tag Docker image将本地镜像打上目标仓库的latest标签
Push Docker image推送到容器仓库,触发 DigitalOcean 侧配置的自动重部署

使用这套工作流时,需要把my-email@gmail.com<YOUR_CONTAINER_REGISTRY_NAME><YOUR_IMAGE_REPOSITORY_NAME>替换为你自己的实际值,并在 GitHub 仓库的 Settings → Secrets 中配置ENCORE_AUTH_KEYDIGITALOCEAN_ACCESS_TOKEN

3.1 为什么先encore build docker再用docker tag

细心的读者会发现:示例中先让 Encore 构建出本地镜像,再用docker tag打上目标仓库标签。这是因为encore build docker默认把镜像输出到本地 Docker daemon(镜像名即你传入的IMAGE_TAG),而不是直接推到远端。从 cli/daemon/export/export.go 的源码可以看到:

  • 未指定--push时,LocalDaemonTag被设置,镜像导出到本地 daemon;
  • 指定--push时,PushDestinationTag被设置,镜像直接推送远端。

因此,默认模式下构建完成后用docker tag+docker push手动编排标签与推送,是灵活且常见的做法。

四、深入encore build docker:参数与平台定制

encore build docker提供了丰富的选项用于定制构建行为。以下是 ci-cd.md 中给出的三种典型用法:

# 构建指定的服务和网关 encore build docker --services=service1,service2 --gateways=api-gateway MY-IMAGE:TAG # 自定义基础镜像 encore build docker --base=node:18-alpine MY-IMAGE:TAG # 为特定架构构建(当 CI 架构与部署目标不一致时尤其有用) encore build docker --arch=arm64 MY-IMAGE:TAG

结合 cli/cmd/encore/build.go 的源码,该命令支持的全部参数如下:

参数源码定义默认值说明
IMAGE_TAG(位置参数)cobra.ExactArgs(1)必填镜像标签名,作为镜像名称使用
--servicesStringSlice全部仅包含指定服务,多个用逗号分隔
--gatewaysStringSlice全部仅包含指定网关,多个用逗号分隔
--baseStringscratch基础镜像;Go 应用默认scratch,TS 应用自动回退为node:slim
--archOneofamd64目标架构,仅允许amd64/arm64
--osOneoflinux目标操作系统,当前仅允许linux
--cgoBool默认取CGO_ENABLED或应用配置是否启用 cgo
--push/-pBoolfalse构建后直接推送镜像到远端仓库
--configString指定基础设施配置文件(infra config)路径
--skip-configBoolfalse不读取也不生成基础设施配置文件

几点从源码确认的重要细节:

  • 基础镜像的默认值不是写死的:CLI 会读取应用根目录下的应用配置文件(appfile.ParseFile),当检测到是 TypeScript 应用且用户未显式指定--base时,自动使用node:slim作为基础镜像(见 build.go 第 51-59 行);Go 应用则保持scratch空镜像。
  • 架构选择应对"CI 与部署目标不一致":例如 CI runner 是 amd64,而生产环境是 arm64 服务器,通过--arch=arm64即可在 x86 的 CI 上产出 arm64 镜像。
  • build命令带有eject别名encore build整体负责"为部署构建你的应用",docker是它的子命令;从源码结构看,未来还可能扩展其他输出格式。

4.1 关于--push直推模式

如果你的部署流水线希望跳过docker tag的中间步骤,可以直接使用--push配合完整的目标仓库地址:

encore build docker --push registry.example.com/myorg/myapp:latest

此时镜像构建完成后会直接推送到远端仓库(对应PushDestinationTag逻辑),推送认证依赖执行环境中已配置好的 Docker/仓库凭据。

五、镜像运行时行为:端口与环境变量

encore build docker产出的镜像默认在 8080 端口监听,你可以通过设置PORT环境变量在启动时自定义端口:

docker run -e PORT=8081 -p 8081:8081 MY-IMAGE:TAG

这条规则的实现位于 supervisor(镜像内的进程管理组件)源码中。镜像入口由 supervisor 进程代理,它启动时会读取环境变量来决定监听端口:

  • supervisor/src/bin/supervisor-encore.rs:从PORT环境变量读取端口,未设置时回退到默认值8080
  • supervisor/src/config.rs:将PORT写入 supervisor 的运行时配置中,供内部各服务端口分配使用。

因此在容器编排平台(如 Kubernetes、DigitalOcean App Platform)中,直接通过环境变量注入PORT即可适配平台要求的不同端口,无需重新构建镜像。

六、源码视角:encore build docker背后发生了什么

理解镜像构建的内部实现,有助于排查 CI 中的构建问题。整个流程分布在两个层面:

6.1 CLI 层:把参数翻译成 daemon 请求

encore build docker的 CLI 实现(cli/cmd/encore/build.go)本身并不直接打镜像,而是:

  1. 解析参数,组装DockerExportParams(基础镜像、本地 daemon 标签或推送目标标签);
  2. 解析--config为绝对路径(build.go 第 121-127 行);
  3. 连接本地 daemon,通过 gRPC 调用daemon.Export,请求中携带Goos/Goarch/CgoEnabledServices/Gateways列表以及基础设施配置路径;
  4. 实时流式输出构建日志(cmdutil.StreamCommandOutput)。

6.2 daemon 层:镜像如何被组装

真正执行镜像构建的是 pkg/dockerbuild/dockerbuild.go 中的BuildImage函数。其核心步骤包括:

  • 解析基础镜像scratch或空字符串解析为空镜像,其他基础镜像通过remote.Image从远端拉取(dockerbuild.go 第 135-153 行),并按目标 OS/架构(remote.WithPlatform)拉取对应平台变体;
  • 分层打包文件系统buildImageFilesystem依次组装源码层、依赖层、运行时层(supervisor 二进制)、配置层(supervisor 配置、构建信息)以及证书层(CA 证书,写入/etc/ssl/certs/ca-certificates.crt)等多个镜像层;
  • 固定时间戳保证可复现:所有文件使用固定的layerEpoch(Unix 时间 0)作为时间戳,使未变化的层在不同构建之间保持相同 digest(dockerbuild.go 第 32-35 行)——这意味着 CI 中重复构建相同代码可以得到可复现的镜像层,利于缓存与增量部署;
  • 设置镜像配置:写入入口点(Entrypoint)、工作目录、环境变量、架构与系统类型,并标注encore.dev作为作者。

需要 CA 证书的场景(如镜像内需要访问外部 HTTPS 服务)由--base基础镜像的内容与证书层共同决定;使用scratch作为基础镜像时,默认不包含证书,这一点在定制基础镜像时需要注意。

七、CI/CD 集成最佳实践小结

综合文档与源码,落地 Encore CI/CD 集成时建议遵循以下几点:

  1. 在 CI 中始终使用非交互式认证:通过 Auth Key(encore auth login --auth-key=<KEY>)代替本地设备授权;Auth Key 作为 CI secret 管理,详见 auth-keys 文档。
  2. 固定 CLI 安装路径:CI 中安装 Encore CLI 后,后续步骤统一使用绝对路径(如/home/runner/.encore/bin/encore)调用,避免 PATH 不一致导致的偶发失败。
  3. 区分构建机架构与目标架构:当 CI runner 架构与部署目标不同(如 amd64 runner 部署到 arm64 集群)时,用--arch指定目标架构。
  4. 按需裁剪镜像内容:多服务应用可通过--services/--gateways仅打包需要的部分,加快构建与拉取速度。
  5. 端口交给平台注入:镜像默认监听 8080,通过PORT环境变量适配各平台,尽量不在镜像内硬编码端口。
  6. 善用"推送即部署"模式:配合 DigitalOcean、Kubernetes 等平台的"镜像更新自动重部署"能力,构建完成后直接推送带latest或版本标签的镜像即可触发部署,无需额外部署步骤。

至此,你已经掌握了 Encore 应用接入 CI/CD 的完整链路:安装认证 →encore build docker构建 → 镜像推送 → 平台自动部署。接下来可以进一步阅读配置基础设施与自托管总览,了解镜像部署到自有基础设施时的环境变量、基础设施配置与服务发现细节。

【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询