Use Cases (更新: 2026/6/2)

用 Claude Code 部署到 GCP Cloud Run:实战指南

用 Docker、IAM、Secret Manager、日志和回滚,把 Node.js API 安全部署到 Cloud Run。

用 Claude Code 部署到 GCP Cloud Run:实战指南

Cloud Run 适合这样的场景:你想发布一个容器化的 HTTP 服务,但不想维护 Kubernetes、ECS 或一组虚拟机。和 Cloud Functions、Lambda 相比,它不要求你把应用拆成很多小函数。一个普通的 Express API、BFF 或 webhook 接收服务,只要能打成 Docker 镜像,就可以交给 Cloud Run 处理 HTTPS、版本、扩缩容和日志。

本文用 Claude Code 辅助完成一条完整链路:本地 Node.js/Express 服务、Dockerfile、本地测试、Artifact Registry、gcloud run deploy、服务账号、IAM、Secret Manager、并发数、最小实例、Cloud Logging、revision 回滚、成本陷阱和安全审查。

先把术语说清楚:Cloud Run 是“按 HTTP 请求运行容器的无服务器平台”;Artifact Registry 是“Docker 镜像仓库”;Secret Manager 是“保存密码和 API key 的保险箱”;IAM 是“决定哪个身份能访问哪个资源的权限系统”。

什么时候 Cloud Run 比 Functions 或 Lambda 更合适

Cloud Run 不是所有场景都优于 Cloud Functions 或 Lambda。非常小的事件处理函数,直接用函数平台可能更轻。但下面这些场景,Cloud Run 的开发体验通常更好。

用例Cloud Run 的优势
Webhook 接收 APIStripe、GitHub、LINE 等 HTTP POST 可以自然映射到 Express 路由
小型 BFF/API 服务鉴权、中间件、路由和校验可以保留在一个 Node.js 应用里
定时批处理入口Cloud Scheduler 通过 HTTP 调用,不必额外搭一套任务框架
轻量 AI 或数据 API原生依赖、系统包、自定义二进制都可以放进容器

如果是长时间常驻 worker,要特别检查 CPU 分配和成本。Cloud Run 很适合请求驱动的服务,但不是所有后台循环任务的默认答案。

可运行的 Express 服务

Cloud Run 会通过 PORT 环境变量告诉容器监听哪个端口,所以代码不要写死端口。还要准备 /health,方便部署后检查。

{
  "name": "cloud-run-claude-code-api",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "tsx src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "test": "node --test"
  },
  "dependencies": {
    "express": "^4.19.2"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^22.10.0",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2"
  }
}
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts"]
}
import express from "express";

const app = express();
app.use(express.json());

const requiredEnv = ["DATABASE_URL", "JWT_SECRET"];
for (const key of requiredEnv) {
  if (!process.env[key]) {
    console.error(`Missing required environment variable: ${key}`);
    process.exit(1);
  }
}

app.get("/health", (_req, res) => {
  res.status(200).json({ ok: true, service: "myapp-api" });
});

app.post("/webhooks/example", (req, res) => {
  console.log("webhook_received", {
    eventType: req.body?.type ?? "unknown",
    receivedAt: new Date().toISOString()
  });
  res.status(202).json({ accepted: true });
});

app.get("/config-check", (_req, res) => {
  res.json({
    nodeEnv: process.env.NODE_ENV ?? "development",
    hasDatabaseUrl: Boolean(process.env.DATABASE_URL),
    hasJwtSecret: Boolean(process.env.JWT_SECRET)
  });
});

const port = Number(process.env.PORT ?? 8080);
const server = app.listen(port, () => {
  console.log(`listening on ${port}`);
});

process.on("SIGTERM", () => {
  console.log("SIGTERM received, closing HTTP server");
  server.close(() => process.exit(0));
  setTimeout(() => process.exit(1), 30000).unref();
});

本地先验证:

npm install
DATABASE_URL="postgresql://local" JWT_SECRET="local-secret" npm run dev
curl http://localhost:8080/health
curl -X POST http://localhost:8080/webhooks/example \
  -H "Content-Type: application/json" \
  -d '{"type":"demo.created"}'

Dockerfile 和 Claude Code 审查

不要只让 Claude Code“生成 Dockerfile”。更好的要求是“按 Cloud Run 生产环境审查”。重点包括运行镜像体积、只安装生产依赖、非 root 用户、.dockerignorePORT 支持,以及安全和成本风险。

claude -p "
Review and improve this Cloud Run Docker setup.
Requirements:
- Node.js 22 LTS, TypeScript, Express
- production dependencies only in runtime image
- run as a non-root user
- listen on the PORT environment variable
- include .dockerignore
- explain any Cloud Run security or cost risks
Return the final Dockerfile and a short review checklist.
"
FROM node:22-alpine AS builder
WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY tsconfig.json ./
COPY src ./src
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=8080

RUN addgroup -S appgroup && adduser -S appuser -G appgroup

COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=builder /app/dist ./dist

USER appuser
EXPOSE 8080
CMD ["node", "--max-old-space-size=384", "dist/index.js"]
node_modules
dist
.env
.env.*
*.log
.git
.gitignore
Dockerfile
README.md
docker build -t myapp-api:local .
docker run --rm -p 8080:8080 \
  -e PORT=8080 \
  -e DATABASE_URL="postgresql://local" \
  -e JWT_SECRET="local-secret" \
  myapp-api:local
curl http://localhost:8080/health

Artifact Registry 和首次部署

Artifact Registry 是镜像仓库。先为目标区域配置 Docker 认证,再创建仓库、构建和推送镜像。

PROJECT_ID="my-project-123"
REGION="asia-northeast1"
REPOSITORY="myapp"
SERVICE="myapp-api"
IMAGE="$REGION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/api:v1.0.0"

gcloud config set project "$PROJECT_ID"
gcloud services enable run.googleapis.com artifactregistry.googleapis.com secretmanager.googleapis.com logging.googleapis.com

gcloud artifacts repositories create "$REPOSITORY" \
  --repository-format=docker \
  --location="$REGION" \
  --description="Docker images for myapp"

gcloud auth configure-docker "$REGION-docker.pkg.dev"
docker build -t "$IMAGE" .
docker push "$IMAGE"

部署前创建专用运行服务账号,避免默认账号权限过大。

gcloud iam service-accounts create myapp-run \
  --display-name="Cloud Run runtime for myapp"

SERVICE_ACCOUNT="myapp-run@$PROJECT_ID.iam.gserviceaccount.com"

gcloud run deploy "$SERVICE" \
  --image "$IMAGE" \
  --region "$REGION" \
  --platform managed \
  --service-account "$SERVICE_ACCOUNT" \
  --memory 512Mi \
  --cpu 1 \
  --concurrency 80 \
  --min-instances 0 \
  --max-instances 20 \
  --allow-unauthenticated \
  --set-env-vars NODE_ENV=production \
  --port 8080

内部 API 不应公开访问,去掉 --allow-unauthenticated,只给调用方 Cloud Run Invoker 权限。

Secret Manager、IAM 和安全

不要把密码写进 --set-env-vars。用 Secret Manager 保存,再让 Cloud Run 注入环境变量。

echo -n "postgresql://user:password@host:5432/app" | \
  gcloud secrets create DATABASE_URL --data-file=-

echo -n "replace-with-long-random-value" | \
  gcloud secrets create JWT_SECRET --data-file=-

gcloud secrets add-iam-policy-binding DATABASE_URL \
  --member="serviceAccount:$SERVICE_ACCOUNT" \
  --role="roles/secretmanager.secretAccessor"

gcloud secrets add-iam-policy-binding JWT_SECRET \
  --member="serviceAccount:$SERVICE_ACCOUNT" \
  --role="roles/secretmanager.secretAccessor"

gcloud run services update "$SERVICE" \
  --region "$REGION" \
  --set-secrets "DATABASE_URL=DATABASE_URL:latest,JWT_SECRET=JWT_SECRET:latest"

权限尽量加在单个 secret 上,而不是给整个项目 roles/editor。这能显著缩小事故影响范围。

并发、最小实例和成本陷阱

Concurrency 表示一个容器实例最多同时处理多少请求。值越高,实例数可能越少,但数据库连接池、外部 API 限流和 CPU 都可能先成为瓶颈。

gcloud run services update "$SERVICE" \
  --region "$REGION" \
  --concurrency 40 \
  --min-instances 1 \
  --max-instances 20 \
  --cpu-throttling

开发环境和低流量个人项目可以用 min-instances 0。Webhook 或生产 API 如果不能接受冷启动延迟,可以设为 1。Webhook 常从 20-40 开始,BFF/API 从 40-80 开始,再根据 p95 延迟、DB 连接数和错误率调整。

Cloud Logging 和回滚

Cloud Run 的请求日志、容器日志和系统日志会进入 Cloud Logging。Node.js 服务通常把日志写到 stdout/stderr 就足够。

gcloud run services logs read "$SERVICE" \
  --region "$REGION" \
  --limit 20

gcloud logging read \
  "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE" \
  --limit 20 \
  --format=json

每次部署或配置变更都会创建不可变 revision。出现问题时,把流量切回上一版。

gcloud run revisions list \
  --service "$SERVICE" \
  --region "$REGION"

gcloud run services update-traffic "$SERVICE" \
  --region "$REGION" \
  --to-revisions myapp-api-00012-abc=100

上线前让 Claude Code 做部署审查:

claude -p "
Act as a Cloud Run deployment reviewer.
Review package.json, Dockerfile, src/index.ts, and the gcloud commands below.
Find blockers before production:
- Cloud Run PORT handling
- SIGTERM graceful shutdown
- non-root container
- Secret Manager usage
- service account and IAM least privilege
- concurrency, min instances, max instances, and cost risks
- Cloud Logging observability
- rollback command for the previous revision
Return: critical issues, recommended fixes, and commands to verify after deploy.
"

常见失败点

镜像太大会拖慢构建、推送和冷启动。把 secret 写进普通环境变量,会留下命令历史或 CI 日志。min-instances 1 可以降延迟,但空闲也会计费。Concurrency 过高会把下游数据库或外部 SaaS 打满。回滚命令必须在平时演练,而不是事故发生后再搜索。

参考和下一步

Cloud Run 是一个实用的中间选择:比函数平台更灵活,比 ECS 或 Kubernetes 更轻。需要把 Claude Code 提示、审查清单和部署护栏落到团队流程中,可以查看 Claude Code 培训与咨询

实测记录

本文示例已按本地 npm run dev、Docker /healthPORT 处理和必填环境变量校验进行验证。上线前还应在真实项目里检查 Artifact Registry 权限、Secret Manager 单 secret IAM、Cloud Logging 查询,以及 update-traffic 回滚演练。

#claude-code #gcp #cloud-run #docker #typescript #serverless
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。