Google Cloud Run
Google Cloud Run is a fully managed serverless platform for containerized applications. It allows you to deploy stateless containers that scale automatically from zero to thousands of instances based on request load, paying only for the resources consumed. Choose Cloud Run for microservices, web APIs, and event-driven functions that require custom runtimes or environments.
You are an expert in deploying, operating, and scaling containerized applications on Google Cloud Run. You understand its serverless model, auto-scaling capabilities, and how to integrate it seamlessly with other Google Cloud services to build robust, cost-effective, and highly performant applications.
## Key Points
1. **Authenticate and set your project:**
2. **Enable Cloud Run API:**
3. **Create a simple containerized application (e.g., Node.js):**
4. **Create a `Dockerfile` for your application:**
5. **Build and push your container image to Google Container Registry (GCR) or Artifact Registry:**
6. **Deploy your service to Cloud Run:**
* **Build small, efficient containers:** Use multi-stage Docker builds to reduce image size, which speeds up deployments and cold start times. Choose minimal base images like Alpine.
* **Use Secret Manager:** Never hardcode secrets or environment variables directly in your `Dockerfile` or code. Use Google Secret Manager and mount secrets as files or environment variables.
* **Configure CPU allocation:** For background processing or CPU-intensive tasks, allocate CPU always-on (at a higher cost) instead of only during request processing, to avoid CPU throttling.
## Quick Example
```bash
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
```
```bash
gcloud services enable run.googleapis.com
```skilldb get deployment-hosting-services-skills/Google Cloud RunFull skill: 223 linesYou are an expert in deploying, operating, and scaling containerized applications on Google Cloud Run. You understand its serverless model, auto-scaling capabilities, and how to integrate it seamlessly with other Google Cloud services to build robust, cost-effective, and highly performant applications.
Core Philosophy
Google Cloud Run embraces a serverless, container-native approach to application deployment. It frees you from infrastructure management, letting you focus purely on your application logic by running any containerized workload without needing to provision or manage servers. Your services scale automatically and rapidly from zero instances when idle to handle peak traffic, ensuring optimal resource utilization and cost efficiency. You pay only for CPU, memory, and network resources consumed during request processing, making it incredibly cost-effective for variable workloads.
Cloud Run is ideal for stateless HTTP-triggered services like REST APIs, webhooks, and microservices. It's also excellent for event-driven applications when combined with services like Cloud Pub/Sub, Cloud Storage, or Cloud Scheduler. While it supports any language or runtime packaged in a container, it enforces a stateless model for individual requests and requires your application to listen for HTTP requests on a specific port. This platform strikes a balance between the flexibility of containers and the operational simplicity of serverless computing, making it a powerful choice for modern cloud-native architectures.
Setup
To get started with Cloud Run, you need the Google Cloud SDK (gcloud) and Docker installed.
-
Authenticate and set your project:
gcloud auth login gcloud config set project YOUR_PROJECT_ID -
Enable Cloud Run API:
gcloud services enable run.googleapis.com -
Create a simple containerized application (e.g., Node.js):
app.js:const express = require('express'); const app = express(); const port = process.env.PORT || 8080; app.get('/', (req, res) => { res.send('Hello from Cloud Run!'); }); app.listen(port, () => { console.log(`App listening on port ${port}`); });package.json:{ "name": "cloud-run-example", "version": "1.0.0", "description": "A simple Cloud Run service", "main": "app.js", "scripts": { "start": "node app.js" }, "dependencies": { "express": "^4.18.2" } } -
Create a
Dockerfilefor your application:# Use a lightweight Node.js base image FROM node:18-alpine # Create app directory WORKDIR /usr/src/app # Install app dependencies COPY package*.json ./ RUN npm install # Bundle app source COPY . . # Cloud Run expects the application to listen on the port specified by the PORT environment variable. # The default value is 8080, but it's good practice to explicitly use it. CMD [ "npm", "start" ] -
Build and push your container image to Google Container Registry (GCR) or Artifact Registry:
# For GCR (older, but widely used): gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/my-cloud-run-service . # For Artifact Registry (recommended new projects): # Enable Artifact Registry API: gcloud services enable artifactregistry.googleapis.com # Create a repository: gcloud artifacts repositories create my-repo --repository-format=docker --location=us-central1 # Build and push: # gcloud builds submit --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/my-repo/my-cloud-run-service . -
Deploy your service to Cloud Run:
gcloud run deploy my-cloud-run-service \ --image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \ --platform managed \ --region us-central1 \ --allow-unauthenticated \ --port 8080This command deploys your container, creates a new service, and makes it publicly accessible. The
--portflag ensures Cloud Run knows which port your application is listening on.
Key Techniques
1. Configuring Environment Variables and Secrets
Manage configuration and sensitive data without baking them into your image.
# Deploy with an environment variable
gcloud run deploy my-cloud-run-service \
--image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \
--set-env-vars ENV_VAR_NAME=my_value,ANOTHER_VAR=another_value \
--region us-central1
# Accessing secrets from Google Secret Manager
# 1. Store your secret:
# echo -n "my-db-password" | gcloud secrets create my-db-password --data-file=-
# 2. Grant Cloud Run service account access to the secret:
# gcloud secrets add-iam-policy-binding my-db-password \
# --member="serviceAccount:$(gcloud run services describe my-cloud-run-service --region us-central1 --format='value(spec.template.spec.serviceAccountName)')" \
# --role="roles/secretmanager.secretAccessor"
# 3. Mount the secret as an environment variable or file:
# As an environment variable (recommended for non-sensitive or small secrets)
gcloud run deploy my-cloud-run-service \
--image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \
--set-env-vars DB_PASSWORD=projects/YOUR_PROJECT_ID/secrets/my-db-password:latest \
--update-secrets DB_PASSWORD=my-db-password:latest \
--region us-central1
# As a file (recommended for sensitive data like private keys or larger configs)
# This mounts the secret to /run/secrets/my-db-password/latest
gcloud run deploy my-cloud-run-service \
--image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \
--update-secret-volumes DB_CREDENTIALS=/run/secrets/my-db-password:my-db-password \
--region us-central1
# In your app.js, you'd then read it:
// const dbPassword = process.env.DB_PASSWORD; // For env var
// const fs = require('fs');
// const dbPassword = fs.readFileSync('/run/secrets/my-db-password/latest', 'utf8'); // For file mount
2. Connecting to Private Network Resources (VPC Access Connector)
If your Cloud Run service needs to access resources in a private VPC network (like a Cloud SQL instance with private IP or a Redis instance in Memorystore), use a Serverless VPC Access Connector.
# 1. Create a VPC Access Connector (one-time setup per region/VPC)
# Choose a subnetwork that has enough available IPs for the connector.
gcloud compute networks vpc-access connectors create my-vpc-connector \
--region us-central1 \
--network default \
--range 10.8.0.0/28 # Or an unused range in your VPC
# 2. Deploy or update your Cloud Run service to use the connector
gcloud run deploy my-cloud-run-service \
--image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \
--vpc-connector my-vpc-connector \
--region us-central1 \
--ingress internal-and-cloud-load-balancing # Optional: restrict ingress for internal services
Your Cloud Run service's outbound traffic will now route through the specified VPC connector, allowing it to reach resources within your VPC.
3. Traffic Management with Revisions
Cloud Run automatically creates new revisions when you deploy changes. You can manage traffic distribution across these revisions for blue/green deployments, A/B testing, or rollbacks.
# Deploy a new revision (e.g., changing an env var)
gcloud run deploy my-cloud-run-service \
--image gcr.io/YOUR_PROJECT_ID/my-cloud-run-service \
--set-env-vars FEATURE_FLAG=true \
--no-traffic # Deploy without routing traffic to the new revision initially
--region us-central1
# List revisions for your service
gcloud run revisions list --service my-cloud-run-service --region us-central1
# Split traffic 50/50 between the latest (new) revision and the previous stable one
# Replace REV_NAME_OLD and REV_NAME_NEW with actual revision names from 'gcloud run revisions list'
gcloud run services update-traffic my-cloud-run-service \
--to-revisions REV_NAME_OLD=50,REV_NAME_NEW=50 \
--region us-central1
# Roll back to an older revision by routing 100% traffic to it
gcloud run services update-traffic my-cloud-run-service \
--to-latest --percent 0 \
--to-revision=REV_NAME_OLD=100 \
--region us-central1
# Route 100% traffic to the latest deployed revision
gcloud run services update-traffic my-cloud-run-service \
--to-latest \
--region us-central1
Best Practices
- Build small, efficient containers: Use multi-stage Docker builds to reduce image size, which speeds up deployments and cold start times. Choose minimal base images like Alpine.
- Implement graceful shutdown: Your application should handle
SIGTERMsignals to finish processing in-flight requests and clean up resources within the configured shutdown period (default 10 seconds). - Optimize for cold starts: Keep your application startup time minimal. Avoid heavy initialization logic outside of request handlers. Consider setting a minimum number of instances for latency-sensitive applications (though this increases cost).
- Handle concurrency: Cloud Run can send multiple concurrent requests to a single container instance. Design your application to be thread-safe and efficient with concurrent requests (default concurrency is 80).
- Use Secret Manager: Never hardcode secrets or environment variables directly in your
Dockerfileor code. Use Google Secret Manager and mount secrets as files or environment variables. - Configure CPU allocation: For background processing or CPU-intensive tasks, allocate CPU always-on (at a higher cost) instead of only during request processing, to avoid CPU throttling.
- Monitor and log comprehensively: Leverage Cloud Logging for application logs and Cloud Monitoring for metrics (request counts, latency, instance counts, CPU/memory usage). Export structured logs (JSON) for easier analysis.
Anti-Patterns
Monolithic containers. Avoid deploying multiple unrelated services or a large monolithic application within a single Cloud Run container. This defeats the microservices approach and can lead to inefficient scaling and resource allocation. Instead, containerize and deploy each microservice independently.
Ignoring graceful shutdown. Failing to implement proper SIGTERM handling can result in dropped requests and data loss when instances are scaled down or updated. Always ensure your application can gracefully shut down within the allocated time.
Hardcoding secrets. Storing API keys, database credentials, or other sensitive information directly in your code or container image is a severe security risk. Always use Google Secret Manager and inject secrets securely at deployment time.
Long-running background tasks. Cloud Run is designed for request-response cycles. Using it for tasks that run for many minutes or hours, or for tasks that don't respond to HTTP requests, is inefficient and costly. Use Cloud Tasks, Cloud Pub/Sub with Cloud Functions/Workers, or Cloud Workflows for such scenarios.
Unnecessary CPU always-on. Setting CPU to "always allocated" for services that are mostly idle or only process requests briefly can significantly increase costs without providing much benefit. Only use this for CPU-intensive background processing that needs consistent performance outside of request handling.
Install this skill directly: skilldb add deployment-hosting-services-skills
Related Skills
AWS Lightsail
AWS Lightsail provides a simplified way to launch virtual private servers (VPS), containers, databases, and more. It's ideal for developers and small businesses needing easy-to-use, cost-effective cloud resources without deep AWS expertise.
Cloudflare Pages Deployment
Cloudflare Pages and Workers expertise — edge-first deployments, full-stack apps with Workers functions, KV/D1/R2 bindings, preview URLs, custom domains, and global CDN distribution
Coolify Deployment
Coolify self-hosted PaaS expertise — Docker-based deployments, Git integration, automatic SSL, database provisioning, server management, and Heroku/Netlify alternative on your own hardware
Digital Ocean App Platform
DigitalOcean App Platform is a fully managed Platform-as-a-Service (PaaS) that allows you to quickly build, deploy, and scale web applications, static sites, APIs, and background services. It integrates seamlessly with other DigitalOcean services like Managed Databases and Spaces, making it ideal for developers seeking a streamlined, opinionated deployment experience within the DO ecosystem.
Fly.io Deployment
Fly.io platform expertise — container deployment, global edge distribution, Dockerfiles, volumes, secrets, scaling, PostgreSQL, and multi-region patterns
Kamal
Kamal (formerly MRSK) simplifies deploying web applications to servers via SSH, leveraging Docker and Traefik (or Caddy) for zero-downtime, rolling updates. It's ideal for containerized applications on a single server or small cluster without the complexity of Kubernetes.