Claude Code × GCP Cloud Run 完全指南 | 无服务器容器自动部署
使用 Claude Code 加速 GCP Cloud Run 部署。完整指南含真实代码示例:Dockerfile 生成、自动扩缩容、CI/CD 流水线和 Secret Manager 集成。
“我想在 GCP 上运行容器,但配置项太多了——不知道从哪里开始”——我以前也有同样的感受。但当我真正动手使用 Cloud Run 时,真的被它比 ECS 简单得多的配置方式惊到了。无需 VPC 设置、无需任务角色设计、无需集群管理。只需准备好容器镜像,几乎立刻就能获得 HTTPS 端点。
结合 Claude Code,从 Dockerfile 生成到 Cloud Build CI/CD 流水线搭建,一切都能在令人惊讶的短时间内完成。本文将以 6 个清晰的步骤,讲解我实际尝试过的操作过程。
为什么 Cloud Run 比 ECS 更简单
Cloud Run 是 GCP 提供的完全托管容器执行服务。采用”请求驱动的无服务器”模型,仅在 HTTP 请求到达时才启动容器。
与 ECS 的对比:
Cloud Run:
- 集群管理:无需
- 网络配置:默认发布外部 HTTPS
- 扩缩容: 从 0 到 N 全自动
- 计费: 基于请求处理时间(空闲时几乎免费)
AWS ECS/Fargate:
- 集群管理:必需(3 层:Cluster / Service / TaskDef)
- 网络配置:需要设计 VPC 和安全组
- 扩缩容: 按最小实例数计费
- 计费: 基于运行任务时间
Step 1:自动生成 Dockerfile
claude -p "
按以下条件生成生产级 Dockerfile。
- 应用:TypeScript + Express API(端口 8080)
- Node.js 版本:22 LTS
- 多阶段构建(builder → runner)
- 以非 root 用户(node 用户)运行
- 同时生成 .dockerignore
- 支持 Cloud Run 推荐的 PORT 环境变量
- 健康检查:/health 端点
"
生成的 Dockerfile:
# ---- builder 阶段 ----
FROM node:22-alpine AS builder
WORKDIR /app
# 先复制依赖项以利用构建缓存
COPY package*.json ./
RUN npm ci --only=production=false
COPY tsconfig.json ./
COPY src ./src
RUN npm run build
# ---- runner 阶段 ----
FROM node:22-alpine AS runner
WORKDIR /app
# 安全:以非 root 用户运行
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# 仅安装生产依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 复制构建产物
COPY /app/dist ./dist
# Cloud Run 通过 PORT 环境变量传递端口
ENV PORT=8080
ENV NODE_ENV=production
# 切换到非 root 用户
USER appuser
EXPOSE 8080
CMD ["node", "dist/index.js"]
Step 2:首次部署到 Cloud Run
gcloud run deploy myapp-api \
--image asia-northeast1-docker.pkg.dev/my-project-123/myapp/api:v1.0.0 \
--region asia-northeast1 \
--platform managed \
--memory 512Mi \
--cpu 1 \
--concurrency 80 \
--allow-unauthenticated \
--set-env-vars NODE_ENV=production \
--port 8080
Step 3:配置自动扩缩容
gcloud run services update myapp-api \
--region asia-northeast1 \
--min-instances 1 \
--max-instances 20 \
--concurrency 80 \
--cpu-throttling \
--execution-environment gen2
# service.yaml - Cloud Run 服务配置文件
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: myapp-api
spec:
template:
metadata:
annotations:
# 最小实例数(防止冷启动)
autoscaling.knative.dev/minScale: "1"
# 最大实例数(成本上限)
autoscaling.knative.dev/maxScale: "20"
# CPU 使用率 70% 时扩容
autoscaling.knative.dev/target-utilization-percentage: "70"
run.googleapis.com/execution-environment: gen2
spec:
containerConcurrency: 80
containers:
- image: asia-northeast1-docker.pkg.dev/my-project-123/myapp/api:latest
resources:
limits:
memory: 512Mi
cpu: "1"
Step 4:Secret Manager 集成
# 注册密钥
echo -n "postgresql://user:password@host:5432/db" | \
gcloud secrets create DATABASE_URL --data-file=-
# 为服务账号授予读取权限
gcloud projects add-iam-policy-binding my-project-123 \
--member="serviceAccount:[email protected]" \
--role="roles/secretmanager.secretAccessor"
# 将密钥挂载到 Cloud Run
gcloud run services update myapp-api \
--region asia-northeast1 \
--set-secrets="DATABASE_URL=DATABASE_URL:latest,SENDGRID_API_KEY=SENDGRID_API_KEY:latest,JWT_SECRET=JWT_SECRET:latest"
// src/config.ts
export const config = {
databaseUrl: process.env.DATABASE_URL!,
sendgridApiKey: process.env.SENDGRID_API_KEY!,
jwtSecret: process.env.JWT_SECRET!,
port: parseInt(process.env.PORT || "8080", 10),
nodeEnv: process.env.NODE_ENV || "development",
};
// 启动时验证必需的密钥
const requiredEnvVars = ["DATABASE_URL", "SENDGRID_API_KEY", "JWT_SECRET"];
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
console.error(`缺少必需的环境变量:${envVar}`);
process.exit(1);
}
}
Step 5:使用 Cloud Build 构建 CI/CD 流水线
# cloudbuild.yaml
steps:
# Step 1:安装依赖并运行测试
- name: "node:22-alpine"
id: "test"
entrypoint: "sh"
args:
- "-c"
- |
npm ci
npm run test
npm run lint
# Step 2:构建 Docker 镜像
- name: "gcr.io/cloud-builders/docker"
id: "build"
args:
- "build"
- "-t"
- "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api:$COMMIT_SHA"
- "-t"
- "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api:latest"
- "."
# Step 3:推送到 Artifact Registry
- name: "gcr.io/cloud-builders/docker"
id: "push"
args:
- "push"
- "--all-tags"
- "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api"
# Step 4:部署到 Cloud Run
- name: "gcr.io/google.com/cloudsdktool/cloud-sdk"
id: "deploy"
entrypoint: "gcloud"
args:
- "run"
- "deploy"
- "myapp-api"
- "--image"
- "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api:$COMMIT_SHA"
- "--region"
- "asia-northeast1"
- "--platform"
- "managed"
- "--quiet"
# Step 5:Slack 通知(成功时)
- name: "curlimages/curl"
id: "notify-success"
entrypoint: "curl"
args:
- "-X"
- "POST"
- "-H"
- "Content-type: application/json"
- "--data"
- '{"text":"✅ Cloud Run 部署完成:$COMMIT_SHA"}'
- "$_SLACK_WEBHOOK_URL"
options:
logging: CLOUD_LOGGING_ONLY
machineType: E2_HIGHCPU_8
timeout: "1200s"
Step 6:自定义域名与负载均衡器
# main.tf - Cloud Run + Load Balancer + SSL
resource "google_compute_region_network_endpoint_group" "cloudrun_neg" {
name = "myapp-neg"
network_endpoint_type = "SERVERLESS"
region = "asia-northeast1"
cloud_run {
service = "myapp-api"
}
}
resource "google_compute_managed_ssl_certificate" "default" {
name = "myapp-ssl-cert"
managed {
domains = ["api.example.com"]
}
}
resource "google_compute_security_policy" "policy" {
name = "myapp-security-policy"
rule {
action = "deny(403)"
priority = "1000"
match {
expr {
expression = "evaluatePreconfiguredExpr('sqli-stable')"
}
}
description = "SQL 注入防护"
}
rule {
action = "allow"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config { src_ip_ranges = ["*"] }
}
description = "默认允许"
}
}
五大常见陷阱
1. 冷启动导致超时
生产环境中将 min-instances 设置为 1 以上。
gcloud run services update myapp-api --min-instances 1 --region asia-northeast1
2. 忘记处理 SIGTERM
// src/index.ts - 正确处理 SIGTERM
process.on("SIGTERM", () => {
server.close(() => process.exit(0));
setTimeout(() => process.exit(1), 30000);
});
3. 在环境变量中明文写入敏感信息
# ❌ 绝对禁止:明文写入密钥
gcloud run services update myapp-api --set-env-vars DATABASE_PASSWORD=mypassword123
# ✅ 正确做法:通过 Secret Manager 安全传递
gcloud run services update myapp-api --set-secrets="DATABASE_PASSWORD=DATABASE_PASSWORD:latest"
4. 内存配置不足
# 解决方案:显式设置 Node.js 堆大小
CMD ["node", "--max-old-space-size=384", "dist/index.js"]
5. 在请求之外进行后台处理
# 始终分配 CPU 模式(需要后台处理的服务)
gcloud run services update myapp-api --no-cpu-throttling --region asia-northeast1
总结
| 任务 | Claude Code 的贡献 |
|---|---|
| Dockerfile 生成 | 多阶段构建和非 root 设置自动化 |
| 首次部署 | 从需求生成完整 gcloud 命令 |
| 扩缩容配置 | 最小/最大实例和 CPU 阈值优化 |
| Secret Manager 集成 | 密钥创建、权限和挂载配置生成 |
| CI/CD 流水线 | 含测试的 cloudbuild.yaml 生成 |
| 自定义域名 | 负载均衡器 Terraform 配置自动生成 |
相关文章
参考资料
免费 PDF:5 分钟看懂 Claude Code 速查表
只需留下邮箱,我们就会立即把这份 A4 一页速查表 PDF 发送给你。
我们会严格保护你的个人信息,绝不发送垃圾邮件。
本文作者
Masa
深度使用 Claude Code 的工程师。运营 claudecode-lab.com——一个涵盖 10 种语言、超过 2,000 页内容的科技媒体。
相关文章
Codex Automations 是什么?让 AI 在你睡觉时完成内容运营
用 Codex Automations 自动查看流量、选择主题、写文章、改善转化路径并部署网站的实用指南。
Claude Code × GCP Cloud Functions 完全指南 | 极速开发无服务器函数
用 Claude Code 高效开发 GCP Cloud Functions。从 HTTP/Pub/Sub/Firestore 触发器实现到本地测试、部署自动化,基于 Masa 的实战经验,附完整可运行代码示例。
用 Claude Code 设计 Firestore:先从查询开始,而不是集合
使用 Claude Code 进行 Firestore query-first 设计:schema、索引、成本、安全规则与 TypeScript 示例。