DevOps & Cloud

Google Cloud Run: Serverless Containers

TOKEN

Panduan lengkap Google Cloud Run β€” deploy container tanpa manage server, auto-scaling ke nol, revisions, traffic splitting, custom domains, dan best practices

1. Pengenalan Cloud Run

Google Cloud Run adalah platform serverless fully managed yang memungkinkan Anda menjalankan container tanpa perlu mengelola server, cluster, atau infrastruktur apapun. Cloud Run otomatis menghandle scaling β€” dari 0 hingga ribuan instance β€” berdasarkan traffic yang masuk. Anda hanya perlu menyediakan container image dan Cloud Run akan mengurus sisanya.

Diperkenalkan pada Google Cloud Next 2019, Cloud Run menjadi populer karena menyederhanakan deployment aplikasi container. Berbeda dengan Kubernetes yang memerlukan manajemen cluster, atau GKE Autopilot yang lebih kompleks, Cloud Run menawarkan pengalaman yang sangat sederhana β€” satu perintah untuk deploy, dan aplikasi langsung bisa diakses.

Mengapa Cloud Run?

Keunggulan Penjelasan
Zero Server ManagementTidak perlu mengelola VM, cluster, atau node
Scale to ZeroBayar hanya saat request aktif β€” 0 request = 0 biaya
Auto-scalingOtomatis scale dari 0 hingga 1000+ instance
Any LanguageGunakan bahasa apapun β€” Node.js, Python, Go, Rust, Java, PHP
PortableBerbasis standar container β€” bisa dipindahkan ke platform lain
Fast DeploysDeploy dalam hitungan detik, bukan menit
Built-in HTTPSEndpoint HTTPS otomatis tanpa konfigurasi SSL
Pay-per-useBayar per request, per CPU time, dan memori yang digunakan
Diagram: Cloud Run Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GOOGLE CLOUD RUN                           β”‚
β”‚                                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                β”‚
β”‚  β”‚ Request  β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ (HTTPS)  │────►│  Google Frontend / Load Balancer      β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                  β”‚                            β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚                    β–Ό             β–Ό             β–Ό             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚ Instance 1  β”‚ β”‚ Instance 2  β”‚ β”‚ Instance N  β”‚            β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚            β”‚
β”‚  β”‚ β”‚Containerβ”‚ β”‚ β”‚ β”‚Containerβ”‚ β”‚ β”‚ β”‚Containerβ”‚ β”‚            β”‚
β”‚  β”‚ β”‚         β”‚ β”‚ β”‚ β”‚         β”‚ β”‚ β”‚ β”‚         β”‚ β”‚            β”‚
β”‚  β”‚ β”‚ App     β”‚ β”‚ β”‚ β”‚ App     β”‚ β”‚ β”‚ β”‚ App     β”‚ β”‚            β”‚
β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                               β”‚
β”‚  Features:                                                    β”‚
β”‚  - Auto-scaling: 0 β†’ N instances                             β”‚
β”‚  - Per-request billing                                       β”‚
β”‚  - Request timeout: max 60 menit (HTTP), 24 jam (gRPC)      β”‚
β”‚  - CPU allocated: 1-8 vCPU                                  β”‚
β”‚  - Memory: 128 MiB - 32 GiB                                 β”‚
β”‚  - Max instance: configurable                                β”‚
β”‚  - Concurrency: 1-1000 concurrent requests per instance      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Perbandingan dengan Alternatif GCP

Fitur Cloud Run Cloud Functions GKE Autopilot
Unit DeployContainer imageFunction codePod / Container
Scale to Zeroβœ… Yaβœ… Ya❌ Tidak
ConcurrencyUp to 1000/instance1 per instanceTidak dibatasi
Max Timeout60 menit9 menitTidak ada
Complexity🟒 Rendah🟒 RendahπŸ”΄ Tinggi
WebSocketβœ… Didukung❌ Tidakβœ… Didukung
Use CaseWeb app, API, microserviceEvent handler, webhookComplex workloads

2. Konsep Dasar: Container, Services, Jobs

Cloud Run Service

Service adalah unit utama di Cloud Run. Setiap service memiliki satu atau lebih revisions, dan menerima HTTP request dari internet. Service otomatis scale berdasarkan jumlah request yang masuk.

Cloud Run Job

Job adalah unit untuk tugas yang bersifat batch β€” berjalan sekali dan selesai. Berbeda dengan Service yang selalu menunggu request, Job menjalankan task, lalu berhenti. Cocok untuk ETL, data processing, scheduled tasks.

Container Image

Cloud Run menggunakan container image standar (OCI) yang bisa dibangun dengan Dockerfile apapun. Image disimpan di Artifact Registry (recommended) atau Docker Hub, GitHub Container Registry, dll.

Diagram: Service vs Job
  CLOUD RUN SERVICE               CLOUD RUN JOB
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ HTTP Listener    β”‚             β”‚ Batch Task       β”‚
  β”‚                  β”‚             β”‚                  β”‚
  β”‚ Always listening β”‚             β”‚ Run β†’ Complete   β”‚
  β”‚ for requests     β”‚             β”‚ β†’ Done           β”‚
  β”‚                  β”‚             β”‚                  β”‚
  β”‚ Scale: 0-N       β”‚             β”‚ Execute: 1-N     β”‚
  β”‚ Timeout: 60min   β”‚             β”‚ tasks in         β”‚
  β”‚                  β”‚             β”‚ parallel         β”‚
  β”‚ Use Cases:       β”‚             β”‚                  β”‚
  β”‚ - Web App        β”‚             β”‚ Use Cases:       β”‚
  β”‚ - REST API       β”‚             β”‚ - ETL jobs       β”‚
  β”‚ - GraphQL API    β”‚             β”‚ - Data migration β”‚
  β”‚ - Microservices  β”‚             β”‚ - Scheduled task β”‚
  β”‚ - Webhook        β”‚             β”‚ - Report gen     β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Region dan Availability

Cloud Run tersedia di lebih dari 30 region di seluruh dunia. Setiap region menyimpan container image dan menjalankan instances dekat dengan user. Multi-region deployment dimungkinkan dengan Cloud Load Balancing.

3. Deploy Aplikasi ke Cloud Run

Prerequisites

Bash
# Install Google Cloud CLI
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init

# Login dan set project
gcloud auth login
gcloud config set project my-project-id

# Enable Cloud Run API
gcloud services enable run.googleapis.com
gcloud services enable artifactregistry.googleapis.com

# Set default region
gcloud config set run/region asia-southeast1

# Verifikasi
gcloud --version
gcloud run --help

Deploy dari Source Code (Tanpa Dockerfile)

Cloud Run bisa mendeteksi bahasa pemrograman dan membuat container image secara otomatis menggunakan Buildpacks.

Bash
# Deploy langsung dari source directory
gcloud run deploy my-service \
  --source . \
  --region asia-southeast1 \
  --allow-unauthenticated \
  --port 8080 \
  --memory 512Mi \
  --cpu 1 \
  --min-instances 0 \
  --max-instances 10

# Buildpacks akan otomatis:
# 1. Detect bahasa (Node.js, Python, Go, Java, dll)
# 2. Install dependencies
# 3. Build container image
# 4. Push ke Artifact Registry
# 5. Deploy ke Cloud Run
# 6. Berikan URL publik

Deploy dari Container Image

Bash
# Deploy dari image yang sudah ada di Artifact Registry
gcloud run deploy my-service \
  --image asia-southeast1-docker.pkg.dev/my-project/my-repo/my-app:latest \
  --region asia-southeast1 \
  --allow-unauthenticated

# Deploy dari Docker Hub
gcloud run deploy my-service \
  --image nginx:latest \
  --region asia-southeast1 \
  --port 80

# Deploy dengan environment variables
gcloud run deploy my-service \
  --image my-registry/my-app:v2.0 \
  --region asia-southeast1 \
  --set-env-vars "DATABASE_URL=postgres://..." \
  --set-env-vars "NODE_ENV=production" \
  --set-env-vars "API_KEY=my-secret-key"

# Deploy dengan secrets dari Secret Manager
gcloud run deploy my-service \
  --image my-registry/my-app:latest \
  --set-secrets "DATABASE_URL=db-url-secret:latest" \
  --set-secrets "API_KEY=api-key-secret:latest"

Manage Services

Bash
# List semua services
gcloud run services list --region asia-southeast1

# Deskripsi service
gcloud run services describe my-service --region asia-southeast1

# Lihat URL service
gcloud run services describe my-service \
  --region asia-southeast1 \
  --format 'value(status.url)'

# Update service
gcloud run services update my-service \
  --region asia-southeast1 \
  --memory 1Gi \
  --cpu 2 \
  --max-instances 20

# Delete service
gcloud run services delete my-service --region asia-southeast1

# Lihat logs
gcloud run services logs read my-service --region asia-southeast1 --limit 50

# Export service ke YAML
gcloud run services describe my-service \
  --region asia-southeast1 \
  --format yaml > service-config.yaml

4. Containerisasi Aplikasi untuk Cloud Run

Dockerfile untuk Node.js

Dockerfile
# Node.js Express App untuk Cloud Run
FROM node:20-slim

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy source code
COPY . .

# Cloud Run menggunakan PORT environment variable
ENV PORT=8080

# Expose port
EXPOSE 8080

# Gunakan non-root user
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
USER appuser

# Start app
CMD ["node", "server.js"]

App Server yang Mendengarkan PORT

JavaScript
// server.js β€” Penting: gunakan process.env.PORT
const express = require('express');
const app = express();

const PORT = process.env.PORT || 8080;

app.get('/', (req, res) => {
  res.json({
    message: 'Hello from Cloud Run!',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV || 'development'
  });
});

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'healthy' });
});

// Penting: listen pada 0.0.0.0 bukan localhost
app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server listening on port ${PORT}`);
});

Dockerfile untuk Python Flask

Dockerfile
# Python Flask App untuk Cloud Run
FROM python:3.12-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy app
COPY . .

# Set environment
ENV PORT=8080

# Non-root user
RUN adduser --disabled-password --gecos "" appuser
USER appuser

# Start with gunicorn
CMD exec gunicorn --bind :$PORT --workers 2 --threads 8 app:app
Python
# app.py
import os
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def home():
    return jsonify({
        'message': 'Hello from Cloud Run!',
        'language': 'Python',
        'port': os.environ.get('PORT', 8080)
    })

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8080))
    app.run(host='0.0.0.0', port=port)

Multi-stage Build untuk Image Lebih Kecil

Dockerfile
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist

ENV NODE_ENV=production
ENV PORT=8080
EXPOSE 8080

USER node
CMD ["node", "dist/server.js"]
πŸ’‘ Tips

Pastikan container app Anda selalu mendengarkan pada 0.0.0.0 (bukan localhost/127.0.0.1) dan menggunakan environment variable PORT. Cloud Run menginject PORT secara otomatis β€” defaultnya 8080.

5. Revisions dan Versioning

Setiap kali Anda deploy atau mengubah konfigurasi service, Cloud Run membuat revision baru. Revision adalah snapshot immutable dari konfigurasi service β€” termasuk container image, environment variables, resource limits, dan lainnya. Revision tidak pernah diubah, hanya baru yang dibuat.

Cara Kerja Revisions

Diagram: Revision Lifecycle
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   REVISION LIFECYCLE                       β”‚
β”‚                                                           β”‚
β”‚  Deploy v1        Deploy v2        Deploy v3              β”‚
β”‚  ─────────►       ─────────►       ─────────►            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚  β”‚Revision β”‚      β”‚Revision β”‚      β”‚Revision β”‚          β”‚
β”‚  β”‚  001    β”‚      β”‚  002    β”‚      β”‚  003    β”‚          β”‚
β”‚  β”‚         β”‚      β”‚         β”‚      β”‚         β”‚          β”‚
β”‚  β”‚ Image:  β”‚      β”‚ Image:  β”‚      β”‚ Image:  β”‚          β”‚
β”‚  β”‚ app:v1  β”‚      β”‚ app:v2  β”‚      β”‚ app:v3  β”‚          β”‚
β”‚  β”‚ CPU: 1  β”‚      β”‚ CPU: 1  β”‚      β”‚ CPU: 2  β”‚          β”‚
β”‚  β”‚ Mem:512 β”‚      β”‚ Mem:1Gi β”‚      β”‚ Mem:1Gi β”‚          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
β”‚  Traffic: 50%     Traffic: 50%     Traffic: 100%  β˜…      β”‚
β”‚  Status: ACTIVE   Status: ACTIVE   Status: ACTIVE        β”‚
β”‚                                                           β”‚
β”‚  Revision properties (immutable):                         β”‚
β”‚  - Container image & tag                                  β”‚
β”‚  - Environment variables                                  β”‚
β”‚  - Resource limits (CPU, memory)                         β”‚
β”‚  - Concurrency settings                                  β”‚
β”‚  - Timeout                                               β”‚
β”‚  - Min/Max instances                                     β”‚
β”‚  - Secrets mapping                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Manage Revisions

Bash
# List semua revisions
gcloud run revisions list \
  --service my-service \
  --region asia-southeast1

# Deskripsi revision spesifik
gcloud run revisions describe my-service-00002-abc \
  --region asia-southeast1

# Lihat revisions dengan detail
gcloud run revisions list \
  --service my-service \
  --region asia-southeast1 \
  --format "table(name, metadata.creationTimestamp, spec.containerConcurrency, status.conditions.type)"

# Deploy dengan nama revision custom
gcloud run deploy my-service \
  --image my-app:v2.0 \
  --revision-suffix v2-0 \
  --region asia-southeast1

# Output:
# Revisions:
#   my-service-00001        (v1.0)    Traffic: 0%
#   my-service-v2-0         (v2.0)    Traffic: 100%

# Rollback ke revision sebelumnya
gcloud run services update-traffic my-service \
  --to-revisions my-service-00001=100 \
  --region asia-southeast1

# Hapus revisions lama (yang tidak menerima traffic)
# Cloud Run otomatis menghapus revisions idle setelah beberapa waktu
# Tapi bisa juga dihapus manual untuk menghemat memory

6. Traffic Splitting

Traffic Splitting adalah fitur powerful Cloud Run yang memungkinkan Anda mengarahkan persentase traffic ke revision tertentu. Ini sangat berguna untuk canary deployments, A/B testing, dan gradual rollouts.

Traffic Splitting Patterns

Diagram: Traffic Splitting Patterns
  PATTERN 1: ROLLING UPDATE (default)
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Revision 1 β”‚   β”‚ Revision 2 β”‚
  β”‚   0% ◄─────────── 100%     β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  Instant switch dari v1 ke v2

  PATTERN 2: CANARY DEPLOYMENT
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Revision 1 β”‚   β”‚ Revision 2 β”‚
  β”‚    90% ◄──────── 10%       β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  Test 10% traffic pada v2 dulu

  PATTERN 3: A/B TESTING
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Revision 1 β”‚   β”‚ Revision 2 β”‚
  β”‚    50% ◄──────── 50%       β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  Split traffic 50:50

  PATTERN 4: GRADUAL ROLLOUT
  Step 1: 95% / 5%
  Step 2: 80% / 20%
  Step 3: 50% / 50%
  Step 4: 0% / 100%
Bash
# === TRAFFIC SPLITTING COMMANDS ===

# Default: 100% ke revisi terbaru
gcloud run deploy my-service \
  --image my-app:v2.0 \
  --region asia-southeast1

# Split traffic: 90% v1, 10% v2 (canary)
gcloud run services update-traffic my-service \
  --to-revisions my-service-00001=90,my-service-00002=10 \
  --region asia-southeast1

# Gradual rollout: 80% v1, 20% v2
gcloud run services update-traffic my-service \
  --to-revisions my-service-00001=80,my-service-00002=20 \
  --region asia-southeast1

# Complete rollout: 100% ke v2
gcloud run services update-traffic my-service \
  --to-revisions my-service-00002=100 \
  --region asia-southeast1

# Rollback: 100% ke v1
gcloud run services update-traffic my-service \
  --to-revisions my-service-00001=100 \
  --region asia-southeast1

# Deploy tanpa langsung menerima traffic (--no-traffic)
gcloud run deploy my-service \
  --image my-app:v3.0 \
  --no-traffic \
  --region asia-southeast1
# Revision baru dibuat tapi tidak menerima traffic
# Untuk testing via URL khusus sebelum promote

# Promote revision yang di-test
gcloud run services update-traffic my-service \
  --to-revisions my-service-00003=100 \
  --region asia-southeast1

# Lihat traffic distribution saat ini
gcloud run services describe my-service \
  --region asia-southeast1 \
  --format "table(status.traffic.revisionName, status.traffic.percent, status.traffic.tag)"

Tagged Revisions untuk Testing

Bash
# Deploy dengan tag (preview URL)
gcloud run deploy my-service \
  --image my-app:v3.0 \
  --tag staging \
  --no-traffic \
  --region asia-southeast1

# Akses via tagged URL untuk testing
# Format: https://staging----uc.a.run.app
# Tidak mempengaruhi traffic production

# Update tag
gcloud run services update-traffic my-service \
  --update-tags staging=my-service-00003 \
  --region asia-southeast1

# Remove tag
gcloud run services update-traffic my-service \
  --remove-tags staging \
  --region asia-southeast1

# Promote tagged revision ke production
gcloud run services update-traffic my-service \
  --to-revisions my-service-00003=100 \
  --region asia-southeast1
πŸ’‘ Tips

Gunakan --no-traffic saat deploy untuk mencegah revision baru langsung menerima traffic. Test dulu via tagged URL, lalu promote ke production jika sudah yakin. Ini mengurangi risiko deployment yang buruk.

7. Auto-scaling dan Konfigurasi

Cara Kerja Auto-scaling

Cloud Run secara otomatis menambah atau mengurangi instances berdasarkan jumlah concurrent requests. Setiap instance bisa menerima 1-80 concurrent request (configurable). Ketika semua instance penuh, Cloud Run menambah instance baru. Ketika traffic turun, instance idle akan di-scale down ke nol.

Konfigurasi Resource

Parameter Range Default
CPU1, 2, 4, 6, 8 vCPU1 vCPU
Memory128 MiB - 32 GiB256 MiB
Concurrency1 - 100080
Timeout1 - 3600 detik (60 menit)300 detik
Min Instances0 - 10000
Max Instances0 - 1000100
Request timeout1s - 3600s300s
Bash
# Deploy dengan full configuration
gcloud run deploy my-service \
  --image my-app:latest \
  --region asia-southeast1 \
  --cpu 2 \
  --memory 1Gi \
  --concurrency 100 \
  --timeout 600 \
  --min-instances 1 \
  --max-instances 50 \
  --port 8080

# Update resource tanpa redeploy
gcloud run services update my-service \
  --region asia-southeast1 \
  --cpu 4 \
  --memory 2Gi \
  --max-instances 100

# CPU allocation modes:
# --cpu-boost    : Startup CPU boost (allocasi CPU lebih saat cold start)
# --cpu-throttled: CPU throttled saat tidak menerima request
# --no-cpu-throttle: CPU selalu allocated (untuk background processing)

# Deploy dengan startup CPU boost
gcloud run deploy my-service \
  --image my-app:latest \
  --cpu-boost \
  --region asia-southeast1

# CPU always allocated (untuk WebSockets atau background tasks)
gcloud run deploy my-service \
  --image my-app:latest \
  --no-cpu-throttle \
  --min-instances 1 \
  --region asia-southeast1

Cold Start Mitigation

⚠️ Cold Start

Cold start terjadi ketika Cloud Run perlu membuat instance baru karena tidak ada instance yang idle. Ini bisa menambah 1-5 detik latency. Cara mengatasi: (1) set --min-instances 1 untuk menjaga minimal 1 instance tetap hidup, (2) gunakan --cpu-boost untuk percepat startup, (3) buat container image sekecil mungkin.

8. Custom Domains dan HTTPS

Bash
# Map custom domain ke Cloud Run service
gcloud run domain-mappings create \
  --service my-service \
  --domain myapp.example.com \
  --region asia-southeast1

# Output akan menunjukkan DNS records yang perlu ditambahkan:
# NAME   TYPE  DATA
# myapp  A     216.239.32.21
# myapp  AAAA  2001:4860:4802:32::15
# _ghs  CNAME   ghs.googlehosted.com.

# Setelah DNS dikonfigurasi, SSL certificate otomatis dibuat

# List domain mappings
gcloud run domain-mappings list --region asia-southeast1

# Deskripsi mapping
gcloud run domain-mappings describe myapp.example.com \
  --region asia-southeast1

# Delete domain mapping
gcloud run domain-mappings delete myapp.example.com \
  --region asia-southeast1

# Dengan Google-managed SSL certificate (otomatis)
# Cloud Run otomatis provisioning SSL cert untuk custom domain
# Pastikan DNS record benar dan propagated

Multi-region dengan Load Balancer

Bash
# Deploy ke beberapa region
gcloud run deploy my-service-asia \
  --image my-app:latest \
  --region asia-southeast1

gcloud run deploy my-service-us \
  --image my-app:latest \
  --region us-central1

gcloud run deploy my-service-eu \
  --image my-app:latest \
  --region europe-west1

# Buat Serverless NEG (Network Endpoint Group) untuk setiap region
gcloud compute network-endpoint-groups create neg-asia \
  --region=asia-southeast1 \
  --serverless-service=my-service-asia

gcloud compute network-endpoint-groups create neg-us \
  --region=us-central1 \
  --serverless-service=my-service-us

# Buat Load Balancer dengan URL Map
# (Lebih detail di Google Cloud Load Balancing docs)

9. Cloud Run Jobs

Cloud Run Jobs cocok untuk tugas yang berjalan sekali dan selesai β€” seperti ETL, migration, scheduled reports, dan batch processing.

Bash
# Buat Cloud Run Job
gcloud run jobs create etl-job \
  --image my-etl-image:latest \
  --region asia-southeast1 \
  --tasks 10 \
  --parallelism 5 \
  --memory 2Gi \
  --cpu 2 \
  --max-retries 3 \
  --set-env-vars "SOURCE=gs://my-bucket/data/*"

# Execute job
gcloud run jobs execute etl-job --region asia-southeast1

# Execute dengan override parameters
gcloud run jobs execute etl-job \
  --region asia-southeast1 \
  --tasks 20 \
  --parallelism 10

# Cek status execution
gcloud run jobs executions describe etl-job-xxxxx \
  --region asia-southeast1

# List executions
gcloud run jobs executions list \
  --job etl-job \
  --region asia-southeast1

# Lihat logs dari execution
gcloud run jobs executions describe etl-job-xxxxx \
  --region asia-southeast1 \
  --format 'value(status.executionCompletionStatus)'

# Update job
gcloud run jobs update etl-job \
  --region asia-southeast1 \
  --memory 4Gi \
  --tasks 20

# Schedule job dengan Cloud Scheduler
gcloud scheduler jobs create http etl-daily \
  --location asia-southeast1 \
  --schedule "0 2 * * *" \
  --uri "https://run.googleapis.com/v2/projects/my-project/locations/asia-southeast1/jobs/etl-job:run" \
  --http-method POST \
  --oauth-service-account-email scheduler@my-project.iam.gserviceaccount.com

# Delete job
gcloud run jobs delete etl-job --region asia-southeast1

10. Integrasi dengan GCP Services

Cloud SQL Connection

Bash
# Deploy dengan Cloud SQL connection
gcloud run deploy my-service \
  --image my-app:latest \
  --region asia-southeast1 \
  --add-cloudsql-instances my-project:asia-southeast1:my-db \
  --set-env-vars "INSTANCE_CONNECTION_NAME=my-project:asia-southeast1:my-db"

# Gunakan Cloud SQL Auth Proxy (recommended)
# Environment variables untuk koneksi database:
# DB_HOST=/cloudsql/my-project:asia-southeast1:my-db
# DB_USER=postgres
# DB_PASS=secret-from-secret-manager
# DB_NAME=myapp

Pub/Sub Integration

Bash
# Cloud Run bisa subscribe ke Pub/Sub topics
# Buat service account untuk Pub/Sub push
gcloud iam service-accounts create pubsub-invoker \
  --display-name "Pub/Sub to Cloud Run Invoker"

# Berikan permission
gcloud run services add-iam-policy-binding my-service \
  --region asia-southeast1 \
  --member serviceAccount:pubsub-invoker@my-project.iam.gserviceaccount.com \
  --role roles/run.invoker

# Create Pub/Sub subscription yang push ke Cloud Run
gcloud pubsub subscriptions create my-subscription \
  --topic my-topic \
  --push-endpoint=https://my-service-xxx.a.run.app/pubsub \
  --push-auth-service-account=pubsub-invoker@my-project.iam.gserviceaccount.com

VPC Connector untuk Private Resources

Bash
# Buat VPC Connector
gcloud compute networks vpc-access connector create my-connector \
  --region asia-southeast1 \
  --subnet projects/my-project/regions/asia-southeast1/subnetworks/default \
  --min-instances 2 \
  --max-instances 10

# Deploy dengan VPC connector
gcloud run deploy my-service \
  --image my-app:latest \
  --region asia-southeast1 \
  --vpc-connector my-connector \
  --set-env-vars "REDIS_HOST=10.0.0.5"

# Sekarang service bisa mengakses resources di VPC:
# - Cloud SQL private IP
# - Redis/Memcached
# - Internal microservices
# - Private APIs

11. Best Practices

Best Practice Detail
Stateless AppsCloud Run instances bisa dihentikan kapanpun. Jangan simpan state di container. Gunakan external storage (Cloud Storage, Cloud SQL, Redis)
Graceful ShutdownHandle SIGTERM signal untuk cleanup sebelum container dihentikan. Timeout 10 detik default
Health ChecksImplementasi /health endpoint. Cloud Run menggunakan ini untuk menentukan kesehatan instance
Min InstancesGunakan --min-instances 1 untuk production services yang sensitif terhadap cold start
ConcurrencyTurunkan concurrency jika app CPU-intensive. Naikkan jika I/O-bound (waiting database)
Image SizeGunakan multi-stage build dan Alpine base images. Image kecil = deploy cepat + cold start cepat
SecretsJangan taruh secrets di environment variables langsung. Gunakan Secret Manager
IAMGunakan least-privilege. Jangan gunakan --allow-unauthenticated untuk internal services
LoggingOutput logs ke stdout/stderr. Cloud Run otomatis mengirim ke Cloud Logging
Startup ProbeImplementasi startup readiness. Cloud Run akan mengirim traffic setelah container start
πŸ’‘ Tips

Untuk mengurangi cold start, gunakan kombinasi --min-instances 1 + --cpu-boost + image sekecil mungkin. Untuk WebSocket atau streaming, gunakan --no-cpu-throttle dan set --min-instances 1.

12. Quiz Pemahaman

πŸ“ Quiz: Pemahaman Google Cloud Run

1. Apa keunggulan utama Cloud Run dibanding GKE?

2. Apa yang terjadi saat Cloud Run menerima request tapi semua instance penuh?

3. Untuk apa --no-traffic digunakan saat deploy?

4. Apa itu Revision dalam Cloud Run?

5. Environment variable apa yang HARUS didengarkan oleh container di Cloud Run?

πŸ” Zoom
100%
🎨 Tema