Stellen Sie dynamische Inhalte bereit und hosten Sie Microservices mit Cloud Run

Kombinieren Sie Cloud Run mit Firebase Hosting, um Ihre dynamischen Inhalte zu generieren und bereitzustellen oder REST-APIs als Microservices zu erstellen.

Mit Cloud Run können Sie eine in einem Container-Image verpackte Anwendung bereitstellen. Mithilfe von Firebase Hosting können Sie dann HTTPS-Anfragen leiten, um Ihre Container-App auszulösen.

  • Cloud Run unterstützt mehrere Sprachen (einschließlich Go, Node.js, Python und Java) und gibt Ihnen so die Flexibilität, die Programmiersprache und das Framework Ihrer Wahl zu verwenden.
  • Cloud Run skaliert Ihr Container-Image automatisch und horizontal, um die empfangenen Anforderungen zu verarbeiten, und verkleinert es dann, wenn die Nachfrage sinkt.
  • Sie zahlen nur für die CPU, den Arbeitsspeicher und die Netzwerkleistung, die während der Anforderungsbearbeitung verbraucht werden.

Beispiel-Anwendungsfälle und Beispiele für Cloud Run, integriert mit Firebase Hosting, finden Sie in unserer serverlosen Übersicht .


Dieser Leitfaden zeigt Ihnen, wie Sie:

  1. Schreiben Sie eine einfache Hello World-Anwendung
  2. Containerisieren Sie eine App und laden Sie sie in Container Registry hoch
  3. Stellen Sie das Container-Image in Cloud Run bereit
  4. Direkte Hosting-Anfragen an Ihre Container-App

Beachten Sie, dass Sie zur Verbesserung der Leistung bei der Bereitstellung dynamischer Inhalte optional Ihre Cache-Einstellungen optimieren können.

Bevor Sie beginnen

Bevor Sie Cloud Run verwenden, müssen Sie einige anfängliche Aufgaben erledigen, darunter das Einrichten eines Cloud-Rechnungskontos, das Aktivieren der Cloud Run-API und die Installation des gcloud Befehlszeilentools.

Richten Sie die Abrechnung für Ihr Projekt ein

Cloud Run bietet ein kostenloses Nutzungskontingent , Sie müssen jedoch dennoch über ein mit Ihrem Firebase-Projekt verknüpftes Cloud-Rechnungskonto verfügen, um Cloud Run nutzen oder ausprobieren zu können.

Aktivieren Sie die API und installieren Sie das SDK

  1. Aktivieren Sie die Cloud Run API in der Google APIs-Konsole:

    1. Öffnen Sie die Cloud Run API-Seite in der Google APIs-Konsole.

    2. Wenn Sie dazu aufgefordert werden, wählen Sie Ihr Firebase-Projekt aus.

    3. Klicken Sie auf der Cloud Run-API-Seite auf Aktivieren .

  2. Installieren und initialisieren Sie das Cloud SDK.

  3. Überprüfen Sie, ob das gcloud Tool für das richtige Projekt konfiguriert ist:

    gcloud config list

Schritt 1 : Schreiben Sie die Musteranwendung

Beachten Sie, dass Cloud Run zusätzlich zu den im folgenden Beispiel gezeigten Sprachen viele weitere Sprachen unterstützt.

Gehen

  1. Erstellen Sie ein neues Verzeichnis mit dem Namen helloworld-go und wechseln Sie dann in das Verzeichnis:

    mkdir helloworld-go
    cd helloworld-go
  2. Erstellen Sie eine neue Datei mit dem Namen helloworld.go und fügen Sie dann den folgenden Code hinzu:

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"os"
    )
    
    func handler(w http.ResponseWriter, r *http.Request) {
    	log.Print("helloworld: received a request")
    	target := os.Getenv("TARGET")
    	if target == "" {
    		target = "World"
    	}
    	fmt.Fprintf(w, "Hello %s!\n", target)
    }
    
    func main() {
    	log.Print("helloworld: starting server...")
    
    	http.HandleFunc("/", handler)
    
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    	}
    
    	log.Printf("helloworld: listening on port %s", port)
    	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
    }
    

    Dieser Code erstellt einen einfachen Webserver, der den durch die Umgebungsvariable PORT definierten Port überwacht.

Ihre App ist fertig und kann in Containern verpackt und in Container Registry hochgeladen werden.

Node.js

  1. Erstellen Sie ein neues Verzeichnis mit dem Namen helloworld-nodejs und wechseln Sie dann in das Verzeichnis:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. Erstellen Sie eine package.json Datei mit folgendem Inhalt:

    {
      "name": "knative-serving-helloworld",
      "version": "1.0.0",
      "description": "Simple hello world sample in Node",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "author": "",
      "license": "Apache-2.0",
      "dependencies": {
        "express": "^4.18.2"
      }
    }
    
  3. Erstellen Sie eine neue Datei mit dem Namen index.js und fügen Sie dann den folgenden Code hinzu:

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
      console.log('Hello world received a request.');
    
      const target = process.env.TARGET || 'World';
      res.send(`Hello ${target}!\n`);
    });
    
    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log('Hello world listening on port', port);
    });
    

    Dieser Code erstellt einen einfachen Webserver, der den durch die Umgebungsvariable PORT definierten Port überwacht.

Ihre App ist fertig und kann in Containern verpackt und in Container Registry hochgeladen werden.

Python

  1. Erstellen Sie ein neues Verzeichnis mit dem Namen helloworld-python und wechseln Sie dann in das Verzeichnis:

    mkdir helloworld-python
    cd helloworld-python
  2. Erstellen Sie eine neue Datei mit dem Namen app.py und fügen Sie dann den folgenden Code hinzu:

    import os
    
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        target = os.environ.get('TARGET', 'World')
        return 'Hello {}!\n'.format(target)
    
    if __name__ == "__main__":
        app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))
    

    Dieser Code erstellt einen einfachen Webserver, der den durch die Umgebungsvariable PORT definierten Port überwacht.

Ihre App ist fertig und kann in Containern verpackt und in Container Registry hochgeladen werden.

Java

  1. Installieren Sie Java SE 8 oder höher, JDK und CURL .

    Beachten Sie, dass wir dies nur tun müssen, um im nächsten Schritt das neue Webprojekt zu erstellen. Die später beschriebene Docker-Datei lädt alle Abhängigkeiten in den Container.

  2. Erstellen Sie in der Konsole mit cURL ein neues leeres Webprojekt und entpacken Sie dann die Befehle:

    curl https://start.spring.io/starter.zip \
        -d dependencies=web \
        -d name=helloworld \
        -d artifactId=helloworld \
        -o helloworld.zip
    unzip helloworld.zip

    Dadurch wird ein SpringBoot-Projekt erstellt.

  3. Aktualisieren Sie die SpringBootApplication Klasse in src/main/java/com/example/helloworld/HelloworldApplication.java indem Sie einen @RestController hinzufügen, um die / -Zuordnung zu verarbeiten, und außerdem ein @Value Feld hinzufügen, um die Umgebungsvariable TARGET bereitzustellen:

    package com.example.helloworld;
    
    import org.springframework.beans.factory.annotation.Value;
    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
    public class HelloworldApplication {
    
      @Value("${TARGET:World}")
      String target;
    
      @RestController
      class HelloworldController {
        @GetMapping("/")
        String hello() {
          return "Hello " + target + "!";
        }
      }
    
      public static void main(String[] args) {
        SpringApplication.run(HelloworldApplication.class, args);
      }
    }
    

    Dieser Code erstellt einen einfachen Webserver, der den durch die Umgebungsvariable PORT definierten Port überwacht.

Ihre App ist fertig und kann in Containern verpackt und in Container Registry hochgeladen werden.

Schritt 2 : Containerisieren Sie eine App und laden Sie sie in Container Registry hoch

  1. Containerisieren Sie die Beispiel-App, indem Sie eine neue Datei mit dem Namen Dockerfile im selben Verzeichnis wie die Quelldateien erstellen. Kopieren Sie den folgenden Inhalt in Ihre Datei.

    Gehen

    # Use the official Golang image to create a build artifact.
    # This is based on Debian and sets the GOPATH to /go.
    FROM golang:latest as builder
    
    ARG TARGETOS
    ARG TARGETARCH
    
    # Create and change to the app directory.
    WORKDIR /app
    
    # Retrieve application dependencies using go modules.
    # Allows container builds to reuse downloaded dependencies.
    COPY go.* ./
    RUN go mod download
    
    # Copy local code to the container image.
    COPY . ./
    
    # Build the binary.
    # -mod=readonly ensures immutable go.mod and go.sum in container builds.
    RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -mod=readonly -v -o server
    
    # Use the official Alpine image for a lean production container.
    # https://hub.docker.com/_/alpine
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM alpine:3
    RUN apk add --no-cache ca-certificates
    
    # Copy the binary to the production image from the builder stage.
    COPY --from=builder /app/server /server
    
    # Run the web service on container startup.
    CMD ["/server"]
    

    Node.js

    # Use the official lightweight Node.js 12 image.
    # https://hub.docker.com/_/node
    FROM node:12-slim
    
    # Create and change to the app directory.
    WORKDIR /usr/src/app
    
    # Copy application dependency manifests to the container image.
    # A wildcard is used to ensure both package.json AND package-lock.json are copied.
    # Copying this separately prevents re-running npm install on every code change.
    COPY package*.json ./
    
    # Install production dependencies.
    RUN npm install --only=production
    
    # Copy local code to the container image.
    COPY . ./
    
    # Run the web service on container startup.
    CMD [ "npm", "start" ]
    

    Python

    # Use the official lightweight Python image.
    # https://hub.docker.com/_/python
    FROM python:3.7-slim
    
    # Allow statements and log messages to immediately appear in the Knative logs
    ENV PYTHONUNBUFFERED True
    
    # Copy local code to the container image.
    ENV APP_HOME /app
    WORKDIR $APP_HOME
    COPY . ./
    
    # Install production dependencies.
    RUN pip install Flask gunicorn
    
    # Run the web service on container startup. Here we use the gunicorn
    # webserver, with one worker process and 8 threads.
    # For environments with multiple CPU cores, increase the number of workers
    # to be equal to the cores available.
    CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app
    

    Java

    # Use the official maven/Java 8 image to create a build artifact: https://hub.docker.com/_/maven
    FROM maven:3.5-jdk-8-alpine as builder
    
    # Copy local code to the container image.
    WORKDIR /app
    COPY pom.xml .
    COPY src ./src
    
    # Build a release artifact.
    RUN mvn package -DskipTests
    
    # Use the Official OpenJDK image for a lean production stage of our multi-stage build.
    # https://hub.docker.com/_/openjdk
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM openjdk:8-jre-alpine
    
    # Copy the jar to the production image from the builder stage.
    COPY --from=builder /app/target/helloworld-*.jar /helloworld.jar
    
    # Run the web service on container startup.
    CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/helloworld.jar"]
    

  2. Erstellen Sie Ihr Container-Image mit Cloud Build, indem Sie den folgenden Befehl aus dem Verzeichnis ausführen, das Ihre Docker-Datei enthält:

    gcloud builds submit --tag gcr.io/PROJECT_ID/helloworld

    Bei Erfolg wird eine ERFOLGREICH-Meldung mit dem Bildnamen angezeigt
    ( gcr.io/ PROJECT_ID /helloworld ).

Das Container-Image wird nun in Container Registry gespeichert und kann bei Bedarf wiederverwendet werden.

Beachten Sie, dass Sie anstelle von Cloud Build eine lokal installierte Version von Docker verwenden können, um Ihren Container lokal zu erstellen .

Schritt 3 : Stellen Sie das Container-Image in Cloud Run bereit

  1. Stellen Sie es mit dem folgenden Befehl bereit:

    gcloud run deploy --image gcr.io/PROJECT_ID/helloworld

  2. Wenn Sie dazu aufgefordert werden:

Um die beste Leistung zu erzielen, platzieren Sie Ihren Cloud Run-Dienst mit Hosting in den folgenden Regionen:

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

Umschreibungen in Cloud Run vom Hosting werden in den folgenden Regionen unterstützt:

  • asia-east1
  • asia-east2
  • asia-northeast1
  • asia-northeast2
  • asia-northeast3
  • asia-south1
  • asia-south2
  • asia-southeast1
  • asia-southeast2
  • australia-southeast1
  • australia-southeast2
  • europe-central2
  • europe-north1
  • europe-southwest1
  • europe-west1
  • europe-west12
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west6
  • europe-west8
  • europe-west9
  • me-central1
  • me-west1
  • northamerica-northeast1
  • northamerica-northeast2
  • southamerica-east1
  • southamerica-west1
  • us-central1
  • us-east1
  • us-east4
  • us-east5
  • us-south1
  • us-west1
  • us-west2
  • us-west3
  • us-west4
  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1
  1. Warten Sie einen Moment, bis die Bereitstellung abgeschlossen ist. Bei Erfolg zeigt die Befehlszeile die Dienst-URL an. Zum Beispiel: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  2. Besuchen Sie Ihren bereitgestellten Container, indem Sie die Dienst-URL in einem Webbrowser öffnen.

Im nächsten Schritt erfahren Sie, wie Sie über eine Firebase-Hosting-URL auf diese Container-App zugreifen, damit sie dynamische Inhalte für Ihre von Firebase gehostete Website generieren kann.

Schritt 4: Leiten Sie Hosting-Anfragen an Ihre Container-App weiter

Mit Rewrite-Regeln können Sie Anfragen, die bestimmten Mustern entsprechen, an ein einzelnes Ziel weiterleiten.

Das folgende Beispiel zeigt, wie Sie alle Anfragen von der Seite /helloworld auf Ihrer Hosting-Site weiterleiten, um den Start und die Ausführung Ihrer helloworld Containerinstanz auszulösen.

  1. Stelle sicher das:

    Ausführliche Anweisungen zur Installation der CLI und zur Initialisierung des Hostings finden Sie im Leitfaden „Erste Schritte“ für Hosting .

  2. Öffnen Sie Ihre firebase.json -Datei .

  3. Fügen Sie im Abschnitt hosting die folgende rewrite Konfiguration hinzu:

    "hosting": {
      // ...
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/helloworld",
        "run": {
          "serviceId": "helloworld",  // "service name" (from when you deployed the container image)
          "region": "us-central1",    // optional (if omitted, default is us-central1)
          "pinTag": true              // optional (see note below)
        }
      } ]
    }
    
  4. Stellen Sie Ihre Hosting-Konfiguration auf Ihrer Site bereit, indem Sie den folgenden Befehl im Stammverzeichnis Ihres Projektverzeichnisses ausführen:

    firebase deploy --only hosting

Ihr Container ist nun über die folgenden URLs erreichbar:

  • Ihre Firebase-Subdomains:
    PROJECT_ID .web.app/ und PROJECT_ID .firebaseapp.com/

  • Alle verbundenen benutzerdefinierten Domänen :
    CUSTOM_DOMAIN /

Besuchen Sie die Hosting-Konfigurationsseite für weitere Details zu Rewrite-Regeln . Sie können sich auch über die Prioritätsreihenfolge der Antworten für verschiedene Hosting-Konfigurationen informieren.

Testen Sie vor Ort

Während der Entwicklung können Sie Ihr Container-Image lokal ausführen und testen. Ausführliche Anweisungen finden Sie in der Cloud Run-Dokumentation .

Nächste Schritte