Claude Code × GCP Cloud Run Guía Completa | Despliegue automático de contenedores serverless
Acelera los despliegues en GCP Cloud Run con Claude Code. Guía completa con ejemplos de código reales: generación de Dockerfile, auto-escalado, pipelines CI/CD e integración con Secret Manager.
“Quiero ejecutar contenedores en GCP, pero hay demasiadas configuraciones — no sé por dónde empezar” — yo mismo me sentía así antes. Pero cuando realmente puse manos a la obra con Cloud Run, me sorprendió genuinamente lo mucho más simple que era la configuración comparado con ECS. Sin configuración de VPC, sin diseño de roles de tarea, sin gestión de clústeres. Solo prepara una imagen de contenedor y casi de inmediato tienes un endpoint HTTPS.
Combínalo con Claude Code, y todo — desde la generación del Dockerfile hasta la configuración del pipeline CI/CD con Cloud Build — se puede hacer en un tiempo sorprendentemente corto. Este artículo explica los pasos que realmente probé, en 6 etapas claras.
Por qué Cloud Run es más simple que ECS
Cloud Run es el servicio de ejecución de contenedores totalmente gestionado de GCP. Usa un modelo “serverless impulsado por solicitudes” donde los contenedores solo se inician cuando llegan solicitudes HTTP.
Comparación con ECS:
Cloud Run:
- Gestión de clústeres: No requerida
- Configuración de red: HTTPS externo publicado por defecto
- Escalado: Totalmente automático de 0 a N
- Facturación: Basada en tiempo de procesamiento de solicitudes (casi gratis en reposo)
AWS ECS/Fargate:
- Gestión de clústeres: Requerida (3 capas: Cluster / Service / TaskDef)
- Configuración de red: Diseño de VPC y grupos de seguridad requerido
- Escalado: Facturación por número mínimo de instancias
- Facturación: Basada en tiempo de tarea en ejecución
Paso 1: Generar automáticamente un Dockerfile
claude -p "
Genera un Dockerfile listo para producción con los siguientes requisitos:
- App: TypeScript + Express API (puerto 8080)
- Versión de Node.js: 22 LTS
- Build multi-etapa (builder → runner)
- Ejecutar como usuario no-root (usuario node)
- También genera .dockerignore
- Soporte para la variable de entorno PORT como recomienda Cloud Run
- Health check: endpoint /health
"
Dockerfile generado:
# ---- etapa builder ----
FROM node:22-alpine AS builder
WORKDIR /app
# Copiar dependencias primero para aprovechar la caché de build
COPY package*.json ./
RUN npm ci --only=production=false
COPY tsconfig.json ./
COPY src ./src
RUN npm run build
# ---- etapa runner ----
FROM node:22-alpine AS runner
WORKDIR /app
# Seguridad: ejecutar como usuario no-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Instalar solo dependencias de producción
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# Copiar artefactos del build
COPY /app/dist ./dist
# Cloud Run pasa el puerto via la variable de entorno PORT
ENV PORT=8080
ENV NODE_ENV=production
# Cambiar a usuario no-root
USER appuser
EXPOSE 8080
CMD ["node", "dist/index.js"]
Paso 2: Primer despliegue en 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
Paso 3: Configurar auto-escalado
gcloud run services update myapp-api \
--region asia-northeast1 \
--min-instances 1 \
--max-instances 20 \
--concurrency 80 \
--cpu-throttling \
--execution-environment gen2
# service.yaml - Configuración del servicio Cloud Run
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: myapp-api
spec:
template:
metadata:
annotations:
# Número mínimo de instancias (mitigación de cold start)
autoscaling.knative.dev/minScale: "1"
# Número máximo de instancias (límite de costos)
autoscaling.knative.dev/maxScale: "20"
# Escalar al 70% de uso de CPU
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"
Paso 4: Integración con Secret Manager
# Registrar secretos
echo -n "postgresql://user:password@host:5432/db" | \
gcloud secrets create DATABASE_URL --data-file=-
# Otorgar permisos de lectura a la cuenta de servicio
gcloud projects add-iam-policy-binding my-project-123 \
--member="serviceAccount:[email protected]" \
--role="roles/secretmanager.secretAccessor"
# Montar secretos en 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",
};
// Validar secretos requeridos al inicio
const requiredEnvVars = ["DATABASE_URL", "SENDGRID_API_KEY", "JWT_SECRET"];
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
console.error(`Variable de entorno faltante: ${envVar}`);
process.exit(1);
}
}
Paso 5: Pipeline CI/CD con Cloud Build
# cloudbuild.yaml
steps:
# Paso 1: Instalar dependencias y ejecutar tests
- name: "node:22-alpine"
id: "test"
entrypoint: "sh"
args:
- "-c"
- |
npm ci
npm run test
npm run lint
# Paso 2: Construir imagen 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"
- "."
# Paso 3: Subir a Artifact Registry
- name: "gcr.io/cloud-builders/docker"
id: "push"
args:
- "push"
- "--all-tags"
- "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api"
# Paso 4: Desplegar en 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"
# Paso 5: Notificación Slack (en caso de éxito)
- name: "curlimages/curl"
id: "notify-success"
entrypoint: "curl"
args:
- "-X"
- "POST"
- "-H"
- "Content-type: application/json"
- "--data"
- '{"text":"✅ Despliegue Cloud Run completado: $COMMIT_SHA"}'
- "$_SLACK_WEBHOOK_URL"
options:
logging: CLOUD_LOGGING_ONLY
machineType: E2_HIGHCPU_8
timeout: "1200s"
Paso 6: Dominio personalizado y balanceador de carga
# 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 = "Protección contra inyección SQL"
}
rule {
action = "allow"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config { src_ip_ranges = ["*"] }
}
description = "Permitir por defecto"
}
}
Los 5 errores más comunes
1. Timeouts por cold starts
Cloud Run escala a cero instancias cuando no hay tráfico. Configura min-instances a 1 o más en producción.
gcloud run services update myapp-api --min-instances 1 --region asia-northeast1
2. No manejar SIGTERM
// src/index.ts - Manejar SIGTERM correctamente
process.on("SIGTERM", () => {
server.close(() => process.exit(0));
setTimeout(() => process.exit(1), 30000);
});
3. Datos sensibles en texto plano en variables de entorno
# ❌ Nunca: secretos en texto plano
gcloud run services update myapp-api --set-env-vars DATABASE_PASSWORD=mypassword123
# ✅ Correcto: usar Secret Manager
gcloud run services update myapp-api --set-secrets="DATABASE_PASSWORD=DATABASE_PASSWORD:latest"
4. Configuración de memoria insuficiente
# Solución: establecer explícitamente el tamaño del heap de Node.js
CMD ["node", "--max-old-space-size=384", "dist/index.js"]
5. Procesamiento en segundo plano fuera de solicitudes
# Modo CPU siempre activo (para servicios que necesitan procesamiento en segundo plano)
gcloud run services update myapp-api --no-cpu-throttling --region asia-northeast1
Resumen
| Tarea | Contribución de Claude Code |
|---|---|
| Generación de Dockerfile | Build multi-etapa y configuración no-root automatizada |
| Primer despliegue | Comandos gcloud completos generados desde requisitos |
| Configuración de escalado | Instancias mín/máx y umbrales de CPU optimizados |
| Integración Secret Manager | Creación de secretos, permisos y configuración de montaje generados |
| Pipeline CI/CD | cloudbuild.yaml con tests generado |
| Dominio personalizado | Configuración Terraform del balanceador de carga generada automáticamente |
Artículos relacionados
- Claude Code × AWS ECS/Fargate Guía Completa
- Claude Code × AWS CloudFormation/CDK Guía Completa
- Claude Code Mejores Prácticas de Seguridad
Referencias
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Lleva tu flujo con Claude Code al siguiente nivel
50 plantillas de prompts probadas en producción, listas para copiar y pegar en Claude Code.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
Que es Codex Automations y como dejar que la IA gestione contenido mientras duermes
Guia practica para usar Codex Automations en analitica, articulos, CTA, despliegue y monetizacion.
Claude Code × GCP Cloud Functions Guía Completa | Desarrollo Serverless Ultrarrápido
Optimiza GCP Cloud Functions con Claude Code. Implementa triggers HTTP/Pub/Sub/Firestore, pruebas locales y automatización de despliegues con ejemplos de código reales de la experiencia de Masa.
Diseña Firestore con Claude Code: empieza por consultas, no colecciones
Flujo práctico para diseñar Firestore con Claude Code: esquema guiado por consultas, índices, costos, reglas de seguridad y TypeScript.