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.
Add this skill
npx mdskills install sickn33/gcp-cloud-runComprehensive GCP serverless patterns with production-ready examples and cold start optimization
1---2name: gcp-cloud-run3description: "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."4source: vibeship-spawner-skills (Apache 2.0)5---67# GCP Cloud Run89## Patterns1011### Cloud Run Service Pattern1213Containerized web service on Cloud Run1415**When to use**: ['Web applications and APIs', 'Need any runtime or library', 'Complex services with multiple endpoints', 'Stateless containerized workloads']1617```javascript18```dockerfile19# Dockerfile - Multi-stage build for smaller image20FROM node:20-slim AS builder21WORKDIR /app22COPY package*.json ./23RUN npm ci --only=production2425FROM node:20-slim26WORKDIR /app2728# Copy only production dependencies29COPY --from=builder /app/node_modules ./node_modules30COPY src ./src31COPY package.json ./3233# Cloud Run uses PORT env variable34ENV PORT=808035EXPOSE 80803637# Run as non-root user38USER node3940CMD ["node", "src/index.js"]41```4243```javascript44// src/index.js45const express = require('express');46const app = express();4748app.use(express.json());4950// Health check endpoint51app.get('/health', (req, res) => {52 res.status(200).send('OK');53});5455// API routes56app.get('/api/items/:id', async (req, res) => {57 try {58 const item = await getItem(req.params.id);59 res.json(item);60 } catch (error) {61 console.error('Error:', error);62 res.status(500).json({ error: 'Internal server error' });63 }64});6566// Graceful shutdown67process.on('SIGTERM', () => {68 console.log('SIGTERM received, shutting down gracefully');69 server.close(() => {70 console.log('Server closed');71 process.exit(0);72 });73});7475const PORT = process.env.PORT || 8080;76const server = app.listen(PORT, () => {77 console.log(`Server listening on port ${PORT}`);78});79```8081```yaml82# cloudbuild.yaml83steps:84 # Build the container image85 - name: 'gcr.io/cloud-builders/docker'86 args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA', '.']8788 # Push the container image89 - name: 'gcr.io/cloud-builders/docker'90 args: ['push', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA']9192 # Deploy to Cloud Run93 - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'94 entrypoint: gcloud95 args:96 - 'run'97 - 'deploy'98 - 'my-service'99 - '--image=gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA'100 - '--region=us-central1'101 - '--platform=managed'102 - '--allow-unauthenticated'103 - '--memory=512Mi'104 - '--cpu=1'105 - '--min-instances=1'106 - '--max-instances=100'107108```109110### Cloud Run Functions Pattern111112Event-driven functions (formerly Cloud Functions)113114**When to use**: ['Simple event handlers', 'Pub/Sub message processing', 'Cloud Storage triggers', 'HTTP webhooks']115116```javascript117```javascript118// HTTP Function119// index.js120const functions = require('@google-cloud/functions-framework');121122functions.http('helloHttp', (req, res) => {123 const name = req.query.name || req.body.name || 'World';124 res.send(`Hello, ${name}!`);125});126```127128```javascript129// Pub/Sub Function130const functions = require('@google-cloud/functions-framework');131132functions.cloudEvent('processPubSub', (cloudEvent) => {133 // Decode Pub/Sub message134 const message = cloudEvent.data.message;135 const data = message.data136 ? JSON.parse(Buffer.from(message.data, 'base64').toString())137 : {};138139 console.log('Received message:', data);140141 // Process message142 processMessage(data);143});144```145146```javascript147// Cloud Storage Function148const functions = require('@google-cloud/functions-framework');149150functions.cloudEvent('processStorageEvent', async (cloudEvent) => {151 const file = cloudEvent.data;152153 console.log(`Event: ${cloudEvent.type}`);154 console.log(`Bucket: ${file.bucket}`);155 console.log(`File: ${file.name}`);156157 if (cloudEvent.type === 'google.cloud.storage.object.v1.finalized') {158 await processUploadedFile(file.bucket, file.name);159 }160});161```162163```bash164# Deploy HTTP function165gcloud functions deploy hello-http \166 --gen2 \167 --runtime nodejs20 \168 --trigger-http \169 --allow-unauthenticated \170 --region us-central1171172# Deploy Pub/Sub function173gcloud functions deploy process-messages \174 --gen2 \175 --runtime nodejs20 \176 --trigger-topic my-topic \177 --region us-central1178179# Deploy Cloud Storage function180gcloud functions deploy process-uploads \181 --gen2 \182 --runtime nodejs20 \183 --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \184 --trigger-event-filters="bucket=my-bucket" \185 --region us-central1186```187```188189### Cold Start Optimization Pattern190191Minimize cold start latency for Cloud Run192193**When to use**: ['Latency-sensitive applications', 'User-facing APIs', 'High-traffic services']194195```javascript196## 1. Enable Startup CPU Boost197198```bash199gcloud run deploy my-service \200 --cpu-boost \201 --region us-central1202```203204## 2. Set Minimum Instances205206```bash207gcloud run deploy my-service \208 --min-instances 1 \209 --region us-central1210```211212## 3. Optimize Container Image213214```dockerfile215# Use distroless for minimal image216FROM node:20-slim AS builder217WORKDIR /app218COPY package*.json ./219RUN npm ci --only=production220221FROM gcr.io/distroless/nodejs20-debian12222WORKDIR /app223COPY --from=builder /app/node_modules ./node_modules224COPY src ./src225CMD ["src/index.js"]226```227228## 4. Lazy Initialize Heavy Dependencies229230```javascript231// Lazy load heavy libraries232let bigQueryClient = null;233234function getBigQueryClient() {235 if (!bigQueryClient) {236 const { BigQuery } = require('@google-cloud/bigquery');237 bigQueryClient = new BigQuery();238 }239 return bigQueryClient;240}241242// Only initialize when needed243app.get('/api/analytics', async (req, res) => {244 const client = getBigQueryClient();245 const results = await client.query({...});246 res.json(results);247});248```249250## 5. Increase Memory (More CPU)251252```bash253# Higher memory = more CPU during startup254gcloud run deploy my-service \255 --memory 1Gi \256 --cpu 2 \257 --region us-central1258```259```260261## Anti-Patterns262263### ❌ CPU-Intensive Work Without Concurrency=1264265**Why bad**: CPU is shared across concurrent requests. CPU-bound work266will starve other requests, causing timeouts.267268### ❌ Writing Large Files to /tmp269270**Why bad**: /tmp is an in-memory filesystem. Large files consume271your memory allocation and can cause OOM errors.272273### ❌ Long-Running Background Tasks274275**Why bad**: Cloud Run throttles CPU to near-zero when not handling276requests. Background tasks will be extremely slow or stall.277278## ⚠️ Sharp Edges279280| Issue | Severity | Solution |281|-------|----------|----------|282| Issue | high | ## Calculate memory including /tmp usage |283| Issue | high | ## Set appropriate concurrency |284| Issue | high | ## Enable CPU always allocated |285| Issue | medium | ## Configure connection pool with keep-alive |286| Issue | high | ## Enable startup CPU boost |287| Issue | medium | ## Explicitly set execution environment |288| Issue | medium | ## Set consistent timeouts |289
Full transparency — inspect the skill content before installing.