mcpField
C
cloudrun-development

cloudrun-development

github.com/tencentcloudbase云与 DevOps1.2k49 次安装今天更新
代码仓库

关于 cloudrun-development

面向需要部署后端服务的团队,提供 CloudBase Run 开发与运维指导。内容涵盖服务模式选择、部署前提、凭证、网络和故障排查。

主要功能

  1. 01Function 与容器模式选择
  2. 02CloudRun 初始化与部署
  3. 03入口和 VPC 规划
  4. 04CloudBase SDK 凭证指导
  5. 05部署失败排查

适用场景

  1. 01部署 Agent 服务
  2. 02迁移需通过 TCP 访问数据库的现有后端
  3. 03排查容器就绪或重启故障
  4. 04选择 CloudRun 或 HTTP 云函数

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tencentcloudbase/cloudbase-ai-toolkit --skill cloudrun-development

安装后在 Claude Code 中输入/cloudrun-development确认已加载。

附带文件references/image-deploy-troubleshooting.mdreferences/vpc-and-database.md

详细介绍

同级技能(仅限本地)

同级 CloudBase 技能与此技能一同提供。请使用 ../auth-tool-cloudbase/SKILL.md 等本地相对路径。

如果此环境中缺少引用的同级技能文件,请让用户安装完整的 CloudBase 插件(或缺少的技能)。不要通过 HTTP 获取远程技能或协议 Markdown 并放入 Agent 上下文。

跨领域协议(编写 HTTP 处理程序或部署镜像前必须阅读):

  • 敏感运行时数据保护:../cloudbase-platform/references/protocols/sensitive-runtime-data-protection.md
  • 部署门禁:../cloudbase-platform/references/protocols/deployment-gate.md

CloudBase Run 开发

激活约定

在以下情况下首先使用
  • 任务是初始化、运行、部署、检查或调试 CloudBase Run 服务。
  • 请求需要长期运行的 HTTP 服务、SSE、WebSocket、自定义系统依赖项或容器式部署。
  • 任务是在 CloudBase Run 上创建或运行 Agent 服务。
  • 任务是迁移使用传统 DATABASE_URL / TCP 数据库客户端的现有 / GitHub / 第三方后端。
  • 服务需要稳定的独立进程(长连接、自定义运行时、VPC 数据库访问)——参见下文「云托管 vs HTTP 云函数」决策部分。仅有 Dockerfile 不是充分的触发条件。
编写代码前阅读(如果)
  • 仍需在 Function 模式和 Container 模式之间做出选择。
  • 提示中提到 queryCloudRun、manageCloudRun、Dockerfile、服务域名或公有/私有访问。
  • 应用通过 TCP 依赖 MySQL、PostgreSQL、Redis 或其他 VPC 私有资源 → 先做数据库访问方式决策(SDK/网关优先,见下方「数据库访问方式决策门」);确认必须通过 TCP 直连后 → 另请阅读 references/vpc-and-database.md。
  • 正在为无状态 HTTP 服务在 CloudRun 和 HTTP 云函数之间做选择。
  • 服务通过 SDK 调用 CloudBase 资源(PG app.rdb()、NoSQL、存储、函数)→ 先通过「计算资源访问 CloudBase 的凭证决策门」:必须在编写代码之前确定凭证由谁签发、如何注入以及如何吊销。
  • 容器部署失败(deploy_failed、Pod 未就绪、就绪检查/探针失败、第三方 imageUrl 无法持续运行)→ 另请阅读 references/image-deploy-troubleshooting.md,并遵循下文的容器部署失败 SOP。不要一开始就提高 InitialDelaySeconds。
还需阅读
  • 使用云函数而非 CloudRun -> ../cloud-functions/SKILL.md
  • Agent SDK 和 AG-UI 相关内容 -> ../cloudbase-agent/SKILL.md
  • 浏览器调用方的 Web 身份验证 -> ../auth-web-cloudbase/SKILL.md
  • 现有应用 + TCP 数据库网络 -> references/vpc-and-database.md
  • 容器镜像部署失败 / 探针 / deploy_failed -> references/image-deploy-troubleshooting.md
  • 服务通过 SDK 调用 CloudBase 资源(凭证来源 / 注入 / 吊销)-> ../cloud-functions/references/http-function-credentials.md
不适用于
  • 更适合函数模型的简单 Event Function 或 HTTP Function 工作流。
  • 没有后端服务的纯前端项目。
  • 数据库架构设计任务。
常见错误/注意事项
  • 请求只需普通云函数时,却选择 CloudRun。
  • 容器模式下忘记监听平台提供的 PORT——而函数模式下则恰恰相反:在函数模式中调用 app.listen(),此时端口已由框架接管,第二次绑定会因 EADDRINUSE 失败。
  • 猜测凭证环境变量名称。@cloudbase/node-sdk 读取的是 CLOUDBASE_APIKEY;臆造的名称(例如 TCB_API_KEY)会被静默忽略,直到运行时才显示为“没有凭证”。
  • 从本地客户端登录状态(auth.json、.cloudbase/)中复制服务端凭证,并将其注入已部署的服务。应改用 manageAppAuth(action="createApiKey", keyType="api_key") 签发密钥,这样密钥才有关联所有者、有轮换途径,并且可以通过 keyId 撤销。参见 ../cloud-functions/references/http-function-credentials.md。
  • 将 CloudRun 当作有状态应用托管服务,并把重要状态存储在本地磁盘上。
  • 误以为容器模式支持本地运行。
  • 默认开放公网访问,而场景实际只需要私有访问或小程序内部访问。
  • 部署使用了 DATABASE_URL/MySQL/PostgreSQL/Redis 的现有应用,却遗漏 serverConfig.VpcConf——部署看似成功,随后运行时数据库连接失败。
  • 新应用部署默认选 TCP 直连数据库——可通过 SDK/网关访问的数据(PG app.rdb()、NoSQL、存储)不需要 VpcConf,也不需要数据库账号密码;只有无法替换经典驱动/ORM 的迁移类应用才使用 TCP 直连 + VpcConf。参见“数据库访问方式决策门”。
  • 混淆 OpenAccessTypes(用户如何访问服务)和 VpcConf(服务如何访问 VPC 数据库)。
  • 部署到尚未初始化 CloudRun 的环境——在没有大租户记录的环境中调用 CreateCloudRunServer,会静默进入旧版小租户路径,创建错误的小租户服务/版本。首次部署前务必确保环境已初始化(manageCloudRun(action="initEnv"),tcbr)。现在,manageCloudRun(action="deploy") 会阻止在未初始化的环境中创建新服务,并提供指引。
  • 使用旧版 tcb CloudRun API(CreateCloudBaseRunResource/DescribeCloudBaseRunResource/DeleteCloudBaseRunResource)——这些是已弃用的小租户开放 API,已在 callCloudApi 中禁用。CloudRun 始终通过 tcbr(CreateCloudRunEnv/CreateCloudRunServer)操作。使用 DescribeEnvBaseInfo(必需 EnvId)查询单个环境的基础信息/CloudRun 是否已启用——使用 manageCloudRun(action="initEnv") 开启,并使用 queryCloudRun(action="envStatus") 轮询状态;使用 DescribeCloudRunEnvs(EnvId 可选过滤条件)查询环境列表/资源信息。
  • 部署 httpbin/请求回显镜像,或返回 req.headers/process.env——CloudBase 可能会注入 x-cloudbase-context(base64 临时凭证)。回显该值会泄露账号的云访问权限。请遵循 ../cloudbase-platform/references/protocols/sensitive-runtime-data-protection.md。
  • 看到就绪探针失败/deploy_failed 后立即调高 InitialDelaySeconds——探针窗口已有约 N+150 秒;崩溃循环和回环地址绑定并非启动缓慢。请遵循容器部署失败 SOP。
  • 部署第三方镜像前未阅读其运行文档——缺少 Cmd、绑定地址环境变量或 VolumesConf,看起来都与探针失败相同。
  • 对 imageUrl 部署调用 getDeployLog——该日志是 CODING 构建日志;请使用 getProcessLog。
  • 将启动横幅当作服务健康的证明——拉取两次 getProcessLog 并进行比较;重复的启动序列表示服务处于重启循环。
Minimal checklist
  • Choose Function mode or Container mode explicitly.
  • Confirm the environment has CloudRun initialized before the first deploy — a brand-new environment must call CreateCloudRunEnv (tcbr) first; never CreateCloudRunServer on an uninitialized environment (it falls back to the legacy 小租户 path). manageCloudRun(action="deploy") validates this automatically and blocks new services on uninitialized environments. When blocked, first call manageCloudRun(action="initEnv", envId=...) (异步开通) and poll queryCloudRun(action="envStatus") until Status=normal, or reconsider an HTTP cloud function to bypass CloudRun entirely.
  • Confirm whether the service should be public, VPC-only, or mini-program internal (ingress).
  • If the app uses TCP databases/caches, resolve and set VpcConf (egress / private network) before deploy — see references/vpc-and-database.md.
  • Keep the service stateless and externalize durable data.
  • Settle the credential path for every CloudBase SDK call before writing code — a server API Key issued through manageAppAuth(action="createApiKey") and injected via EnvParams, never a key copied out of the local client login state.
  • Use absolute paths for every local project path.
  • Confirm handlers never echo x-cloudbase-context, full headers, or credential env vars; do not deploy httpbin-style reflectors.
  • For third-party images, complete the five-item docs checklist (Cmd / port / bind env / volume / health) before deploy.

Overview

Use CloudBase Run when the task needs a deployed backend service rather than a short-lived serverless function.

云托管 vs HTTP 云函数(按需求选,不按文件选)

核心原则:HTTP 云函数优先。只有需求真正需要云托管时才用云托管;有 Dockerfile 不等于必须上云托管。

HTTP 云函数更合适(优先):

  • 无状态 HTTP 服务,监听 PORT/9000,只做「请求进来 → 处理 → 响应」的响应式逻辑
  • 短生命周期请求,无长连接需求(SSE/WebSocket 之外的普通 API、CRUD、转发)
  • 不需要自定义系统依赖 / 多语言运行时,标准 runtime 足够
  • 部署更快、费用更低(按请求计费,可缩容到 0)、无需初始化云托管环境
  • 有 Dockerfile 但服务本质是无状态 HTTP → 优先 HTTP 云函数(HTTP Function / Custom Image HTTP Function),不必上云托管

云托管才需要(只有以下之一才选云托管):

  • 长连接:WebSocket、SSE 长连接、服务端推送
  • 自定义系统依赖 / 任意语言运行时 / 需要稳定独立进程
  • VPC 内数据库 / Redis 访问(VpcConf 私有网络连通)
  • Agent 服务(Function mode CloudRun)
  • 迁移已有 / GitHub / 第三方应用,或需要常驻进程

决策示例: 一个带 Dockerfile 的 Go/Python HTTP API,无长连接、无自定义运行时、不碰 VPC 数据库 → 选 HTTP 云函数而不是云托管;同一份代码若有 WebSocket 长连接 → 才选云托管。

数据库访问方式决策门(部署前必答:SDK 优先,TCP 直连兜底)

核心原则:能用 CloudBase SDK/网关访问的数据,一律优先 SDK 路径。 TCP 直连会引入 VPC、安全组、数据库账号密码三件套,全是部署后才暴露的问题(ETIMEDOUT、安全组拦截、密码注入),能不碰就不碰。

优先:SDK / 网关路径(无需 VpcConf、无需数据库账号密码)

  • CloudBase PG → app.rdb()(js-sdk v3 / node-sdk,走 PG HTTP 网关;详见 ../postgresql-development-cloudbase/SKILL.md)
  • NoSQL → app.database();对象存储 → app.storage
  • 新应用 / CloudBase 原生数据 → 数据层直接按 SDK 路径设计,部署时完全不需要 VPC 配置;若只用到这些数据面,还可结合上一节的「HTTP 云函数优先」进一步免掉云托管

仅当以下情况才走 TCP 直连(须完成 references/vpc-and-database.md 全流程):

  • 迁移已有 / GitHub / 第三方应用,数据层是经典驱动或 ORM(mysql2、pg、Prisma、SQLAlchemy、WordPress / Ghost 等),改造成 SDK 的成本高或用户明确要求保留
  • 需要 SDK 不覆盖的能力(特定 SQL 方言、存储过程、Redis 原生协议等)

决策动作: 扫描到 DATABASE_URL / DB 依赖信号时,先停下来回答「这个数据访问能不能换成 SDK/网关」,再决定是否进入 VPC checklist——不要默认按 TCP 直连方案往下走。

计算资源访问 CloudBase 的凭证决策门(部署前必答)

核心原则:SDK 路径免掉的是数据库账号密码,不是 CloudBase 资源访问凭证。 服务代码要调 CloudBase 资源(PG app.rdb() / NoSQL / storage / functions)时,先把凭证来源定下来,再写代码、再部署。

三件事必须先答:

  1. 谁签发 — CloudBase 服务端 API Key:manageAppAuth(action="createApiKey", keyType="api_key", keyName="<service>-<env>"),或 CLI tcb env apikey create my-key -e env-xxx。不要从本地客户端登录态(auth.json / .cloudbase/)里取一把来用。
  2. 怎么注入 — 经 serverConfig.EnvParams 注入 CLOUDBASE_APIKEY(@cloudbase/node-sdk 自动读取该变量;显式字段是 accessKey)。变量名以官方为准,不要自造。改环境变量时保留已有键值,不要整份覆盖。
  3. 怎么吊销 — 每个服务一把专用 key,记录 keyName 与轮换负责人;下线或轮换时 manageAppAuth(action="deleteApiKey", keyId=...) 并重新部署。轮换后旧实例里残留的副本不会报错,只会静默失效。

不要假设云托管容器已自动带上可用的 CloudBase 凭证 —— 部署后用一次真实的 SDK 读取验证(验证两次以上,不要只看进程起没起来)。完整步骤、Manager SDK 的腾讯云密钥对路径、环境变量合并的安全写法见 ../cloud-functions/references/http-function-credentials.md。

api_key 是环境级凭证:可绕过 RLS,单环境签发数量有限。不要给每个服务灌同一把 —— 任一实例失陷即整环境失陷。

When CloudRun is a better fit
  • Long connections: WebSocket, SSE, server push
  • Long-running request handling or persistent service processes
  • Custom runtime environments or system libraries
  • Arbitrary languages or frameworks
  • Stable external service endpoints with elastic scaling
  • AI Agent deployment on Function mode CloudRun
  • Migrating existing containerized or multi-language apps that need VPC access to databases

Mode selection

DimensionFunction modeContainer mode
Best forFast start, Node.js service patterns, built-in framework, Agent flowsExisting containers, arbitrary runtimes, custom system dependencies
Port modelThe function framework binds the platform port itself — your code must not call app.listen()App must listen on the injected PORT
DockerfileNot requiredRequired — but a Dockerfile alone does not mean CloudRun; first check whether the service needs long connections / custom runtime. Stateless HTTP services with a Dockerfile may fit HTTP cloud functions better.
Local run through toolsSupportedNot supported
Typical useStreaming APIs, low-latency backend, Agent serviceCustom language stack, migrated container app

如何使用此技能(面向编码 Agent)

  1. 先选择模式

    • 函数模式 -> HTTP/SSE/WebSocket 或 Agent 场景的最快路径
    • 容器模式 -> 确实需要 Docker/自定义运行时的场景
  2. 遵循强制运行时规则

    • 容器模式:监听注入的 PORT。函数模式:框架会为你绑定端口——切勿调用 app.listen()
    • 在编写任何 CloudBase SDK 调用之前,先确定凭证门禁方案(由谁签发 / 如何注入 / 如何撤销)
    • 保持服务无状态
    • 将持久化数据存入数据库/存储/缓存
    • 控制依赖项和镜像大小
    • 遵循资源比例建议:Mem = 2 × CPU
  3. 使用正确的工具

    • 读取操作 -> queryCloudRun
    • 写入操作 -> manageCloudRun
    • 删除操作需要明确确认并设置 force: true
    • 始终使用绝对 targetPath
  4. 遵循部署顺序

    • 初始化或下载代码
    • 对于全新环境,先确保 CloudRun 已初始化——首次部署前调用 manageCloudRun(action="initEnv", envId=...)(异步、幂等);在未初始化的环境中,manageCloudRun(action="deploy") 会阻止新服务部署,并提示你调用 initEnv
    • 对于容器模式,验证 Dockerfile
    • 检查数据库/缓存依赖信号(DATABASE_URL、docker-compose 数据库服务、ORM 配置)
    • 如果需要 TCP 数据库访问,在部署前完成 references/vpc-and-database.md 中的 VPC 检查清单
    • 条件允许时在本地运行
    • 配置入口访问模型,并在需要时配置出口 VpcConf
    • 对于 imageUrl / 第三方镜像,在部署前完成容器部署故障处理 SOP 中的五项文档检查清单
    • 部署并验证详情输出和数据库连通性
    • 如果部署失败,请遵循容器部署故障处理 SOP(references/image-deploy-troubleshooting.md)——文档 → getProcessLog → 配置;不要一开始就调整 InitialDelaySeconds

工具路由

读取操作
  • queryCloudRun(action="list") -> 列出服务
  • queryCloudRun(action="detail") -> 检查单个服务及其最新部署状态(如有)
  • queryCloudRun(action="templates") -> 查看可用的起始模板
  • queryCloudRun(action="getDeployLog") -> 构建日志(CODING / DescribeCloudRunBuildLog)。仅对云端源码构建有意义;已存在镜像的部署(imageUrl)没有构建过程,不要用它诊断镜像部署失败。未登录 CODING 的账号会报错(例如 User not created or may not qcloud user)
  • queryCloudRun(action="getProcessLog") -> 运行日志(tcbr/DescribeCloudRunProcessLog)。返回部署阶段步骤(如 create_version_check_vpc / create_eks_virtual_service / check_eks_virtual_service)+ 容器启动/运行日志(s6-overlay、应用进程、readiness probe 失败原因)。镜像部署和源码构建均可用,不依赖 CODING。参数:detailServerName/serverName + 可选 runId(不传则取最新部署的 RunId;也可从 detail / getDeployRecords 的 latestDeploy.RunId 获取 RunId)
  • queryCloudRun(action="getDeployRecords") -> 列出部署记录(从新到旧;包括 BuildId / RunId / FlowRatio / Status)——在执行流量操作前,用于查看发布历史和回滚上下文
  • queryCloudRun(action="envStatus") -> 检查环境的 CloudRun 是否已开通及其创建状态(Status=creating 表示正在开通 / normal 表示已开通)——在 initEnv 后用于轮询进度,或在 deploy 前确认环境已就绪
  • queryCloudRun(action="getManageTask") -> 发布任务状态(tcbr/DescribeServerManageTask)。返回 taskId / taskStatus 和最新部署记录状态 latestDeployStatus。用于两种情况:遇到「已有部署发布任务运行中」时,先确认任务是否确实在推进;以及部署长时间没有进展时,区分「任务仍在推进」和「任务已卡住」。不清楚任务状态时,不要反复重试 deploy
日志查询 SOP(构建日志 vs 运行日志)

排查部署失败时,必须区分两类日志,不要只用 getDeployLog:

  1. 云端源码构建(传入 targetPath,走 CODING 构建)
    • 先用 queryCloudRun(action="getDeployLog", detailServerName=..., buildId=...) 查询构建日志(编译/打包失败)
    • 再用 queryCloudRun(action="getProcessLog", detailServerName=..., runId=...) 查询运行日志(部署步骤 + 容器启动/健康检查)
  2. 已有镜像部署(传入 imageUrl、DeployType=image)
    • 跳过 getDeployLog(没有构建过程;且依赖 CODING,未登录会直接失败)
    • 直接用 queryCloudRun(action="detail") 或 getDeployRecords 获取 latestDeploy.RunId,再用 getProcessLog 查询运行日志
{
  "action": "getProcessLog",
  "detailServerName": "my-svc",
  "runId": "<from latestDeploy.RunId>"
}
部署任务 SOP(遇到「已有部署发布任务运行中」时)

manageCloudRun(action="deploy") 报错「已有部署发布任务运行中」/ already has a deploy task running 时,不要盲目重试,也不要反复修改 Dockerfile / serverConfig —— 先确认任务的实际状态:

  1. queryCloudRun(action="getManageTask", detailServerName=...) → 查看 taskId / taskStatus / latestDeployStatus
  2. queryCloudRun(action="getProcessLog") → 间隔 20–40 秒拉取两次并进行对比,确认部署阶段的步骤是否仍在推进
  3. 根据结果分支处理:
观察情况操作
taskStatus 仍为运行态,部署步骤有推进继续等待,不要重新发送 deploy
任务已结束(非运行态),但 deploy 仍被拒绝此时才考虑重试
任务长时间停留在非终态,版本也停在 creating 没有变化记录 taskId / latestDeployStatus / 时间范围作为证据,不要空转重试

force=true 无法解决此问题:它只会跳过本工具的确认提示,不会取消或覆盖服务端已有的发布任务 —— 把它当作「强制覆盖」只会白白失败一次。

日志排查顺序(构建日志 vs 运行日志、先查日志再查配置)见上面的 日志查询 SOP 与 容器部署失败 SOP。

写操作
  • manageCloudRun(action="initEnv") -> 为环境打开(初始化)CloudRun — 异步、幂等(Status=normal → 已打开,不会重新创建)。用于全新环境首次部署前,或 deploy 因「尚未初始化云托管」而受阻时。参数:envId(默认为已配置的环境)、packageType(默认 Trial)。轮询 queryCloudRun(action="envStatus"),直到 Status=normal。
  • manageCloudRun(action="init") -> 创建本地项目
  • manageCloudRun(action="download") -> 拉取远程代码
  • manageCloudRun(action="run") -> Function 模式下本地运行
  • manageCloudRun(action="deploy") -> 触发部署 + 等待注册完成(轻量等待)(不会一直等待完整构建;如果不需要 buildId,传入 waitRegistration=false 可跳过这段等待)。返回 buildId / runId / taskId + 根据 DeployType 提供的 next_step:source → 先调用 getDeployLog,再调用 getProcessLog;image(imageUrl,BuildId 通常为 0)→ 跳过 getDeployLog,通过 getDeployRecords/detail 获取 RunId,再调用 getProcessLog。请遵循返回的 next_step —— 不要总是轮询构建日志。对于已有服务:RMW 会保留远程 VpcConf / EnvParams 键 / OpenAccessTypes;对于新服务,会自动验证环境的 CloudRun 是否已初始化 —— 如果尚未初始化,部署会受阻,并提示先调用 initEnv
  • manageCloudRun(action="updateConfig") -> 仅更新配置(不上传代码;VPC / EnvParams / 扩缩容 / 访问类型)
  • manageCloudRun(action="traffic") -> 流量管理 / 灰度发布(与 tcb cloudrun traffic 保持一致):trafficOp="set" 调整稳定版/灰度版的流量比例(stablePercent + canaryPercent 必须等于 100,例如 90/10);trafficOp="promote" 将灰度版本提升为全量发布(100%,关闭灰度发布,不可逆);trafficOp="rollback" 回滚到上一稳定版本(停止正在发布的灰度版本)。先检查 queryCloudRun(action="getDeployRecords"),了解当前版本和流量情况
  • manageCloudRun(action="delete") -> 删除服务
  • manageCloudRun(action="createAgent") -> 创建 Agent 服务

Deploying an existing image (imageUrl)

已有一个现成镜像(本地构建好、或第三方发布)时,不需要本地源码目录,直接 manageCloudRun(action="deploy") 传入 imageUrl 即可,走 DeployType="image"(容器型)部署,targetPath 可省略。若用户明确提到使用某个镜像或无需重新构建代码,必须传 imageUrl,不要仅因本地有源码目录就回退到源码构建。

决策路径(直填 vs 本地中转):

  1. 公网匿名可拉取(如 ccr.ccs.tencentyun.com/...、公开 Docker Hub 镜像)→ 直填 imageUrl:manageCloudRun(action="deploy", serverName=..., imageUrl="ccr.ccs.tencentyun.com/ns/img:v1", serverConfig={...})。CloudBase 会直接拉取该 registry 地址构建部署。若 docker.io / Docker Hub 在节点上反复拉取失败,不要空转重试:改用 Dockerfile FROM <public-image> + targetPath 源码构建(CODING 拉公网镜像,产物进 CCR 内网拉取)。见下方 SOP 第 4 步。
  2. 私有 / 需登录的 registry(ghcr.io、私有 ECR/Harbor 等)→ 本地中转到 CCR:
    docker pull ghcr.io/example/app:latest
    docker tag ghcr.io/example/app:latest ccr.ccs.tencentyun.com/<ns>/app:latest
    docker login ccr.ccs.tencentyun.com
    docker push ccr.ccs.tencentyun.com/<ns>/app:latest
    
    然后把 ccr.ccs.tencentyun.com/<ns>/app:latest 作为 imageUrl 传入。中转只解决拉取,不能替代镜像文档里的启动命令 / 环境变量 / 数据目录。

与 initEnv 联动: 镜像部署同样要求环境已开通云托管。新环境首次部署前先 manageCloudRun(action="initEnv", envId=...),并用 queryCloudRun(action="envStatus") 轮询到 Status=normal;未开通时 deploy 会被拦截并引导先 initEnv。

示例:

{
  "action": "deploy",
  "serverName": "my-image-svc",
  "imageUrl": "ccr.ccs.tencentyun.com/ns/app:latest",
  "serverConfig": {
    "OpenAccessTypes": ["PUBLIC"],
    "Cpu": 0.5,
    "Mem": 1,
    "MinNum": 1,
    "MaxNum": 3,
    "Port": 8080,
    "Cmd": ["node", "server.js"],
    "EnvParams": "{\"PORT\":\"8080\",\"BIND_HOST\":\"0.0.0.0\"}"
  }
}

Port / Cmd / EnvParams 必须来自镜像官方文档的五要素清单,不要套用 3000 或省略启动命令。第三方镜像的完整对照见 references/image-deploy-troubleshooting.md 附录。

部署后:manageCloudRun(deploy) 对镜像返回的 next_step 默认指向 getProcessLog(或先 getDeployRecords 取 RunId),不要改去调 getDeployLog。也可用 queryCloudRun(action="detail") 查看 imageInfo(镜像地址与部署类型)。镜像部署失败排查走下方 SOP。

Container deploy failure SOP

顺序:先查镜像官方文档 → 再查运行日志 → 最后才动配置。禁止一看到 probe failed / deploy_failed 就调 InitialDelaySeconds。

详情与案例:references/image-deploy-troubleshooting.md。

1. 部署前:从镜像官方文档确认五要素

不要靠 Docker Hub tag 或「常见默认值」猜。部署前必须确认:

  1. 启动命令 EntryPoint / Cmd(进程如何前台常驻)→ serverConfig.EntryPoint / Cmd
  2. 服务端口(进程真正 bind 的端口;不要假设 80/3000,也不要假设镜像尊重 PORT)→ serverConfig.Port
  3. 对外监听环境变量(必须 0.0.0.0 而不是 127.0.0.1、功能开关默认关闭等)→ EnvParams
  4. 数据目录挂载 → serverConfig.VolumesConf
  5. 健康端点(CloudRun readiness 探的是服务端口,不是任意 HTTP path)

缺任何一项再部署,失败看起来都会像「健康检查失败」。

2. 部署失败:用 getProcessLog 定性

镜像部署(imageUrl)跳过 getDeployLog(那是云端源码构建的构建日志)。从 detail / getDeployRecords 取 RunId,再 queryCloudRun(action="getProcessLog")。

启动日志存在 ≠ 服务正常运行。 banner、s6/tini 行、sidecar "listening" 都不能证明探针目标已起来。

两次日志对比判活: 隔 20–40 秒再拉一次 getProcessLog。

观察定性
只有调度/创建步骤(create_eks_*),没有容器 stdoutPod 调度中 / 镜像拉取
同一段启动 banner / PID 1 行重复出现(时间戳在走、内容几乎一样)容器启动即退出 / 重启循环
进程还在,但 listen 在 127.0.0.1 或端口 ≠ serverConfig.Port端口 / 绑定地址问题
两次拉取是同一条启动过程在往后打日志,banner 不重复才可能是启动慢
3. Readiness probe 真实机制(严禁先调延迟)

部署步骤完成后:先等 N 秒(InitialDelaySeconds),再大约 每 5 秒 探一次服务端口,连续约 30 次全失败 才判本次部署失败。窗口 ≈ N+150s。不是「N 秒后立即失败」。

  • 禁止: 看到 probe failed 就把 N 改成 120。崩溃循环和 loopback 绑定不会因为 N 变大而好。
  • 允许调大 N 仅当: 两次日志证明同一个进程还在一次性初始化(JVM 预热、迁移)且尚未 listen。
4. 公网镜像(docker.io)反复失败 → Dockerfile 源码构建

节点直连 Docker Hub 反复失败时,不要空转 imageUrl。写:

FROM docker.io/example/app:latest

用 targetPath 走云端源码构建:CODING 构建机拉公网镜像,产物进 CCR,云托管节点内网拉取。这只解决拉取拓扑,不替代第 1 步的 Cmd / 环境变量 / 卷。

5. Supervisor 镜像(s6 / tini / supervisord)启动即退出

PID 1 往往是监督进程,不是 HTTP 应用。用两次日志找子进程重启风暴。若镜像 issue 记录了 PID 1 / pgrep -f 误匹配,按文档 workaround(绝对路径 Cmd、关闭 supervise),不要调探针延迟。示例见 reference 附录。

Access guidance

  • Web/public scenarios -> enable PUBLIC ingress intentionally and pair it with the right auth flow.
  • Mini Program -> prefer internal direct connection and avoid unnecessary public exposure.
  • Private ingress scenarios -> keep public access off unless the product requirement clearly needs it.
  • Database / Redis in a VPC -> this is not solved by OpenAccessTypes. You must set serverConfig.VpcConf and use the database private address. Read references/vpc-and-database.md.

Quick examples

Initialize
{ "action": "init", "serverName": "my-svc", "targetPath": "/abs/ws/my-svc" }
Local run (Function mode)
{ "action": "run", "serverName": "my-svc", "targetPath": "/abs/ws/my-svc", "runOptions": { "port": 3000 } }
Deploy (no VPC-private dependencies)
{
  "action": "deploy",
  "serverName": "my-svc",
  "targetPath": "/abs/ws/my-svc",
  "serverConfig": {
    "OpenAccessTypes": ["PUBLIC"],
    "Cpu": 0.5,
    "Mem": 1,
    "MinNum": 1,
    "MaxNum": 5
  }
}
部署(连接到 MySQL / PostgreSQL / Redis 的现有应用,通过 TCP 连接)
{
  "action": "deploy",
  "serverName": "my-existing-app",
  "targetPath": "/abs/ws/my-existing-app",
  "serverConfig": {
    "OpenAccessTypes": ["PUBLIC"],
    "Cpu": 0.5,
    "Mem": 1,
    "MinNum": 1,
    "MaxNum": 5,
    "EnvParams": "{\"DATABASE_URL\":\"postgres://user:[email protected]:5432/app\"}",
    "VpcConf": {
      "VpcId": "vpc-xxxxxxxx",
      "SubnetId": "subnet-xxxxxxxx"
    }
  }
}

有效的 OpenAccessTypes 值:OA(办公网访问)、PUBLIC(公网访问)、MINIAPP(小程序访问)、VPC(VPC 访问)。需要公开 HTTPS 访问的 Web 应用请使用 PUBLIC。

如果希望降低冷启动延迟,建议将 MinNum: 1 设为默认值。如果用户明确更看重低成本,并且接受更多冷启动,请说明其中的权衡,并允许他们将 MinNum 降至 0。

最佳实践

  1. 尽可能优先使用 PRIVATE/VPC 或小程序内部入口。
  2. 对于 TCP 数据库访问,始终将私有数据库 URL 与 VpcConf 配套使用,并确保二者位于数据库所在的同一 VPC/地域。
  3. 使用环境变量存放机密信息和各环境的配置——仅在服务端读取;绝不要在 HTTP 响应中返回这些信息。CloudBase API Keys 应通过 manageAppAuth(action="createApiKey") 创建,而不是从本地客户端登录文件中获取。
  4. 在部署前后使用 queryCloudRun(action="detail") 验证配置。
  5. 尽量减少启动时执行的工作,以降低冷启动的影响。
  6. 对于 Agent 场景,请使用 Agent SDK 技能了解协议和适配器详情,不要在此处重复说明。
  7. 对于冒烟测试,请返回固定的 { "ok": true } / 健康状态负载——绝不要部署 httpbin 或任何会回显请求头的服务。

故障排查提示

  • 访问失败 -> 检查入口访问类型、域名设置,以及实例是否已缩容至零。
  • 部署因“尚未初始化云托管 / not initialized”而被阻止 -> 必须先为环境启用 CloudRun:调用 manageCloudRun(action="initEnv", envId=...)(异步开通),并轮询 queryCloudRun(action="envStatus"),直至 Status=normal;或者打开控制台 环境 → 云托管 → 开通。对于无状态 HTTP 服务,可以考虑完全改用 HTTP 云函数,而不是 CloudRun。
  • 部署失败 -> 按照上文的容器部署失败 SOP(以及 references/image-deploy-troubleshooting.md)操作:镜像部署会跳过 getDeployLog,仅使用 getProcessLog;通过两次拉取日志区分调度问题、端口问题和启动即退出问题。在日志证明初始化确实缓慢之前,不要调高 InitialDelaySeconds。同时检查 Dockerfile(源码)和 CPU/内存比例。
  • 部署因“a deploy task is already running” /「已有部署发布任务运行中」而被拒绝 -> 首先使用 queryCloudRun(action="getManageTask") 读取实际任务状态。不要盲目重试,也不要设置 force=true 期待覆盖——它只会跳过此工具的确认提示。请参阅上文的部署任务 SOP。
  • 部署已被接受,但版本一直处于 creating 状态 -> 使用 queryCloudRun(action="getManageTask") 检查 latestDeployStatus 和 taskStatus,然后使用 getProcessLog 查看部署阶段的步骤。只有在日志确实指向代码或配置问题时,才修改 Dockerfile / serverConfig。
  • 本地运行失败 -> 请记住,本地运行工具仅支持 Function 模式。
  • 性能问题 -> 减少依赖、优化初始化,并调整最小实例数。
  • 部署成功后仍无法连接数据库 / Redis -> 几乎总是缺少或配置错误的 VpcConf、私有主机地址错误或安全组配置错误。重写应用代码之前,请先按照 references/vpc-and-database.md 操作。
  • 服务中的 CloudBase SDK 调用因凭据缺失 / 无效而失败 -> 跳过了上述凭据检查,或者变量名不是官方名称。使用 manageAppAuth(action="createApiKey") 创建密钥,通过 EnvParams 将其注入为 CLOUDBASE_APIKEY,重新部署,然后验证实际读取。请参阅 ../cloud-functions/references/http-function-credentials.md。

参考索引

所有打包的参考文件(技能 lint 可达性检查所必需):

评论

支持 Markdown