Use Cases

Claude Code × GCP Cloud Run Guide Complet | Déploiement automatique de conteneurs serverless

Accélérez les déploiements GCP Cloud Run avec Claude Code. Guide complet avec exemples de code réels : génération de Dockerfile, auto-scaling, pipelines CI/CD et intégration Secret Manager.

“Je veux faire tourner des conteneurs sur GCP, mais il y a trop de configurations — je ne sais pas par où commencer” — c’est exactement ce que je ressentais avant. Mais quand j’ai vraiment utilisé Cloud Run, j’ai été sincèrement surpris de voir à quel point la configuration était plus simple qu’avec ECS. Pas de configuration VPC, pas de conception de rôles de tâche, pas de gestion de cluster. Préparez simplement une image de conteneur et vous avez presque immédiatement un endpoint HTTPS.

Combinez cela avec Claude Code, et tout — de la génération du Dockerfile à la mise en place du pipeline CI/CD Cloud Build — peut être fait en un temps étonnamment court. Cet article explique les étapes que j’ai réellement essayées, en 6 phases claires.


Pourquoi Cloud Run est plus simple qu’ECS

Cloud Run est le service d’exécution de conteneurs entièrement géré de GCP. Il utilise un modèle “serverless piloté par les requêtes” où les conteneurs ne démarrent que lorsque des requêtes HTTP arrivent.

Comparaison avec ECS :

Cloud Run :
- Gestion de cluster : Non requise
- Configuration réseau : HTTPS externe publié par défaut
- Mise à l'échelle :   Entièrement automatique de 0 à N
- Facturation :        Basée sur le temps de traitement des requêtes (presque gratuit au repos)

AWS ECS/Fargate :
- Gestion de cluster : Requise (3 couches : Cluster / Service / TaskDef)
- Configuration réseau : Conception VPC et groupes de sécurité requise
- Mise à l'échelle :   Facturation pour le nombre minimum d'instances
- Facturation :        Basée sur le temps de tâche en cours d'exécution

Étape 1 : Générer automatiquement un Dockerfile

claude -p "
Génère un Dockerfile prêt pour la production avec les exigences suivantes :

- App : TypeScript + Express API (port 8080)
- Version de Node.js : 22 LTS
- Build multi-étapes (builder → runner)
- Exécuter en tant qu'utilisateur non-root (utilisateur node)
- Générer aussi .dockerignore
- Support de la variable d'environnement PORT comme recommandé par Cloud Run
- Health check : endpoint /health
"

Dockerfile généré :

# ---- étape builder ----
FROM node:22-alpine AS builder
WORKDIR /app

# Copier les dépendances en premier pour profiter du cache de build
COPY package*.json ./
RUN npm ci --only=production=false

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

# ---- étape runner ----
FROM node:22-alpine AS runner
WORKDIR /app

# Sécurité : exécuter en tant qu'utilisateur non-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Installer uniquement les dépendances de production
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Copier les artefacts du build
COPY --from=builder /app/dist ./dist

# Cloud Run passe le port via la variable d'environnement PORT
ENV PORT=8080
ENV NODE_ENV=production

# Passer à l'utilisateur non-root
USER appuser

EXPOSE 8080
CMD ["node", "dist/index.js"]

Étape 2 : Premier déploiement sur 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

Étape 3 : Configurer l’auto-scaling

gcloud run services update myapp-api \
  --region asia-northeast1 \
  --min-instances 1 \
  --max-instances 20 \
  --concurrency 80 \
  --cpu-throttling \
  --execution-environment gen2
# service.yaml - Configuration du service Cloud Run
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: myapp-api
spec:
  template:
    metadata:
      annotations:
        # Nombre minimum d'instances (atténuation du cold start)
        autoscaling.knative.dev/minScale: "1"
        # Nombre maximum d'instances (plafond de coût)
        autoscaling.knative.dev/maxScale: "20"
        # Scale out à 70% d'utilisation 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"

Étape 4 : Intégration Secret Manager

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

# Accorder les droits de lecture au compte de service
gcloud projects add-iam-policy-binding my-project-123 \
  --member="serviceAccount:[email protected]" \
  --role="roles/secretmanager.secretAccessor"

# Monter les secrets dans 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",
};

// Valider les secrets requis au démarrage
const requiredEnvVars = ["DATABASE_URL", "SENDGRID_API_KEY", "JWT_SECRET"];
for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    console.error(`Variable d'environnement manquante : ${envVar}`);
    process.exit(1);
  }
}

Étape 5 : Pipeline CI/CD avec Cloud Build

# cloudbuild.yaml
steps:
  # Étape 1 : Installer les dépendances et lancer les tests
  - name: "node:22-alpine"
    id: "test"
    entrypoint: "sh"
    args:
      - "-c"
      - |
        npm ci
        npm run test
        npm run lint

  # Étape 2 : Construire l'image 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"
      - "."

  # Étape 3 : Pousser vers Artifact Registry
  - name: "gcr.io/cloud-builders/docker"
    id: "push"
    args:
      - "push"
      - "--all-tags"
      - "asia-northeast1-docker.pkg.dev/$PROJECT_ID/myapp/api"

  # Étape 4 : Déployer sur 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"

  # Étape 5 : Notification Slack (en cas de succès)
  - name: "curlimages/curl"
    id: "notify-success"
    entrypoint: "curl"
    args:
      - "-X"
      - "POST"
      - "-H"
      - "Content-type: application/json"
      - "--data"
      - '{"text":"✅ Déploiement Cloud Run terminé : $COMMIT_SHA"}'
      - "$_SLACK_WEBHOOK_URL"

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: E2_HIGHCPU_8
timeout: "1200s"

Étape 6 : Domaine personnalisé et load balancer

# 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 = "Protection contre l'injection SQL"
  }
  rule {
    action   = "allow"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config { src_ip_ranges = ["*"] }
    }
    description = "Autoriser par défaut"
  }
}

Les 5 pièges les plus courants

1. Timeouts causés par les cold starts

Cloud Run passe à zéro instance en l’absence de trafic. Définissez min-instances à 1 ou plus en production.

gcloud run services update myapp-api --min-instances 1 --region asia-northeast1

2. Ne pas gérer SIGTERM

// src/index.ts - Gérer SIGTERM correctement
process.on("SIGTERM", () => {
  server.close(() => process.exit(0));
  setTimeout(() => process.exit(1), 30000);
});

3. Données sensibles en clair dans les variables d’environnement

# ❌ Jamais : secrets en texte clair
gcloud run services update myapp-api --set-env-vars DATABASE_PASSWORD=mypassword123

# ✅ Correct : utiliser Secret Manager
gcloud run services update myapp-api --set-secrets="DATABASE_PASSWORD=DATABASE_PASSWORD:latest"

4. Configuration mémoire insuffisante

# Solution : définir explicitement la taille du heap Node.js
CMD ["node", "--max-old-space-size=384", "dist/index.js"]

5. Traitement en arrière-plan hors des requêtes

# Mode CPU toujours actif (pour les services nécessitant un traitement en arrière-plan)
gcloud run services update myapp-api --no-cpu-throttling --region asia-northeast1

Récapitulatif

TâcheContribution de Claude Code
Génération du DockerfileBuild multi-étapes et configuration non-root automatisés
Premier déploiementCommandes gcloud complètes générées à partir des exigences
Configuration du scalingInstances min/max et seuils CPU optimisés
Intégration Secret ManagerCréation de secrets, permissions et configuration de montage générés
Pipeline CI/CDcloudbuild.yaml avec tests généré
Domaine personnaliséConfiguration Terraform du load balancer générée automatiquement

Articles connexes

Références

#claude-code #gcp #cloud-run #docker #typescript #serverless
Gratuit

PDF gratuit : aide-mémoire Claude Code en 5 minutes

Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.

Nous traitons vos données avec soin et n'envoyons jamais de spam.

Passez votre flux Claude Code au niveau supérieur

50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.

Masa

À propos de l'auteur

Masa

Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.