Use Cases

Claude Code × GCP Cloud Run Panduan Lengkap | Deploy Kontainer Serverless Otomatis

Percepat deployment GCP Cloud Run dengan Claude Code. Panduan lengkap dengan contoh kode nyata: pembuatan Dockerfile, auto-scaling, pipeline CI/CD, dan integrasi Secret Manager.

“Saya ingin menjalankan kontainer di GCP, tapi ada terlalu banyak konfigurasi — tidak tahu harus mulai dari mana” — itulah yang saya rasakan dulu. Tapi ketika saya benar-benar mencoba Cloud Run, saya benar-benar terkejut betapa lebih sederhananya konfigurasi dibandingkan dengan ECS. Tidak perlu setup VPC, tidak perlu desain task role, tidak perlu manajemen cluster. Cukup siapkan image kontainer dan hampir langsung mendapat endpoint HTTPS.

Kombinasikan dengan Claude Code, dan segalanya — mulai dari pembuatan Dockerfile hingga setup pipeline CI/CD Cloud Build — bisa diselesaikan dalam waktu yang mengejutkan singkatnya. Artikel ini menjelaskan langkah-langkah yang benar-benar saya coba, dalam 6 tahap yang jelas.


Mengapa Cloud Run Lebih Sederhana dari ECS

Cloud Run adalah layanan eksekusi kontainer yang sepenuhnya dikelola oleh GCP. Menggunakan model “serverless berbasis permintaan” di mana kontainer hanya dimulai ketika permintaan HTTP tiba.

Cloud Run:
- Manajemen cluster: Tidak diperlukan
- Setup jaringan:    HTTPS eksternal dipublikasikan secara default
- Penskalaan:        Otomatis penuh dari 0 hingga N
- Penagihan:         Berdasarkan waktu pemrosesan permintaan (hampir gratis saat idle)

AWS ECS/Fargate:
- Manajemen cluster: Diperlukan (3 lapisan: Cluster / Service / TaskDef)
- Setup jaringan:    Desain VPC dan security group diperlukan
- Penskalaan:        Ditagih untuk jumlah instans minimum
- Penagihan:         Berdasarkan waktu task yang berjalan

Langkah 1: Buat Dockerfile Secara Otomatis

claude -p "
Buat Dockerfile yang siap produksi dengan persyaratan berikut:

- App: TypeScript + Express API (port 8080)
- Versi Node.js: 22 LTS
- Multi-stage build (builder → runner)
- Jalankan sebagai user non-root (user node)
- Buat juga .dockerignore
- Dukung variabel lingkungan PORT seperti yang direkomendasikan Cloud Run
- Health check: endpoint /health
"

Dockerfile yang dihasilkan:

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

# Salin dependensi terlebih dahulu untuk memanfaatkan cache build
COPY package*.json ./
RUN npm ci --only=production=false

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

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

# Keamanan: jalankan sebagai user non-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Instal hanya dependensi produksi
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Salin artefak build
COPY --from=builder /app/dist ./dist

# Cloud Run meneruskan port via variabel lingkungan PORT
ENV PORT=8080
ENV NODE_ENV=production

# Beralih ke user non-root
USER appuser

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

Langkah 2: Deployment Pertama ke 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

Langkah 3: Konfigurasi 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 - Konfigurasi layanan Cloud Run
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: myapp-api
spec:
  template:
    metadata:
      annotations:
        # Jumlah instans minimum (mitigasi cold start)
        autoscaling.knative.dev/minScale: "1"
        # Jumlah instans maksimum (batas biaya)
        autoscaling.knative.dev/maxScale: "20"
        # Scale out pada penggunaan 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"

Langkah 4: Integrasi Secret Manager

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

# Berikan izin baca ke service account
gcloud projects add-iam-policy-binding my-project-123 \
  --member="serviceAccount:[email protected]" \
  --role="roles/secretmanager.secretAccessor"

# Mount secret di 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",
};

// Validasi secret yang diperlukan saat startup
const requiredEnvVars = ["DATABASE_URL", "SENDGRID_API_KEY", "JWT_SECRET"];
for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    console.error(`Missing required environment variable: ${envVar}`);
    process.exit(1);
  }
}

Langkah 5: Pipeline CI/CD dengan Cloud Build

# cloudbuild.yaml
steps:
  # Langkah 1: Instal dependensi dan jalankan tes
  - name: "node:22-alpine"
    id: "test"
    entrypoint: "sh"
    args:
      - "-c"
      - |
        npm ci
        npm run test
        npm run lint

  # Langkah 2: Build 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"
      - "."

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

  # Langkah 4: Deploy ke 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"

  # Langkah 5: Notifikasi Slack (berhasil)
  - name: "curlimages/curl"
    id: "notify-success"
    entrypoint: "curl"
    args:
      - "-X"
      - "POST"
      - "-H"
      - "Content-type: application/json"
      - "--data"
      - '{"text":"✅ Deployment Cloud Run selesai: $COMMIT_SHA"}'
      - "$_SLACK_WEBHOOK_URL"

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

Langkah 6: Domain Kustom dan 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 = "Perlindungan SQL injection"
  }
  rule {
    action   = "allow"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config { src_ip_ranges = ["*"] }
    }
    description = "Izinkan default"
  }
}

5 Jebakan Paling Umum

1. Timeout akibat cold start

Atur min-instances ke setidaknya 1 di produksi.

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

2. Tidak menangani SIGTERM

process.on("SIGTERM", () => {
  server.close(() => process.exit(0));
  setTimeout(() => process.exit(1), 30000);
});

3. Data sensitif dalam variabel lingkungan

# ❌ Jangan pernah: secret dalam teks biasa
gcloud run services update myapp-api --set-env-vars DATABASE_PASSWORD=mypassword123

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

4. Konfigurasi memori tidak mencukupi

CMD ["node", "--max-old-space-size=384", "dist/index.js"]

5. Pemrosesan latar belakang di luar permintaan

gcloud run services update myapp-api --no-cpu-throttling --region asia-northeast1

Ringkasan

TugasKontribusi Claude Code
Pembuatan DockerfileMulti-stage build dan setup non-root diotomatisasi
Deployment pertamaPerintah gcloud lengkap dihasilkan dari persyaratan
Konfigurasi scalingInstans min/max dan ambang CPU dioptimalkan
Integrasi Secret ManagerPembuatan secret, izin, dan konfigurasi mount dihasilkan
Pipeline CI/CDcloudbuild.yaml dengan tes dihasilkan
Domain kustomKonfigurasi Terraform load balancer digenerate otomatis

Artikel Terkait

Referensi

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

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Cukup masukkan emailmu dan kami akan langsung mengirim cheatsheet PDF A4 satu halaman.

Kami menjaga data pribadimu dengan aman dan tidak pernah mengirim spam.

Tingkatkan alur kerja Claude Code kamu

50 template prompt yang sudah teruji, siap copy-paste ke Claude Code sekarang juga.

Masa

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.