### Repository Directory Structure Example Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/CONTRIBUTING.md Illustrates the recommended directory layout for sample applications within the repository, including sub-directories for platform-specific code. ```bash .\nsample-app\n├── managed\n└── anthos ``` -------------------------------- ### Lazy Initialization of Globals (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates lazy initialization of global variables in a Python application for Cloud Run. This can improve cold start times by deferring setup tasks. ```python from flask import Flask import time import os app = Flask(__name__) lazy_initialized_value = None initialized = False def initialize_lazy_value(): global lazy_initialized_value, initialized print("Initializing lazy value...") # Simulate a time-consuming initialization time.sleep(2) lazy_initialized_value = "This value was initialized lazily." initialized = True print("Lazy value initialized.") @app.route('/') def index(): if not initialized: initialize_lazy_value() return "Initialization pending..." return lazy_initialized_value if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Deploy a service with gcloud Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/test-cases/test-markdown.md Use the gcloud CLI to deploy a service to Cloud Run. Ensure you have the gcloud CLI installed and authenticated. ```bash $ gcloud run deploy ``` -------------------------------- ### Manual Logging in Cloud Run (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Provides an example of manual logging within a Cloud Run service using Java. Logs are typically directed to System.out or System.err. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class LoggingApplication { public static void main(String[] args) { SpringApplication.run(LoggingApplication.class, args); } @GetMapping("/") public String hello() { System.out.println("Hello, world!"); return "Hello, world!"; } } ``` -------------------------------- ### Enable Required APIs Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/multi-container/hello-nginx-sample/README.md Enables the Cloud Run and Secret Manager APIs for your Google Cloud project. Run this command before proceeding with other setup steps. ```bash gcloud services enable secretmanager.googleapis.com run.googleapis.com ``` -------------------------------- ### Dockerfile for GPU-accelerated FFmpeg on Cloud Run Jobs Source: https://context7.com/googlecloudplatform/cloud-run-samples/llms.txt This Dockerfile sets up an environment for GPU-accelerated video transcoding using FFmpeg with NVENC on Cloud Run Jobs. It includes build and runtime stages with CUDA tools and installs FFmpeg with necessary codecs. The entrypoint script executes the transcoding process. ```dockerfile # Dockerfile - GPU-accelerated FFmpeg for Cloud Run Jobs # Build stage with CUDA development tools FROM nvidia/cuda:12.1.0-devel-ubuntu22.04 AS builder WORKDIR /workspace # Build FFmpeg with NVENC support RUN apt-get update && apt-get install -y build-essential cmake git pkg-config yasm nasm \ libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev RUN git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && \ cd nv-codec-headers && git checkout n12.1.14.0 && make install RUN git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg --depth 1 && \ cd ffmpeg && ./configure \ --enable-gpl --enable-version3 --enable-nonfree \ --enable-cuda-nvcc --enable-cuvid --enable-nvenc --enable-nvdec \ --extra-cflags=-I/usr/local/cuda/include \ --extra-ldflags=-L/usr/local/cuda/lib64 && \ make -j "$(nproc)" && make install # Runtime stage with CUDA runtime FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04 ENV NVIDIA_VISIBLE_DEVICES=all ENV NVIDIA_DRIVER_CAPABILITIES=compute,video,utility COPY --from=builder /usr/local /usr/local COPY entrypoint.sh . RUN chmod +x entrypoint.sh ENTRYPOINT ["./entrypoint.sh"] # entrypoint.sh example: # #!/bin/bash # ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc -preset fast output.mp4 ``` -------------------------------- ### Manually Start Cloud Run for Anthos Build Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md Manually triggers a Cloud Build for a Cloud Run for Anthos deployment via the CLI. Navigate to the sample directory first. ```sh cd $SAMPLE gcloud builds submit --substitutions 'SHORT_SHA=manual,_SAMPLE_DIR=.' ``` -------------------------------- ### Lazy Initialization of Globals (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows lazy initialization of global variables in a Java application for Cloud Run. This can optimize startup performance by delaying resource-intensive setup. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class GlobalLazyApplication { private static String lazyInitializedValue; private static boolean initialized = false; private static final Object lock = new Object(); private static void initializeLazyValue() { System.out.println("Initializing lazy value..."); // Simulate a time-consuming initialization try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } lazyInitializedValue = "This value was initialized lazily."; initialized = true; System.out.println("Lazy value initialized."); } public static void main(String[] args) { SpringApplication.run(GlobalLazyApplication.class, args); } @GetMapping("/") public String hello() { if (!initialized) { synchronized (lock) { if (!initialized) { // Double-checked locking initializeLazyValue(); } } } return lazyInitializedValue; } } ``` -------------------------------- ### Set Artifact Registry Repository Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/jobs-shell/README.md Configure the AR_REPO_NAME environment variable for your Artifact Registry. Example uses 'containers' in us-central1. ```bash export AR_REPO_NAME=us-central1-pkg.dev/${PROJECT_ID}/containers ``` -------------------------------- ### Lazy Initialization of Globals (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows lazy initialization of global variables in a Node.js application for Cloud Run. This can optimize startup time by delaying resource-intensive setup. ```javascript const express = require('express'); const app = express(); let lazyInitializedValue = null; let isInitialized = false; function initializeLazyValue() { console.log('Initializing lazy value...'); // Simulate a time-consuming initialization setTimeout(() => { lazyInitializedValue = 'This value was initialized lazily.'; isInitialized = true; console.log('Lazy value initialized.'); }, 2000); } app.get('/', (req, res) => { if (!isInitialized) { initializeLazyValue(); // Wait for initialization to complete (in a real app, use Promises or async/await) // For this example, we'll just return a pending message. return res.send('Initialization pending...'); } res.send(lazyInitializedValue); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Create Nightly Trigger Config Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md Defines a Cloud Build trigger configuration for nightly builds. This example uses a push event on a specific branch as a workaround for manual trigger creation. ```yaml name: SAMPLE-nightly description: nightly github: name: cloud-run-samples owner: GoogleCloudPlatform push: # TODO: Update when manual triggers are supported branch: nightly includedFiles: - SAMPLE_DIR/** filename: SAMPLE_DIR/cloudbuild.yaml ``` -------------------------------- ### Manually Start Cloud Run (fully managed) Build Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md Manually triggers a Cloud Build for a Cloud Run (fully managed) deployment using the `gcloud builds submit` command. Ensure you are in the repository's base directory. ```sh $SAMPLE=sample-name gcloud builds submit \ --config "$SAMPLE/tests.cloudbuild.yaml" \ --substitutions "SHORT_SHA=manual,_SAMPLE_DIR=${SAMPLE},_SECRET_NAME=${SECRET_NAME},_RUNNER_IDENTITY=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" ``` -------------------------------- ### Multi-Container Nginx Sidecar Deployment Source: https://context7.com/googlecloudplatform/cloud-run-samples/llms.txt This YAML defines a multi-container Cloud Run service using Nginx as a reverse proxy sidecar. It demonstrates container dependencies, secret mounting, and specifies that the 'hello' container must start before 'nginx'. ```yaml # service.yaml - Multi-container Cloud Run service apiVersion: serving.knative.dev/v1 kind: Service metadata: name: "MC_SERVICE_NAME" labels: cloud.googleapis.com/location: "REGION" annotations: run.googleapis.com/launch-stage: BETA run.googleapis.com/ingress: all spec: template: metadata: annotations: # Container startup order: hello must start before nginx run.googleapis.com/container-dependencies: "{nginx: [hello]}" spec: containers: # Nginx ingress container on port 8080 - image: nginx name: nginx ports: - name: http1 containerPort: 8080 resources: limits: cpu: 500m memory: 256Mi volumeMounts: - name: nginx-conf-secret readOnly: true mountPath: /etc/nginx/conf.d/ # Hello sidecar container on port 8888 - image: us-docker.pkg.dev/cloudrun/container/hello name: hello env: - name: PORT value: "8888" resources: limits: cpu: 1000m memory: 512Mi volumes: - name: nginx-conf-secret secret: secretName: nginx_config items: - key: latest path: default.conf # nginx.conf (stored in Secret Manager as nginx_config) # server { # listen 8080; # server_name _; # gzip on; # location / { # proxy_pass http://127.0.0.1:8888; # } # } # Setup and deploy: # gcloud secrets create nginx_config --replication-policy="automatic" --data-file="./nginx.conf" # gcloud run services replace service.yaml ``` -------------------------------- ### Authentication in Cloud Run (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates how to handle authentication for a Cloud Run service using Go. This sample might involve verifying ID tokens. ```go package main import ( "fmt" "log" "net/http" "os" // Import the Google Auth library for ID token verification "google.golang.org/api/idtoken" ) func main() { http.HandleFunc("/", authMiddleware(helloHandler)) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } func helloHandler(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value("claims").(*idtoken.Claims) fmt.Fprintf(w, "Hello, %s!", claims.Subject) } func authMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Get the ID token from the Authorization header authHeader := r.Header.Get("Authorization") if authHeader == "" { http.Error(w, "Authorization header missing", http.StatusUnauthorized) return } // Expecting "Bearer " token := strings.TrimPrefix(authHeader, "Bearer ") if token == authHeader { http.Error(w, "Invalid Authorization header format", http.StatusUnauthorized) return } // Verify the ID token payload, err := idtoken.Validate(r.Context(), token, os.Getenv("GOOGLE_AUDIENCE")) // Use your Cloud Run service URL as audience if err != nil { http.Error(w, fmt.Sprintf("Failed to validate ID token: %v", err), http.StatusUnauthorized) return } // Add claims to the request context r = r.WithContext(context.WithValue(r.Context(), "claims", payload)) next.ServeHTTP(w, r) } } ``` -------------------------------- ### System Package in Cloud Run (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Illustrates how to use system packages within a Cloud Run service written in Go. This sample might involve specific build configurations or dependencies. ```go package main import ( "fmt" "log" "net/http" "os/exec" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { cmd := exec.Command("echo", "Hello from system package!") output, err := cmd.CombinedOutput() if err != nil { log.Printf("Command error: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintf(w, "Output: %s", output) }) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil)) } ``` -------------------------------- ### Pub/Sub Integration in Cloud Run (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to integrate Cloud Run services with Google Cloud Pub/Sub using Go. This sample typically involves setting up a push subscription to trigger your service. ```go package main import ( "encoding/json" "fmt" "log" "net/http" "os" ) type PubSubMessage struct { Message struct { Data []byte `json:"data,omitempty"` ID string `json:"messageId,omitempty"` } `json:"message,omitempty"` Subscription string `json:"subscription,omitempty"` } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { var m PubSubMessage err := json.NewDecoder(r.Body).Decode(&m) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } log.Printf("Received message: %s", string(m.Message.Data)) w.WriteHeader(http.StatusOK) }) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } ``` -------------------------------- ### Pub/Sub Integration in Cloud Run (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates integrating Cloud Run services with Google Cloud Pub/Sub using Java. This sample usually involves setting up a push subscription to invoke your service. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @SpringBootApplication @RestController public class PubSubApplication { public static void main(String[] args) { SpringApplication.run(PubSubApplication.class, args); } @PostMapping public void handlePubSubMessage(@RequestBody Map payload) { if (payload.containsKey("message") && payload.get("message") instanceof Map) { @SuppressWarnings("unchecked") Map message = (Map) payload.get("message"); if (message.containsKey("data") && message.get("data") instanceof String) { String data = (String) message.get("data"); String decodedData = new String(java.util.Base64.getDecoder().decode(data)); System.out.println("Received message: " + decodedData); } else { System.out.println("Received message without data field."); } } else { System.out.println("Received invalid payload format."); } } } ``` -------------------------------- ### Connect to Cloud SQL PostgreSQL (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates connecting to a Cloud SQL PostgreSQL instance from a Node.js application on Cloud Run. This sample uses the `knex` library for database operations. ```javascript const express = require('express'); const knex = require('knex'); const app = express(); // Configure your database connection using Knex const db = knex({ client: 'pg', connection: { user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, // For Cloud SQL, use the Cloud SQL Node.js library for connection pooling // or connect via the instance socket if running on the same VPC network. // Example using socket path (ensure socket is available): // host: process.env.DB_SOCKET_PATH } }); app.get('/', async (req, res) => { try { const result = await db.raw('SELECT NOW()'); res.send(`Database time: ${result.rows[0].now}`); } catch (err) { console.error('Database query failed:', err); res.status(500).send('Database query failed.'); } }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Lazy Initialization of Globals (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates lazy initialization of global variables in a Go application for Cloud Run. This can improve startup performance by deferring expensive initializations. ```go package main import ( "fmt" "log" "net/http" "os" "sync" ) var ( lazyInitializedValue string initOnce sync.Once ) func initializeLazyValue() { log.Println("Initializing lazy value...") // Simulate a time-consuming initialization time.Sleep(2 * time.Second) lazyInitializedValue = "This value was initialized lazily." log.Println("Lazy value initialized.") } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { initOnce.Do(initializeLazyValue) // Ensure initialization happens only once fmt.Fprintf(w, lazyInitializedValue) }) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } ``` -------------------------------- ### Hello World Shell Service in Go Source: https://context7.com/googlecloudplatform/cloud-run-samples/llms.txt An HTTP server in Go that executes a bash script on each request, demonstrating the shell-script-as-a-service pattern. The script.sh file is executed by the Go program. ```go // invoke.go - HTTP server that executes shell scripts package main import ( "log" "net/http" "os" "os/exec" ) func main() { http.HandleFunc("/", scriptHandler) port := os.Getenv("PORT") if port == "" { port = "8080" } log.Printf("Listening on port %s", port) log.Fatal(http.ListenAndServe(": ``` ```bash #!/bin/bash set -e echo "Hello ${NAME:-World}!" ``` -------------------------------- ### Global State Management (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Illustrates how to manage global state in a Go application deployed on Cloud Run. Be cautious with mutable global state in concurrent environments. ```go package main import ( "fmt" "net/http" "os" "sync" ) var ( counter int mutex sync.Mutex ) func main() { http.HandleFunc("/increment", incrementHandler) http.HandleFunc("/count", countHandler) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } func incrementHandler(w http.ResponseWriter, r *http.Request) { mutex.Lock() counter++ mutex.Unlock() fmt.Fprintf(w, "Counter incremented.") } func countHandler(w http.ResponseWriter, r *http.Request) { mutex.Lock() currentCount := counter mutex.Unlock() fmt.Fprintf(w, "Current count: %d", currentCount) } ``` -------------------------------- ### Connect to Cloud SQL MySQL (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates how to connect to a Cloud SQL MySQL instance from a Node.js application running on Cloud Run. This sample uses the `mysql` package. ```javascript const express = require('express'); const mysql = require('mysql'); const app = express(); // Configure your database connection const connection = mysql.createConnection({ user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, // For Cloud SQL, use the Cloud SQL Node.js library for connection pooling // or connect via the instance socket if running on the same VPC network. // Example using socket path (ensure socket is available): // socketPath: process.env.DB_SOCKET_PATH }); connection.connect((err) => { if (err) { console.error('Error connecting to database:', err); return; } console.log('Connected to database.'); }); app.get('/', (req, res) => { connection.query('SELECT NOW() as now', (error, results, fields) => { if (error) { console.error('Error querying database:', error); return res.status(500).send('Database query failed.'); } res.send(`Database time: ${results[0].now}`); }); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### System Package in Cloud Run (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates the use of system packages within a Cloud Run service implemented in Java. This sample might require specific configurations for external command execution. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.BufferedReader; import java.io.InputStreamReader; @SpringBootApplication @RestController public class SystemPackageApplication { public static void main(String[] args) { SpringApplication.run(SystemPackageApplication.class, args); } @GetMapping("/") public String hello() { try { Process process = Runtime.getRuntime().exec("echo Hello from system package!"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder output = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { output.append(line); } process.waitFor(); return "Output: " + output.toString(); } catch (Exception e) { e.printStackTrace(); return "Error executing command"; } } } ``` -------------------------------- ### Authentication in Cloud Run (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates how to handle authentication for a Cloud Run service using Java. This sample might involve verifying ID tokens using the Google Auth library. ```java import com.google.auth.oauth2.IdTokenVerifier; import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.ServiceOptions; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.security.GeneralSecurityException; @WebServlet("/*") public class AuthenticationServlet extends HttpServlet { private static final long serialVersionUID = 1L; private IdTokenVerifier idTokenVerifier; @Override public void init() { try { // Use your Cloud Run service URL as the audience String audience = System.getenv("GOOGLE_AUDIENCE"); idTokenVerifier = IdTokenVerifier.newBuilder().setAudience(audience).build(); } catch (GeneralSecurityException e) { throw new RuntimeException("Failed to initialize IdTokenVerifier", e); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); PrintWriter out = resp.getWriter(); String authHeader = req.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); out.println("Authorization header missing or invalid."); return; } String idToken = authHeader.substring(7); try { com.google.auth.oauth2.IdToken token = idtokenVerifier.verify(idToken); String userId = token.getClaims().getSubject(); out.println("Hello, " + userId + "!"); resp.setStatus(HttpServletResponse.SC_OK); } catch (Exception e) { resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); out.println("Failed to verify ID token: " + e.getMessage()); } } } ``` -------------------------------- ### Pub/Sub Integration in Cloud Run (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates integrating Cloud Run with Google Cloud Pub/Sub using Node.js. This sample usually involves setting up a push subscription to invoke your service. ```javascript const express = require('express'); const app = express(); app.use(express.json()); app.post('/', (req, res) => { const message = req.body.message; if (!message || !message.data) { return res.status(400).send('Bad Request: missing message data'); } const data = Buffer.from(message.data, 'base64').toString(); console.log(`Received message: ${data}`); res.status(200).send('Message received'); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Hello Broken Sample (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md A sample Cloud Run application in Go that intentionally returns an error. Useful for testing error handling and retry mechanisms. ```go package main import ( "fmt" "log" "net/http" "os" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { log.Println("Returning an error.") http.Error(w, "Intentional error", http.StatusInternalServerError) }) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } ``` -------------------------------- ### Connect to Cloud SQL MySQL (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to connect to a Cloud SQL MySQL instance from a Java application on Cloud Run. This sample uses JDBC with a servlet. ```java import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; @WebServlet("/") public class MySqlServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); PrintWriter out = resp.getWriter(); String dbUser = System.getProperty("cloudsql.user"); String dbPassword = System.getProperty("cloudsql.password"); String dbName = System.getProperty("cloudsql.database"); String instanceConnectionName = System.getProperty("cloudsql.instances"); String url = String.format("jdbc:mysql:///%s?cloudSqlInstance=%s&socketFactory=com.google.cloud.sql.netty.NettySocketFactory", dbName, instanceConnectionName); try (Connection conn = DriverManager.getConnection(url, dbUser, dbPassword)) { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT NOW() as now"); rs.next(); out.println("Database time: " + rs.getString("now")); } catch (Exception e) { e.printStackTrace(out); } } } ``` -------------------------------- ### Pub/Sub Integration in Cloud Run (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to connect Cloud Run services with Google Cloud Pub/Sub using Python. This typically involves configuring a push subscription to trigger your service. ```python from flask import Flask import base64 app = Flask(__name__) @app.route('/', methods=['POST']) def index(): envelope = request.get_json() if not envelope: msg = 'no Pub/Sub message received' print(f"error processing request: {msg}") return ('Bad Request: No Pub/Sub message received', 400) if not isinstance(envelope, dict) or 'message' not in envelope: msg = 'invalid Pub/Sub message format' print(f"error processing request: {msg}") return ('Bad Request: Invalid Pub/Sub message format', 400) pubsub_message = envelope['message'] if isinstance(pubsub_message, dict) and 'data' in pubsub_message: data = base64.b64decode(pubsub_message['data']).decode('utf-8') print(f"Received message: {data}") else: print("Received message without data") return ('OK', 200) if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Connect to Cloud SQL MySQL (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to connect to a Cloud SQL MySQL instance from a Python application on Cloud Run. This sample uses SQLAlchemy. ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy import os app = Flask(__name__) # Configure your database connection # Example using Cloud SQL Python Connector: # db_user = os.environ.get('DB_USER') # db_pass = os.environ.get('DB_PASS') # db_name = os.environ.get('DB_NAME') # instance_connection_name = os.environ.get('INSTANCE_CONNECTION_NAME') # app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+mysqlconnector://{db_user}:{db_pass}@127.0.0.1:3306/{db_name}?unix_socket=/cloudsql/{instance_connection_name}' # Example using direct connection (ensure network connectivity): app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) @app.route('/') def index(): try: # Example query user = User.query.first() if user: return f'Hello, {user.name}!' else: # Create a dummy user if none exist new_user = User(name='Cloud Run User') db.session.add(new_user) db.session.commit() return 'Created a new user. Please refresh.' except Exception as e: return f'An error occurred: {str(e)}' if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Connect to Cloud SQL PostgreSQL (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to connect to a Cloud SQL PostgreSQL instance from a Java application on Cloud Run. This sample uses JDBC with a servlet. ```java import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; @WebServlet("/") public class PostgresServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); PrintWriter out = resp.getWriter(); String dbUser = System.getProperty("cloudsql.user"); String dbPassword = System.getProperty("cloudsql.password"); String dbName = System.getProperty("cloudsql.database"); String instanceConnectionName = System.getProperty("cloudsql.instances"); String url = String.format("jdbc:postgresql:///%s?cloudSqlInstance=%s&socketFactory=com.google.cloud.sql.postgres.SocketFactory", dbName, instanceConnectionName); try (Connection conn = DriverManager.getConnection(url, dbUser, dbPassword)) { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT NOW() as now"); rs.next(); out.println("Database time: " + rs.getString("now")); } catch (Exception e) { e.printStackTrace(out); } } } ``` -------------------------------- ### Run Integration Tests with Shell Script Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md Use this Cloud Build step to run integration tests defined in a shell script within the sample's directory. It requires the service URL to be available. ```yaml - id: 'Integration Tests' name: 'gcr.io/cloud-builders/curl' entrypoint: '/bin/sh' dir: $_SAMPLE args: - '-c' - | SERVICE_URL=$(cat _service_url) sh integration-tests.sh ``` -------------------------------- ### Manual Logging in Cloud Run (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Demonstrates how to implement manual logging in a Cloud Run service using Python. Ensure your application is configured to send logs to standard output or standard error. ```python from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): print('Hello, world!') return 'Hello, world!' if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080))) ``` -------------------------------- ### Connect to Cloud SQL PostgreSQL (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to connect to a Cloud SQL PostgreSQL instance from a Python application on Cloud Run. This sample uses SQLAlchemy. ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy import os app = Flask(__name__) # Configure your database connection # Example using Cloud SQL Python Connector: # db_user = os.environ.get('DB_USER') # db_pass = os.environ.get('DB_PASS') # db_name = os.environ.get('DB_NAME') # instance_connection_name = os.environ.get('INSTANCE_CONNECTION_NAME') # app.config['SQLALCHEMY_DATABASE_URI'] = f'postgresql+psycopg2://{db_user}:{db_pass}@/localhost:5432/{db_name}?host=/cloudsql/{instance_connection_name}' # Example using direct connection (ensure network connectivity): app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('SQLALCHEMY_DATABASE_URI') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class Item(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) @app.route('/') def index(): try: # Example query item = Item.query.first() if item: return f'Found item: {item.name}' else: # Create a dummy item if none exist new_item = Item(name='Cloud Run Item') db.session.add(new_item) db.session.commit() return 'Created a new item. Please refresh.' except Exception as e: return f'An error occurred: {str(e)}' if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Image Processing in Cloud Run (Go) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Provides a sample for image processing within a Cloud Run service using Go. This might involve using libraries to manipulate images upon request. ```go package main import ( "fmt" "image" "image/color" "image/png" "log" "net/http" "os" "path/filepath" "strings" _ "image/jpeg" _ "image/png" ) func main() { http.HandleFunc("/", handler) port := "8080" if p := os.Getenv("PORT"); p != "" { port = p } log.Printf("Listening on port %s", port) http.ListenAndServe(":"+port, nil) } func handler(w http.ResponseWriter, r *http.Request) { file, _, err := r.FormFile("image") if err != nil { if err == http.ErrMissingFile { http.Error(w, "Please upload an image", http.StatusBadRequest) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } defer file.Close() contentType := r.Header.Get("Content-Type") if !strings.HasPrefix(contentType, "image/") { http.Error(w, "Invalid content type. Expected image/*", http.StatusBadRequest) return } img, format, err := image.Decode(file) if err != nil { http.Error(w, "Could not decode image", http.StatusBadRequest) return } log.Printf("Decoded image format: %s", format) bounds := img.Bounds() newImg := image.NewRGBA(bounds) for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { newImg.Set(x, y, color.Gray128Model.Convert(img.At(x, y))) } } w.Header().Set("Content-Type", "image/png") png.Encode(w, newImg) } ``` -------------------------------- ### Hello Broken Sample (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md A sample Cloud Run application in Java that intentionally returns an error. Useful for testing error handling and retry mechanisms. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class HelloBrokenApplication { public static void main(String[] args) { SpringApplication.run(HelloBrokenApplication.class, args); } @GetMapping("/") public ResponseEntity hello() { System.out.println("Returning an error."); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Intentional error"); } } ``` -------------------------------- ### Hello Broken Sample (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md A sample Cloud Run application in Python that intentionally returns an error. Useful for testing error handling and retry mechanisms. ```python from flask import Flask, Response import os app = Flask(__name__) @app.route('/') def hello_world(): print('Returning an error.') return Response('Intentional error', status=500) if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Global State Management (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Illustrates managing global state in a Java application on Cloud Run. Be mindful of thread safety when accessing shared variables. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.atomic.AtomicInteger; @SpringBootApplication @RestController public class GlobalStateApplication { // Use AtomicInteger for thread-safe increment and retrieval private static final AtomicInteger counter = new AtomicInteger(0); public static void main(String[] args) { SpringApplication.run(GlobalStateApplication.class, args); } @GetMapping("/increment") public String increment() { int currentCount = counter.incrementAndGet(); return "Counter incremented to " + currentCount; } @GetMapping("/count") public String count() { return "Current count: " + counter.get(); } } ``` -------------------------------- ### Image Processing in Cloud Run (Java) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Offers a sample for image processing in a Cloud Run service using Java. This might involve using libraries like `javax.imageio` or external dependencies for image manipulation. ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; @SpringBootApplication @RestController public class ImageProcessingApplication { public static void main(String[] args) { SpringApplication.run(ImageProcessingApplication.class, args); } @PostMapping public String processImage(@RequestParam("image") MultipartFile file) { try { BufferedImage image = ImageIO.read(file.getInputStream()); if (image == null) { return "Error: Could not read image."; } BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY); Graphics2D g = grayImage.createGraphics(); g.drawImage(image, 0, 0, Color.WHITE, null); g.dispose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(grayImage, "png", baos); byte[] pngBytes = baos.toByteArray(); // In a real application, you would return these bytes as a response. // For simplicity, returning a success message. return "Image processed successfully. Grayscale image generated. Size: " + pngBytes.length + " bytes."; } catch (Exception e) { e.printStackTrace(); return "Error processing image: " + e.getMessage(); } } } ``` -------------------------------- ### System Package in Cloud Run (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to utilize system packages in a Cloud Run service developed with Node.js. This may require specific dependency management or execution environments. ```javascript const express = require('express'); const { exec } = require('child_process'); const app = express(); app.get('/', (req, res) => { exec('echo "Hello from system package!"', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return res.status(500).send('Error executing command'); } res.send(`Output: ${stdout}`); }); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Global State Management (Python) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Shows how to manage global state in a Python application on Cloud Run. Consider the implications of shared mutable state across requests. ```python from flask import Flask import os app = Flask(__name__) # Global variable to store state counter = 0 @app.route('/increment') def increment(): global counter counter += 1 return f'Counter incremented to {counter}' @app.route('/count') def count(): return f'Current count: {counter}' if __name__ == '__main__': port = int(os.environ.get('PORT', 8080)) app.run(host='0.0.0.0', port=port) ``` -------------------------------- ### Hello Broken Sample (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md A sample Cloud Run application in Node.js that intentionally returns an error. Useful for testing error handling and retry mechanisms. ```javascript const express = require('express'); const app = express(); app.get('/', (req, res) => { console.log('Returning an error.'); res.status(500).send('Intentional error'); }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Build and Deploy Cloud Run Service with Cloud Build Source: https://context7.com/googlecloudplatform/cloud-run-samples/llms.txt This Cloud Build configuration automates the process of building a Docker container, pushing it to a registry, deploying it to Cloud Run, and performing integration tests. ```yaml steps: - id: 'Build Container' name: 'gcr.io/cloud-builders/docker:latest' args: ['build', '-t', 'gcr.io/$PROJECT_ID/${_SAMPLE}', '.'] - id: 'Push Container' name: 'gcr.io/cloud-builders/docker:latest' args: ['push', 'gcr.io/$PROJECT_ID/${_SAMPLE}'] - id: 'Deploy to Cloud Run' name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:latest' entrypoint: 'gcloud' args: - 'run' - 'deploy' - '${_SERVICE}' - '--image=gcr.io/$PROJECT_ID/${_SAMPLE}' - '--region=${_REGION}' - '--no-allow-unauthenticated' - id: 'Get Service URL' name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:latest' entrypoint: 'bash' args: - '-c' - | gcloud run services describe ${_SERVICE} --region ${_REGION} \ --format 'value(status.url)' > _service_url # Get identity token for authenticated requests gcloud auth print-identity-token --audiences "$(cat _service_url)" > _id_token - id: 'Integration Tests' name: 'gcr.io/cloud-builders/curl' entrypoint: '/bin/sh' args: - '-c' - | SERVICE_URL=$(cat _service_url) ID_TOKEN=$(cat _id_token) curl -H "Authorization: Bearer ${ID_TOKEN}" ${SERVICE_URL} - id: 'Cleanup' name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:latest' args: ['run', 'services', 'delete', '${_SERVICE}', '--region=${_REGION}', '--quiet'] substitutions: _SAMPLE: 'helloworld-shell' _SERVICE: 'test-${SHORT_SHA}' _REGION: 'us-central1' ``` -------------------------------- ### Build Container Image with Cloud Build Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/jobs-shell/README.md Submit a build to Cloud Build to create a container image tagged with your Artifact Registry repository. ```sh gcloud builds submit -t "${AR_REPO_NAME}/jobs-shell" ``` -------------------------------- ### Create Cloud Build Triggers via CLI Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md Commands to create Cloud Build GitHub triggers using YAML configuration files. Use these to set up pull request and nightly triggers. ```sh gcloud beta builds triggers create github \ --trigger-config=sample/path/pr.trigger-config.yaml gcloud beta builds triggers create github \ --trigger-config=sample/path/nightly.trigger-config.yaml ``` -------------------------------- ### Image Processing in Cloud Run (Node.js) Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/README.md Offers a sample for image processing in a Cloud Run service using Node.js. This might involve using libraries like Sharp for image manipulation. ```javascript const express = require('express'); const multer = require('multer'); const sharp = require('sharp'); const path = require('path'); const app = express(); const upload = multer({ storage: multer.memoryStorage() }); app.post('/', upload.single('image'), async (req, res) => { if (!req.file) { return res.status(400).send('No image file uploaded.'); } try { const processedImageBuffer = await sharp(req.file.buffer) .grayscale() .toFormat('png') .toBuffer(); res.setHeader('Content-Type', 'image/png'); res.send(processedImageBuffer); } catch (error) { console.error('Image processing error:', error); res.status(500).send('Error processing image.'); } }); const port = process.env.PORT || 8080; app.listen(port, () => { console.log(`Listening on port ${port}`); }); ``` -------------------------------- ### Run Integration Tests with Maven Source: https://github.com/googlecloudplatform/cloud-run-samples/blob/main/testing/README.md This Cloud Build step executes integration tests using Maven for Java projects. It assumes the service URL is available and uses the 'maven:3-openjdk-11' builder. ```yaml - id: 'Integration Tests' name: 'maven:3-openjdk-11' entrypoint: '/bin/bash' dir: $_SAMPLE args: - '-c' - | SERVICE_URL=$(cat _service_url) mvn verify ```