尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Encore 自托管实战:用 `encore build docker` 从 CLI 构建可移植的 Docker 镜像

Encore 自托管实战:用 `encore build docker` 从 CLI 构建可移植的 Docker 镜像 Encore 自托管实战用encore build docker从 CLI 构建可移植的 Docker 镜像【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore本文围绕 Encore开源 Backend Framework 与基础设施平台的官方自托管文档展开系统讲解如何通过encore build docker命令在自有基础设施上构建、定制并运行 Encore 应用的 Docker 镜像。读完本文你将掌握镜像构建的全部命令行参数、基础设施配置文件Infra Config的完整编写方法以及如何将镜像构建集成进 GitHub Actions 等 CI/CD 流水线实现完全脱离 Encore Cloud 的自主部署。1. 为什么需要自托管 Docker 镜像Encore 官方文档明确给出了自托管镜像的适用场景当 Encore Cloud 不适合你的用例时或者当你计划 迁移离开 Encore 时直接基于 CLI 构建 Docker 镜像是一个可靠的选择。关键设计事实来自官方文档encore build docker走的是与 Encore 云平台 CI 系统完全相同的代码路径。这意味着你在本地构建出的镜像与 Encore Cloud 构建出的镜像保持行为一致不存在兼容性差异。这一点也是官方迁移指南 migrate-away 中零迁移成本论点的技术基础自托管的应用本身就是一个普通程序只有约 1% 的代码是 Encore 特有的而部署环节用encore build docker即可平滑接续。2. 快速上手构建你的第一个镜像构建镜像只需一条命令encore build docker MY-IMAGE:TAG该命令会先在宿主机上完成 Encore 应用的编译包括解析、构建应用模型、生成运行时配置等完整流水线然后产出一个包含编译后应用的 Docker 镜像。基础镜像默认值分语言而异Go 应用默认使用scratch极简空镜像体积最小TypeScript 应用默认使用node:slim需要 Node.js 运行时环境。默认情况下镜像会包含你应用中的所有服务并随镜像一同启动。如果你只想打包部分服务与网关可以使用--services和--gateways参数见下一节。构建完成后镜像默认在8080 端口对外提供服务你可以通过设置PORT环境变量来自定义端口docker run -e PORT8081 -p 8081:8081 MY-IMAGE:TAG2.1 参数对照encore build docker全部标志上述命令的底层实现在 cli/cmd/encore/build.go以下标志均能在该文件中找到对应定义标志默认值说明IMAGE_TAG位置参数必填镜像标签例如myapp:latest--basescratchGo/node:slimTS自定义基础镜像如node:18-alpine--services全部逗号分隔的、要包含进镜像的服务名列表--gateways全部逗号分隔的、要包含进镜像的网关列表--archamd64目标 CPU 架构允许值amd64、arm64--oslinux目标操作系统当前仅允许linux-p, --push关闭构建完成后将镜像推送到远程镜像仓库--config无基础设施配置文件Infra Config的路径--skip-config关闭跳过读取或生成基础设施配置文件--cgo关闭读取CGO_ENABLED环境变量启用 CGO3. 定制镜像服务、架构、基础镜像与推送3.1 只打包指定服务与网关当你的应用由多个服务组成但希望某些镜像只承担部分职责例如分离 API 网关与后台 Worker时encore build docker --servicesservice1,service2 --gatewaysapi-gateway MY-IMAGE:TAG--services与--gateways在源码中定义为StringSlice类型build.go支持逗号分隔多个值。这一能力在拆分微服务镜像、控制镜像体积时非常实用。3.2 指定目标架构当构建机器的架构与部署目标不一致时例如在 x86 开发机上为 ARM 服务器构建使用--arch指定目标架构encore build docker --archarm64 MY-IMAGE:TAG源码层面--arch的可选值被约束为amd64与arm64build.go且--os当前仅允许linux。从 export.go 可以看出该值会被传递到编译参数GOARCH/GOOS中确保交叉编译产物与目标平台匹配。3.3 自定义基础镜像如果你需要 CA 证书、时区数据或系统工具链可以替换基础镜像encore build docker --basenode:18-alpine MY-IMAGE:TAG在 export.go 的resolveBaseImage实现中基础镜像的解析顺序是先尝试从本地 Docker daemon 获取若本地没有或架构不匹配则按目标平台从远程仓库拉取如果同时指定了本地保存标签还会把拉取到的镜像回写到本地 daemon。3.4 构建后直接推送配合 CI/CD 场景--push标志会在构建完成后直接推送镜像到远端仓库源码中对应PushDestinationTag见 export.goencore build docker --push MY-IMAGE:TAG4. 镜像构建的底层流程源码视角理解镜像内部结构有助于排查部署问题。以 cli/daemon/export/export.go 中的Docker函数为线索一次encore build docker调用会依次经历解析与编译通过builderimpl.Resolve解析应用语言Go/TS依次执行Prepare → Parse → Compile并携带StaticLink: true、DebugModeDisabled等生产构建参数构建前后还会触发appfile.Hook中配置的 PreBuild / PostBuild 钩子export.go。生成镜像描述dockerbuild.Describe根据编译产物、运行时路径、基础镜像等生成ImageSpec对于 TS 应用或配置了bundle_source的 Go 应用会把工作区源码一并打入镜像的/workspace目录排除.gitexport.go。嵌入基础设施配置将 Infra Config 以 JSON 形式写入镜像内的/encore/infra.config.json并通过环境变量ENCORE_INFRA_CONFIG_PATH/encore/infra.config.json告知应用运行时加载位置export.go 与 infra_config.go。每个服务对应的 CUE 配置也会以ENCORE_CFG_SERVICE_NAMEBase64 编码的形式注入环境变量。进程管理当镜像需要以每服务一个进程模式运行时镜像内会嵌入supervisor-encore守护进程二进制pkg/dockerbuild/dockerbuild.go 中的setupSupervisor由 supervisor 负责统一拉起和监管各服务进程。构建与输出dockerbuild.BuildImage完成镜像组装随后根据参数选择写入本地 Docker daemonLocalDaemonTag或推送到远端仓库PushDestinationTag。这套流水线同时也是 Encore 云平台 CI 的镜像构建实现这正是官方文档强调完全兼容、同一代码路径的源码级依据。5. 为运行时提供基础设施配置Infra Config如果你的应用使用了 SQL 数据库、Pub/Sub、缓存、对象存储等基础设施资源那么必须为镜像提供基础设施配置否则应用无法正确连接资源。通过--config标志指定配置文件路径encore build docker --config path/to/infra-config.json MY-IMAGE:TAG配置文件是一个遵循Encore Infra Config Schema的 JSON 文件用于声明基础设施资源的访问方式使用哪个云提供商、什么凭据等服务间网络调用Service Discovery尤其是各服务的 base URL可观测性配置指标导出到哪里等运行环境元数据供 Encore 的 metadata API 使用应用声明的 secrets 取值。5.1 一个完整的配置示例{ $schema: https://encore.dev/schemas/infra.schema.json, metadata: { app_id: my-app, env_name: my-env, env_type: production, cloud: gcp, base_url: https://my-app.com }, sql_servers: [ { host: my-db-host:5432, databases: { my-db: { username: my-db-owner, password: {$env: DB_PASSWORD} } } } ], service_discovery: { myservice: { base_url: https://myservice:8044 } }, redis: { my-redis: { database_index: 0, auth: { type: acl, username: encoreredis, password: {$env: REDIS_PASSWORD} }, host: my-redis-host } }, metrics: { type: prometheus, remote_write_url: https://my-remote-write-url }, graceful_shutdown: { total: 30 }, auth: [ { type: key, id: 1, key: {$env: SVC_TO_SVC_KEY} } ], secrets: { AppSecret: {$env: APP_SECRET} }, pubsub: [ { type: gcp_pubsub, project_id: my-project, topics: { my-topic: { name: gcp-topic-name, subscriptions: { encore-subscription: { name: gcp-subscription-name } } } } } ], object_storage: [ { type: gcs, buckets: { my-gcs-bucket: { name: my-gcs-bucket } } } ] }5.2 环境元数据配置{ metadata: { app_id: my-encore-app, env_name: production, env_type: production, cloud: aws, base_url: https://api.myencoreapp.com } }app_idEncore 应用的 ID。env_name环境名如production、staging、development。env_type环境类型可取production、test、development、ephemeral。cloud托管基础设施的云提供商如aws、gcp、azure。base_url环境中各服务的基础 URL供 Encore 的 metadata API 使用。5.3 优雅停机配置{ graceful_shutdown: { total: 30, shutdown_hooks: 10, handlers: 20 } }total整个停机过程允许的总时长秒。shutdown_hooks执行 shutdown hooks 允许的时长。handlers停机期间处理完进行中请求所允许的时长。5.4 服务间认证配置如果服务部署在 VPC 等私有网络中未指定认证方法时私有端点不需要认证但当服务需要通过公网互访时建议配置认证确保私有端点只对后端服务开放。当前 Encore 支持共享密钥shared key认证{ auth: [ { type: key, id: 1, key: { $env: SERVICE_API_KEY } } ] }type认证方式类型目前为key。id该认证方式的 ID。key认证密钥可通过环境变量引用$env注入。5.5 服务发现Service Discovery配置服务发现用于让服务通过网络访问其他服务。注意如果你把所有服务都打进了同一个镜像则无需配置 service discovery——服务启动时会自动完成相互发现。{ service_discovery: { myservice: { base_url: https://myservice.myencoreapp.com, auth: [ { type: key, id: 1, key: { $env: MY_SERVICE_API_KEY } } ] } } }myservice服务名须与 Encore 应用中声明的服务名一致。base_url该服务的基础 URL。auth访问该服务使用的认证方法若省略则回落到顶层auth段定义的认证方法。5.6 指标导出配置Encore 支持四种指标导出目标Prometheus、DataDog、GCP Cloud Monitoring、AWS CloudWatch。Prometheus{ metrics: { type: prometheus, collection_interval: 15, remote_write_url: { $env: PROMETHEUS_REMOTE_WRITE_URL } } }Datadog{ metrics: { type: datadog, collection_interval: 30, site: datadoghq.com, api_key: { $env: DATADOG_API_KEY } } }GCP Cloud Monitoring{ metrics: { type: gcp_cloud_monitoring, collection_interval: 60, project_id: my-gcp-project, monitored_resource_type: gce_instance, monitored_resource_labels: { instance_id: 1234567890, zone: us-central1-a }, metric_names: { cpu_usage: compute.googleapis.com/instance/cpu/usage_time } } }AWS CloudWatch{ metrics: { type: aws_cloudwatch, collection_interval: 60, namespace: MyAppMetrics } }5.7 SQL 数据库配置应用中声明的每个数据库都必须在配置文件中给出对应条目每个数据库恰好一条一个sql_servers数组可包含多个 SQL server{ sql_servers: [ { host: db.myencoreapp.com:5432, tls_config: { disabled: false, ca: ---BEGIN CERTIFICATE---\n..., disable_tls_hostname_verification: false, disable_ca_verification: false }, databases: { my-database: { name: my-postgres-db-name, max_connections: 100, min_connections: 10, username: db_user, password: { $env: DB_PASSWORD } } } } ] }my-database数据库在数据库服务器上的名称。name数据库在 Encore 应用中声明的名称默认为 map 的键名。hostSQL server 主机可包含端口。tls_configTLS 配置。若服务器使用了非系统 CA 根证书的 TLS或需要客户端证书则在此以 PEM 字符串填写相应字段否则留空即可。databases数据库列表每项包含连接设置用户名、密码、最大/最小连接数等。5.8 Secrets 配置方式一直接指定——直接在配置文件中写死 secret 值或用环境变量引用{ secrets: { API_TOKEN: embedded-secret-value, DB_PASSWORD: { $env: DB_PASSWORD } } }其中API_TOKEN是应用声明的 secret 名称。方式二整体环境变量引用——将整个 secrets 映射放进一个环境变量环境变量内容是 JSON 字符串键为 secret 名值为 secret 值{ secrets: { $env: SECRET_JSON } }5.9 Redis 配置{ redis: { my-redis: { host: redis.myencoreapp.com:6379, database_index: 0, auth: { type: auth_string, auth_string: { $env: REDIS_AUTH_STRING } }, max_connections: 50, min_connections: 5 } } }my-redisRedis 资源在 Encore 应用中声明的名称。hostRedis 服务器主机可包含端口。auth认证配置示例使用auth_string类型综合示例中的acl类型则需usernamepassword。key_prefix应用到所有 key 的前缀。5.10 Pub/Sub 配置当前支持的 Pub/Sub 提供商nsqNSQgcp_pubsubGoogle Cloud Pub/Subaws_sns_sqsAWS SNS SQSazureAzure Service Bus。GCP Pub/Sub{ pubsub: [ { type: gcp_pubsub, project_id: my-gcp-project, topics: { my-topic: { name: my-topic, project_id: my-gcp-project, subscriptions: { my-subscription: { name: my-subscription, push_config: { id: my-push, service_account: service-accountmy-gcp-project.iam.gserviceaccount.com } } } } } } ] }my-topic/my-subscription与 Encore 应用中声明的 topic / subscription 名称一致。project_id默认的 GCP project ID可在 topic 或 subscription 级别覆盖。nametopic 或 subscription 的实际名称。push_config/id该 id 会被拼接到/__encore/pubsub/push/之后形成完整的推送路径如/__encore/pubsub/push/id即你的服务接收 push 消息的路径。push_config/service_account为 push subscription 配置的服务账号。AWS SNS/SQS{ pubsub: [ { type: aws_sns_sqs, topics: { my-topic: { arn: arn:aws:sns:us-east-1:123456789012:my-topic, subscriptions: { my-queue: { url: https://sqs.eu-east-1.amazonaws.com/123456789012/my-queue } } } } } ] }arnSNS topic 的 ARN。urlSQS 队列的 URL。NSQ{ pubsub: [ { type: nsq, hosts: nsq.myencoreapp.com:4150, topics: { my-topic: { name: my-topic, subscriptions: { my-subscription: { name: my-subscription } } } } } ] }5.11 对象存储配置当前支持的对象存储提供商gcsGoogle Cloud Storage与s3AWS S3 或任意 S3 兼容服务。GCS{ object_storage: [ { type: gcs, buckets: { my-gcs-bucket: { name: my-gcs-bucket, key_prefix: my-optional-prefix/, public_base_url: https://my-gcs-bucket-cdn.example.com/my-optional-prefix } } } ] }S3{ object_storage: [ { type: s3, region: us-east-1, buckets: { my-s3-bucket: { name: my-s3-bucket, key_prefix: my-optional-prefix/, public_base_url: https://my-gcs-bucket-cdn.example.com/my-optional-prefix } } } ] }namebucket 的完整名称。key_prefix可选应用到 bucket 内所有 key 的前缀。public_base_url若将 bucket 配置为公开访问此项必填Encore 生成公开 URL 时会把对象 key 追加到该 URL 之后前缀不会被追加。自定义 S3 提供商适用于 Cloudflare R2 等 S3 兼容存储{ object_storage: [ { type: s3, region: auto, endpoint: https://..., access_key_id: ..., secret_access_key: { $env: BUCKET_SECRET_ACCESS_KEY }, buckets: { my-custom-bucket: { name: my-custom-bucket, key_prefix: my-optional-prefix/, public_base_url: https://my-gcs-bucket-cdn.example.com/my-optional-prefix } } } ] }6. 集成到 CI/CD 流水线encore build docker天然适配任何 CI/CD 平台官方 CI/CD 集成文档 给出的通用流程是四步在 CI 环境中安装 Encore CLI使用encore build docker创建 Docker 镜像将镜像推送到你的容器镜像仓库部署到你的基础设施。如果你的应用与 Encore Cloud 关联需要在 CI 中先完成 CLI 认证在 Encore Cloud 控制台的App Settings Auth Keys中生成一个 auth key存入 CI 的 secret然后在构建前执行encore auth login --auth-keyKEY6.1 GitHub Actions 完整示例以下示例展示了如何用 GitHub Actions 构建 Encore Docker 镜像并推送到 DigitalOceanDigitalOcean 应用配置为每次有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/checkoutv4 - name: Download Encore CLI script uses: sozo-design/curlv1.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-emailgmail.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:latest6.2 CI 环境中的构建定制CI 机器的架构与部署目标往往不同此时可组合使用构建参数# 只构建指定服务和网关 encore build docker --servicesservice1,service2 --gatewaysapi-gateway MY-IMAGE:TAG # 自定义基础镜像 encore build docker --basenode:18-alpine MY-IMAGE:TAG # 为指定架构构建CI 与部署目标架构不同时尤其有用 encore build docker --archarm64 MY-IMAGE:TAG镜像默认监听 8080 端口可通过PORT环境变量覆盖docker run -e PORT8081 -p 8081:8081 MY-IMAGE:TAG7. 自托管之后的下一步构建并运行起镜像只是自托管的开始。如果你的应用使用了基础设施资源务必参照上文第 5 节编写完整的 Infra Config 并通过--config传入完整的 基础设施配置指南 覆盖了 SQL 数据库、Redis、Pub/Sub、对象存储、指标导出等全部资源类型。若你正考虑彻底脱离 Encore可参考 迁移指南——其中再次确认了encore build docker与 Encore Cloud CI 使用完全相同的构建代码路径这是镜像可移植性与一致性的最有力保障。构建镜像不是终点合理的配置才是自托管应用正确运行的关键元数据驱动 Encore 的 metadata APIservice discovery 打通服务间调用graceful shutdown 保障滚动发布与缩容时的请求不中断而 secrets、TLS 与认证配置则守护着生产环境的安全边界。将这些配置与 CI/CD 自动化结合你就能在任意基础设施上稳定运行 Encore 应用。【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表