Claude Agent Skill · by Sickn33

Gcp Cloud Run

Install Gcp Cloud Run skill for Claude Code from sickn33/antigravity-awesome-skills.

Install
Terminal · npx
$npx skills add https://github.com/vercel-labs/skills --skill find-skills
Works with Paperclip

How Gcp Cloud Run fits into a Paperclip company.

Gcp Cloud Run drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md1382 lines
Expand
---name: gcp-cloud-rundescription: Specialized skill for building production-ready serverless  applications on GCP. Covers Cloud Run services (containerized), Cloud Run  Functions (event-driven), cold start optimization, and event-driven  architecture with Pub/Sub.risk: unknownsource: vibeship-spawner-skills (Apache 2.0)date_added: 2026-02-27--- # GCP Cloud Run Specialized skill for building production-ready serverless applications on GCP.Covers Cloud Run services (containerized), Cloud Run Functions (event-driven),cold start optimization, and event-driven architecture with Pub/Sub. ## Principles - Cloud Run for containers, Functions for simple event handlers- Optimize for cold starts with startup CPU boost and min instances- Set concurrency based on workload (start with 8, adjust)- Memory includes /tmp filesystem - plan accordingly- Use VPC Connector only when needed (adds latency)- Containers should start fast and be stateless- Handle signals gracefully for clean shutdown ## Patterns ### Cloud Run Service Pattern Containerized web service on Cloud Run **When to use**: Web applications and APIs,Need any runtime or library,Complex services with multiple endpoints,Stateless containerized workloads ```dockerfile# Dockerfile - Multi-stage build for smaller imageFROM node:20-slim AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=production FROM node:20-slimWORKDIR /app # Copy only production dependenciesCOPY --from=builder /app/node_modules ./node_modulesCOPY src ./srcCOPY package.json ./ # Cloud Run uses PORT env variableENV PORT=8080EXPOSE 8080 # Run as non-root userUSER node CMD ["node", "src/index.js"]``` ```javascript// src/index.jsconst express = require('express');const app = express(); app.use(express.json()); // Health check endpointapp.get('/health', (req, res) => {  res.status(200).send('OK');}); // API routesapp.get('/api/items/:id', async (req, res) => {  try {    const item = await getItem(req.params.id);    res.json(item);  } catch (error) {    console.error('Error:', error);    res.status(500).json({ error: 'Internal server error' });  }}); // Graceful shutdownprocess.on('SIGTERM', () => {  console.log('SIGTERM received, shutting down gracefully');  server.close(() => {    console.log('Server closed');    process.exit(0);  });}); const PORT = process.env.PORT || 8080;const server = app.listen(PORT, () => {  console.log(`Server listening on port ${PORT}`);});``` ```yaml# cloudbuild.yamlsteps:  # Build the container image  - name: 'gcr.io/cloud-builders/docker'    args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA', '.']   # Push the container image  - name: 'gcr.io/cloud-builders/docker'    args: ['push', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA']   # Deploy to Cloud Run  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'    entrypoint: gcloud    args:      - 'run'      - 'deploy'      - 'my-service'      - '--image=gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA'      - '--region=us-central1'      - '--platform=managed'      - '--allow-unauthenticated'      - '--memory=512Mi'      - '--cpu=1'      - '--min-instances=1'      - '--max-instances=100'      - '--concurrency=80'      - '--cpu-boost' images:  - 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA'``` ### Structure project/├── Dockerfile├── .dockerignore├── src/│   ├── index.js│   └── routes/├── package.json└── cloudbuild.yaml ### Gcloud_deploy # Direct gcloud deploymentgcloud run deploy my-service \  --source . \  --region us-central1 \  --allow-unauthenticated \  --memory 512Mi \  --cpu 1 \  --min-instances 1 \  --max-instances 100 \  --concurrency 80 \  --cpu-boost ### Cloud Run Functions Pattern Event-driven functions (formerly Cloud Functions) **When to use**: Simple event handlers,Pub/Sub message processing,Cloud Storage triggers,HTTP webhooks ```javascript// HTTP Function// index.jsconst functions = require('@google-cloud/functions-framework'); functions.http('helloHttp', (req, res) => {  const name = req.query.name || req.body.name || 'World';  res.send(`Hello, ${name}!`);});``` ```javascript// Pub/Sub Functionconst functions = require('@google-cloud/functions-framework'); functions.cloudEvent('processPubSub', (cloudEvent) => {  // Decode Pub/Sub message  const message = cloudEvent.data.message;  const data = message.data    ? JSON.parse(Buffer.from(message.data, 'base64').toString())    : {};   console.log('Received message:', data);   // Process message  processMessage(data);});``` ```javascript// Cloud Storage Functionconst functions = require('@google-cloud/functions-framework'); functions.cloudEvent('processStorageEvent', async (cloudEvent) => {  const file = cloudEvent.data;   console.log(`Event: ${cloudEvent.type}`);  console.log(`Bucket: ${file.bucket}`);  console.log(`File: ${file.name}`);   if (cloudEvent.type === 'google.cloud.storage.object.v1.finalized') {    await processUploadedFile(file.bucket, file.name);  }});``` ```bash# Deploy HTTP functiongcloud functions deploy hello-http \  --gen2 \  --runtime nodejs20 \  --trigger-http \  --allow-unauthenticated \  --region us-central1 # Deploy Pub/Sub functiongcloud functions deploy process-messages \  --gen2 \  --runtime nodejs20 \  --trigger-topic my-topic \  --region us-central1 # Deploy Cloud Storage functiongcloud functions deploy process-uploads \  --gen2 \  --runtime nodejs20 \  --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \  --trigger-event-filters="bucket=my-bucket" \  --region us-central1``` ### Cold Start Optimization Pattern Minimize cold start latency for Cloud Run **When to use**: Latency-sensitive applications,User-facing APIs,High-traffic services ## 1. Enable Startup CPU Boost ```bashgcloud run deploy my-service \  --cpu-boost \  --region us-central1``` ## 2. Set Minimum Instances ```bashgcloud run deploy my-service \  --min-instances 1 \  --region us-central1``` ## 3. Optimize Container Image ```dockerfile# Use distroless for minimal imageFROM node:20-slim AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=production FROM gcr.io/distroless/nodejs20-debian12WORKDIR /appCOPY --from=builder /app/node_modules ./node_modulesCOPY src ./srcCMD ["src/index.js"]``` ## 4. Lazy Initialize Heavy Dependencies ```javascript// Lazy load heavy librarieslet bigQueryClient = null; function getBigQueryClient() {  if (!bigQueryClient) {    const { BigQuery } = require('@google-cloud/bigquery');    bigQueryClient = new BigQuery();  }  return bigQueryClient;} // Only initialize when neededapp.get('/api/analytics', async (req, res) => {  const client = getBigQueryClient();  const results = await client.query({...});  res.json(results);});``` ## 5. Increase Memory (More CPU) ```bash# Higher memory = more CPU during startupgcloud run deploy my-service \  --memory 1Gi \  --cpu 2 \  --region us-central1``` ### Optimization_impact - Startup_cpu_boost: 50% faster cold starts- Min_instances: Eliminates cold starts for traffic spikes- Distroless_image: Smaller attack surface, faster pull- Lazy_init: Defers heavy loading to first request ### Concurrency Configuration Pattern Proper concurrency settings for Cloud Run **When to use**: Need to optimize instance utilization,Handle traffic spikes efficiently,Reduce cold starts ## Understanding Concurrency ```bash# Default concurrency is 80# Adjust based on your workload # For I/O-bound workloads (most web apps)gcloud run deploy my-service \  --concurrency 80 \  --cpu 1 # For CPU-bound workloadsgcloud run deploy my-service \  --concurrency 1 \  --cpu 1 # For memory-intensive workloadsgcloud run deploy my-service \  --concurrency 10 \  --memory 2Gi``` ## Node.js Concurrency ```javascript// Node.js is single-threaded but handles I/O concurrently// Use async/await for all I/O operations // GOOD - async I/Oapp.get('/api/data', async (req, res) => {  const [users, products] = await Promise.all([    fetchUsers(),    fetchProducts()  ]);  res.json({ users, products });}); // BAD - blocking operationapp.get('/api/compute', (req, res) => {  const result = heavyCpuOperation(); // Blocks other requests!  res.json(result);});``` ## Python Concurrency with Gunicorn ```dockerfileFROM python:3.11-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . . # 4 workers for concurrencyCMD exec gunicorn --bind :$PORT --workers 4 --threads 2 main:app``` ```python# main.pyfrom flask import Flaskapp = Flask(__name__) @app.route('/api/data')def get_data():    return {'status': 'ok'}``` ### Concurrency_guidelines - Concurrency=1: Only for CPU-bound or unsafe code- Concurrency=8 20: Memory-intensive workloads- Concurrency=80: Default, good for I/O-bound- Concurrency=250: Maximum, for very lightweight handlers ### Pub/Sub Integration Pattern Event-driven processing with Cloud Pub/Sub **When to use**: Asynchronous message processing,Decoupled microservices,Event-driven architecture ## Push Subscription to Cloud Run ```bash# Create topicgcloud pubsub topics create orders # Create push subscription to Cloud Rungcloud pubsub subscriptions create orders-push \  --topic orders \  --push-endpoint https://my-service-xxx.run.app/pubsub \  --ack-deadline 600``` ```javascript// Handle Pub/Sub push messagesconst express = require('express');const app = express();app.use(express.json()); app.post('/pubsub', async (req, res) => {  // Verify the request is from Pub/Sub  if (!req.body.message) {    return res.status(400).send('Invalid Pub/Sub message');  }   try {    // Decode message data    const message = req.body.message;    const data = message.data      ? JSON.parse(Buffer.from(message.data, 'base64').toString())      : {};     console.log('Processing order:', data);     await processOrder(data);     // Return 200 to acknowledge    res.status(200).send('OK');  } catch (error) {    console.error('Processing failed:', error);    // Return 500 to trigger retry    res.status(500).send('Processing failed');  }});``` ## Publishing Messages ```javascriptconst { PubSub } = require('@google-cloud/pubsub');const pubsub = new PubSub(); async function publishOrder(order) {  const topic = pubsub.topic('orders');  const messageBuffer = Buffer.from(JSON.stringify(order));   const messageId = await topic.publishMessage({    data: messageBuffer,    attributes: {      type: 'order_created',      priority: 'high'    }  });   console.log(`Published message ${messageId}`);  return messageId;}``` ## Dead Letter Queue ```bash# Create DLQ topicgcloud pubsub topics create orders-dlq # Update subscription with DLQgcloud pubsub subscriptions update orders-push \  --dead-letter-topic orders-dlq \  --max-delivery-attempts 5``` ### Cloud SQL Connection Pattern Connect Cloud Run to Cloud SQL securely **When to use**: Need relational database,Migrating existing applications,Complex queries and transactions ```bash# Deploy with Cloud SQL connectiongcloud run deploy my-service \  --add-cloudsql-instances PROJECT:REGION:INSTANCE \  --set-env-vars INSTANCE_CONNECTION_NAME="PROJECT:REGION:INSTANCE" \  --set-env-vars DB_NAME="mydb" \  --set-env-vars DB_USER="myuser"``` ```javascript// Using Unix socket connectionconst { Pool } = require('pg'); const pool = new Pool({  user: process.env.DB_USER,  password: process.env.DB_PASS,  database: process.env.DB_NAME,  // Cloud SQL connector uses Unix socket  host: `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}`,  max: 5,  // Connection pool size  idleTimeoutMillis: 30000,  connectionTimeoutMillis: 10000,}); app.get('/api/users', async (req, res) => {  const client = await pool.connect();  try {    const result = await client.query('SELECT * FROM users LIMIT 100');    res.json(result.rows);  } finally {    client.release();  }});``` ```python# Python with SQLAlchemyimport osfrom sqlalchemy import create_engine def get_engine():    instance_connection_name = os.environ["INSTANCE_CONNECTION_NAME"]    db_user = os.environ["DB_USER"]    db_pass = os.environ["DB_PASS"]    db_name = os.environ["DB_NAME"]     engine = create_engine(        f"postgresql+pg8000://{db_user}:{db_pass}@/{db_name}",        connect_args={            "unix_sock": f"/cloudsql/{instance_connection_name}/.s.PGSQL.5432"        },        pool_size=5,        max_overflow=2,        pool_timeout=30,        pool_recycle=1800,    )    return engine``` ### Best_practices - Use connection pooling (max 5-10 per instance)- Set appropriate idle timeouts- Handle connection errors gracefully- Consider Cloud SQL Proxy for local development ### Secret Manager Integration Securely manage secrets in Cloud Run **When to use**: API keys, database passwords,Service account keys,Any sensitive configuration ```bash# Create secretecho -n "my-secret-value" | gcloud secrets create my-secret --data-file=- # Mount as environment variablegcloud run deploy my-service \  --update-secrets=API_KEY=my-secret:latest # Mount as file volumegcloud run deploy my-service \  --update-secrets=/secrets/api-key=my-secret:latest``` ```javascript// Access mounted as environment variableconst apiKey = process.env.API_KEY; // Access mounted as fileconst fs = require('fs');const apiKey = fs.readFileSync('/secrets/api-key', 'utf8'); // Access via Secret Manager API (when not mounted)const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');const client = new SecretManagerServiceClient(); async function getSecret(name) {  const [version] = await client.accessSecretVersion({    name: `projects/${projectId}/secrets/${name}/versions/latest`  });  return version.payload.data.toString();}``` ## Sharp Edges ### /tmp Filesystem Counts Against Memory Severity: HIGH Situation: Writing files to /tmp directory in Cloud Run Symptoms:Container killed with OOM error.Memory usage spikes unexpectedly.File operations cause container restarts."Container memory limit exceeded" in logs. Why this breaks:Cloud Run uses an in-memory filesystem for /tmp. Any files writtento /tmp consume memory from your container's allocation. Common scenarios:- Downloading files temporarily- Creating temp processing files- Libraries caching to /tmp- Large log buffers A 512MB container that downloads a 200MB file to /tmp only has~300MB left for the application. Recommended fix: ## Calculate memory including /tmp usage ```yaml# cloudbuild.yamlsteps:  - name: 'gcr.io/cloud-builders/gcloud'    args:      - 'run'      - 'deploy'      - 'my-service'      - '--memory=1Gi'  # Include /tmp overhead      - '--image=gcr.io/$PROJECT_ID/my-service'``` ## Stream instead of buffering ```python# BAD - buffers entire file in /tmpdef process_large_file(bucket_name, blob_name):    blob = bucket.blob(blob_name)    blob.download_to_filename('/tmp/large_file')    with open('/tmp/large_file', 'rb') as f:        process(f.read()) # GOOD - stream processingdef process_large_file(bucket_name, blob_name):    blob = bucket.blob(blob_name)    with blob.open('rb') as f:        for chunk in iter(lambda: f.read(8192), b''):            process_chunk(chunk)``` ## Use Cloud Storage for large files ```pythonfrom google.cloud import storage def process_with_gcs(bucket_name, input_blob, output_blob):    client = storage.Client()    bucket = client.bucket(bucket_name)     # Process directly to/from GCS    input_blob = bucket.blob(input_blob)    output_blob = bucket.blob(output_blob)     with input_blob.open('rb') as reader:        with output_blob.open('wb') as writer:            for chunk in iter(lambda: reader.read(65536), b''):                processed = transform(chunk)                writer.write(processed)``` ## Monitor memory usage ```pythonimport psutilimport logging def log_memory():    memory = psutil.virtual_memory()    logging.info(f"Memory: {memory.percent}% used, "                f"{memory.available / 1024 / 1024:.0f}MB available")``` ### Concurrency=1 Causes Scaling Bottlenecks Severity: HIGH Situation: Setting concurrency to 1 for request isolation Symptoms:Auto-scaling creates many container instances.High latency during traffic spikes.Increased cold starts.Higher costs from more instances. Why this breaks:Setting concurrency to 1 means each container handles only onerequest at a time. During traffic spikes: - 100 concurrent requests = 100 container instances- Each instance has cold start overhead- More instances = higher costs- Scaling takes time, requests queue up This should only be used when:- Processing is truly single-threaded- Memory-heavy per-request processing- Using thread-unsafe libraries Recommended fix: ## Set appropriate concurrency ```bash# For I/O-bound workloads (most web apps)gcloud run deploy my-service \  --concurrency=80 \  --max-instances=100 # For CPU-bound workloadsgcloud run deploy my-service \  --concurrency=4 \  --cpu=2 # Only use 1 when absolutely necessarygcloud run deploy my-service \  --concurrency=1 \  --max-instances=1000  # Be prepared for many instances``` ## Node.js - use async properly ```javascript// With high concurrency, ensure async operationsconst express = require('express');const app = express(); app.get('/api/data', async (req, res) => {  // All I/O should be async  const data = await fetchFromDatabase();  const enriched = await enrichData(data);  res.json(enriched);}); // Concurrency 80+ is safe for async I/O workloads``` ## Python - use async framework ```pythonfrom fastapi import FastAPIimport asyncioimport httpx app = FastAPI() @app.get("/api/data")async def get_data():    # Async I/O allows high concurrency    async with httpx.AsyncClient() as client:        response = await client.get("https://api.example.com/data")        return response.json() # Concurrency 80+ safe with async framework``` ## Calculate concurrency ```concurrency = memory_limit / per_request_memory Example:- 512MB container- 20MB per request overhead- Safe concurrency: ~25``` ### CPU Throttled When Not Handling Requests Severity: HIGH Situation: Running background tasks or processing between requests Symptoms:Background tasks run extremely slowly.Scheduled work doesn't complete.Metrics collection fails.Connection keep-alive breaks. Why this breaks:By default, Cloud Run throttles CPU to near-zero when not activelyhandling a request. This is "CPU only during requests" mode. Affected operations:- Background threads- Connection pool maintenance- Metrics/telemetry emission- Scheduled tasks within container- Cleanup operations after response Recommended fix: ## Enable CPU always allocated ```bash# CPU allocated even outside requestsgcloud run deploy my-service \  --cpu-throttling=false \  --min-instances=1 # Note: This increases costs but enables background work``` ## Use startup CPU boost for initialization ```bash# Boost CPU during cold start onlygcloud run deploy my-service \  --cpu-boost \  --cpu-throttling=true  # Default, throttle after request``` ## Move background work to Cloud Tasks ```pythonfrom google.cloud import tasks_v2import json def create_background_task(payload):    client = tasks_v2.CloudTasksClient()    parent = client.queue_path(        "my-project", "us-central1", "my-queue"    )     task = {        "http_request": {            "http_method": tasks_v2.HttpMethod.POST,            "url": "https://my-service.run.app/process",            "body": json.dumps(payload).encode(),            "headers": {"Content-Type": "application/json"}        }    }     client.create_task(parent=parent, task=task) # Handle response immediately, background via Cloud Tasks@app.post("/api/order")async def create_order(order: Order):    order_id = await save_order(order)     # Queue background processing    create_background_task({"order_id": order_id})     return {"order_id": order_id, "status": "processing"}``` ## Use Pub/Sub for async processing ```yaml# Move heavy processing to separate servicesteps:  # Main service - responds quickly  - name: 'gcr.io/cloud-builders/gcloud'    args: ['run', 'deploy', 'api-service',           '--cpu-throttling=true']   # Worker service - processes messages  - name: 'gcr.io/cloud-builders/gcloud'    args: ['run', 'deploy', 'worker-service',           '--cpu-throttling=false',           '--min-instances=1']``` ### VPC Connector 10-Minute Idle Timeout Severity: MEDIUM Situation: Cloud Run service connecting to VPC resources Symptoms:Connection errors after period of inactivity."Connection reset" or "Connection refused" errors.Sporadic failures to VPC resources.Database connections drop unexpectedly. Why this breaks:Cloud Run's VPC connector has a 10-minute idle timeout on connections.If a connection is idle for 10 minutes, it's silently closed. Affects:- Database connection pools- Redis connections- Internal API connections- Any persistent VPC connection Recommended fix: ## Configure connection pool with keep-alive ```python# SQLAlchemy with connection recyclingfrom sqlalchemy import create_engine engine = create_engine(    DATABASE_URL,    pool_size=5,    max_overflow=2,    pool_recycle=300,  # Recycle connections every 5 minutes    pool_pre_ping=True  # Validate connection before use)``` ## TCP keep-alive for custom connections ```pythonimport socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 60)sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)``` ## Redis with connection validation ```pythonimport redis pool = redis.ConnectionPool(    host=REDIS_HOST,    port=6379,    socket_keepalive=True,    socket_keepalive_options={        socket.TCP_KEEPIDLE: 60,        socket.TCP_KEEPINTVL: 60,        socket.TCP_KEEPCNT: 5    },    health_check_interval=30)client = redis.Redis(connection_pool=pool)``` ## Use Cloud SQL Proxy sidecar ```yaml# Use Cloud SQL connector which handles reconnection# requirements.txtcloud-sql-python-connector[pg8000]``` ```pythonfrom google.cloud.sql.connector import Connectorimport sqlalchemy connector = Connector() def getconn():    return connector.connect(        "project:region:instance",        "pg8000",        user="user",        password="password",        db="database"    ) engine = sqlalchemy.create_engine(    "postgresql+pg8000://",    creator=getconn)``` ### Container Startup Timeout (4 minutes max) Severity: HIGH Situation: Deploying containers with slow initialization Symptoms:Deployment fails with "Container failed to start".Service never becomes healthy."Revision failed to become ready" errors.Works locally but fails on Cloud Run. Why this breaks:Cloud Run expects your container to start listening on PORT within4 minutes (240 seconds). If it doesn't, the instance is killed. Common causes:- Heavy framework initialization (ML models, etc.)- Waiting for external dependencies at startup- Large dependency loading- Database migrations on startup Recommended fix: ## Enable startup CPU boost ```bashgcloud run deploy my-service \  --cpu-boost \  --startup-cpu-boost``` ## Lazy initialization ```pythonfrom functools import lru_cachefrom fastapi import FastAPI app = FastAPI() # Don't load at import timemodel = None @lru_cache()def get_model():    global model    if model is None:        # Load on first request, not at startup        model = load_heavy_model()    return model @app.get("/predict")async def predict(data: dict):    model = get_model()  # Loads on first call only    return model.predict(data) # Startup is fast - model loads on first request``` ## Start listening immediately ```pythonimport asynciofrom fastapi import FastAPIimport uvicorn app = FastAPI() # Global state for async initializationinitialized = asyncio.Event() @app.on_event("startup")async def startup():    # Start background initialization    asyncio.create_task(async_init()) async def async_init():    # Heavy initialization happens after server starts    await load_models()    await warm_up_connections()    initialized.set() @app.get("/ready")async def ready():    if not initialized.is_set():        raise HTTPException(503, "Still initializing")    return {"status": "ready"} @app.get("/health")async def health():    # Always respond - health check passes    return {"status": "healthy"}``` ## Use multi-stage builds ```dockerfile# Build stage - slowFROM python:3.11 as builderWORKDIR /appCOPY requirements.txt .RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt # Runtime stage - fast startupFROM python:3.11-slimWORKDIR /appCOPY --from=builder /wheels /wheelsRUN pip install --no-cache /wheels/* && rm -rf /wheelsCOPY . .CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]``` ## Run migrations separately ```bash# Don't migrate on startup - use Cloud Buildsteps:  # Run migrations first  - name: 'gcr.io/cloud-builders/gcloud'    entrypoint: 'bash'    args:      - '-c'      - |        gcloud run jobs execute migrate-job --wait   # Then deploy  - name: 'gcr.io/cloud-builders/gcloud'    args: ['run', 'deploy', 'my-service', ...]``` ### Second Generation Execution Environment Differences Severity: MEDIUM Situation: Migrating to or using Cloud Run second-gen execution environment Symptoms:Network behavior changes.Different syscall support.File system behavior differences.Container behaves differently than in first-gen. Why this breaks:Cloud Run's second-generation execution environment uses a differentsandbox (gVisor) with different characteristics: - More Linux syscalls supported- Full /proc and /sys access- Different network stack- No automatic HTTPS redirect- Different tmp filesystem behavior Recommended fix: ## Explicitly set execution environment ```bash# First generation (legacy)gcloud run deploy my-service \  --execution-environment=gen1 # Second generation (recommended for most)gcloud run deploy my-service \  --execution-environment=gen2``` ## Handle network differences ```python# Second-gen doesn't auto-redirect HTTP to HTTPSfrom fastapi import FastAPI, Requestfrom fastapi.responses import RedirectResponse app = FastAPI() @app.middleware("http")async def redirect_https(request: Request, call_next):    # Check X-Forwarded-Proto header    if request.headers.get("X-Forwarded-Proto") == "http":        url = request.url.replace(scheme="https")        return RedirectResponse(url, status_code=301)    return await call_next(request)``` ## GPU access (second-gen only) ```bash# GPUs only available in second-gengcloud run deploy ml-service \  --execution-environment=gen2 \  --gpu=1 \  --gpu-type=nvidia-l4``` ## Check execution environment ```pythonimport os def get_execution_environment():    # Second-gen has different /proc structure    try:        with open('/proc/version', 'r') as f:            version = f.read()            if 'gVisor' in version:                return 'gen2'    except:        pass    return 'gen1'``` ### Request Timeout Configuration Mismatch Severity: MEDIUM Situation: Long-running requests or background processing Symptoms:Requests terminated before completion.504 Gateway Timeout errors.Processing stops unexpectedly.Inconsistent timeout behavior. Why this breaks:Cloud Run has multiple timeout configurations that must align:- Request timeout (default 300s, max 3600s for HTTP, 60m for gRPC)- Client timeout- Downstream service timeouts- Load balancer timeout (for external access) Recommended fix: ## Set consistent timeouts ```bash# Increase request timeout (max 3600s for HTTP)gcloud run deploy my-service \  --timeout=900  # 15 minutes``` ## Handle long-running with webhooks ```pythonfrom fastapi import FastAPI, BackgroundTasksimport httpx app = FastAPI() @app.post("/process")async def process(data: dict, background_tasks: BackgroundTasks):    task_id = create_task_id()     # Start background processing    background_tasks.add_task(        long_running_process,        task_id,        data,        data.get("callback_url")    )     # Return immediately    return {"task_id": task_id, "status": "processing"} async def long_running_process(task_id, data, callback_url):    result = await heavy_computation(data)     # Callback when done    if callback_url:        async with httpx.AsyncClient() as client:            await client.post(callback_url, json={                "task_id": task_id,                "result": result            })``` ## Use Cloud Tasks for reliable long-running ```pythonfrom google.cloud import tasks_v2 def create_long_running_task(data):    client = tasks_v2.CloudTasksClient()    parent = client.queue_path(PROJECT, REGION, "long-tasks")     task = {        "http_request": {            "http_method": tasks_v2.HttpMethod.POST,            "url": "https://worker.run.app/process",            "body": json.dumps(data).encode(),            "headers": {"Content-Type": "application/json"}        },        "dispatch_deadline": {"seconds": 1800}  # 30 min    }     return client.create_task(parent=parent, task=task)``` ## Streaming for long responses ```pythonfrom fastapi import FastAPIfrom fastapi.responses import StreamingResponse @app.get("/large-report")async def large_report():    async def generate():        for chunk in process_large_data():            yield chunk     return StreamingResponse(generate(), media_type="text/plain")``` ## Validation Checks ### Hardcoded GCP Credentials Severity: ERROR GCP credentials must never be hardcoded in source code Message: Hardcoded GCP service account credentials. Use Secret Manager or Workload Identity. ### GCP API Key in Source Code Severity: ERROR API keys should use Secret Manager Message: Hardcoded GCP API key. Use Secret Manager. ### Credentials JSON File in Repository Severity: ERROR Service account JSON files should not be in source control Message: Credentials file detected. Add to .gitignore and use Secret Manager. ### Running as Root User Severity: WARNING Containers should not run as root for security Message: Dockerfile runs as root. Add USER directive for security. ### Missing Health Check in Dockerfile Severity: INFO Cloud Run uses HTTP health checks, Dockerfile HEALTHCHECK is optional Message: No HEALTHCHECK in Dockerfile. Cloud Run uses its own health checks. ### Hardcoded Port in Application Severity: WARNING Port should come from PORT environment variable Message: Hardcoded port. Use PORT environment variable for Cloud Run. ### Large File Writes to /tmp Severity: WARNING /tmp uses container memory, large writes can cause OOM Message: /tmp writes consume memory. Consider Cloud Storage for large files. ### Synchronous File Operations Severity: WARNING Sync file ops block the event loop in async apps Message: Synchronous file operations. Use async versions for better concurrency. ### Global Mutable State Severity: WARNING Global state issues with concurrent requests Message: Global mutable state may cause issues with concurrent requests. ### Thread-Unsafe Singleton Pattern Severity: WARNING Singletons need thread safety for concurrency > 1 Message: Singleton pattern - ensure thread safety if using concurrency > 1. ## Collaboration ### Delegation Triggers - user needs AWS serverless -> aws-serverless (Lambda, API Gateway, SAM)- user needs Azure containers -> azure-functions (Azure Container Apps, Functions)- user needs database design -> postgres-wizard (Cloud SQL design, AlloyDB)- user needs authentication -> auth-specialist (Firebase Auth, Identity Platform)- user needs AI integration -> llm-architect (Vertex AI, Cloud Run + LLM)- user needs workflow orchestration -> workflow-automation (Cloud Workflows, Eventarc) ## When to UseUse this skill when the request clearly matches the capabilities and patterns described above. ## Limitations- Use this skill only when the task clearly matches the scope described above.- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.