Offri contenuti dinamici e ospita microservizi con Cloud Run

Abbina Cloud Run a Firebase Hosting per generare e servire i tuoi contenuti dinamici o creare API REST come microservizi.

Utilizzando cloud Run , è possibile distribuire un'applicazione confezionato un'immagine contenitore. Quindi, utilizzando Firebase Hosting, puoi indirizzare le richieste HTTPS per attivare la tua app containerizzata.

  • Nuvola Run supporta diverse lingue (tra cui Go, Node.js, Python e Java), offrendo la flessibilità necessaria per utilizzare il linguaggio di programmazione e il quadro della vostra scelta.
  • Nuvola Esegui automaticamente e in orizzontale scale vostra immagine contenitore per gestire le richieste pervenute, poi le scale verso il basso quando la domanda diminuisce.
  • Hai solo paga per la CPU, memoria e networking consumato durante la manipolazione richiesta.

Per i casi di utilizzo di esempio e campioni per Cloud Run integrati con Firebase Hosting, visita la nostra panoramica senza server .


Questa guida ti mostra come:

  1. Scrivi una semplice applicazione Hello World
  2. Containerizza un'app e caricala in Container Registry
  3. Distribuisci l'immagine del contenitore su Cloud Run
  4. Richieste di hosting diretto alla tua app containerizzata

Si noti che per migliorare le prestazioni di servire contenuti dinamici, è possibile opzionalmente sintonizzare le vostre impostazioni della cache .

Prima di iniziare

Prima di utilizzare cloud Run, è necessario completare alcuni compiti iniziali, tra cui la creazione di un account di fatturazione cloud, permettendo al Cloud API Run, e l'installazione del gcloud strumento da riga di comando.

Imposta la fatturazione per il tuo progetto

Nuvola Run offre quota di utilizzo gratuito , ma è comunque necessario avere un conto di fatturazione cloud associato al tuo progetto di Firebase per uso o provare nuvola Esegui.

Abilita l'API e installa l'SDK

  1. Abilita l'API Cloud Run nella console delle API di Google:

    1. Aprire la pagina di Cloud API Run nella console delle API di Google.

    2. Quando richiesto, seleziona il tuo progetto Firebase.

    3. Fare clic su Attiva nella pagina Cloud API Esegui.

  2. Installare e inizializzare Cloud SDK.

  3. Controllare che il gcloud strumento è configurato per il progetto corretto:

    gcloud config list

Fase 1: scrivere l'applicazione di esempio

Nota che il Cloud Run supporta molte altre lingue , oltre alle lingue indicate nel seguente esempio.

andare

  1. Creare una nuova directory denominata helloworld-go , quindi nella directory appropriata:

    mkdir helloworld-go
    cd helloworld-go
  2. Creare un nuovo file chiamato helloworld.go , quindi aggiungere il seguente codice:

    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))
    }
    

    Questo codice crea un web server di base che ascolti sulla porta definita dal PORT variabile d'ambiente.

La tua app è finita e pronta per essere containerizzata e caricata in Container Registry.

Nodo.js

  1. Creare una nuova directory denominata helloworld-nodejs , cambiare directory poi in esso:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. Creare un package.json file con il seguente contenuto:

    {
      "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.16.4"
      }
    }
    
  3. Creare un nuovo file di nome index.js , quindi aggiungere il seguente codice:

    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);
    });
    

    Questo codice crea un web server di base che ascolti sulla porta definita dal PORT variabile d'ambiente.

La tua app è finita e pronta per essere containerizzata e caricata in Container Registry.

Pitone

  1. Creare una nuova directory denominata helloworld-python , cambiare directory poi in esso:

    mkdir helloworld-python
    cd helloworld-python
  2. Creare un nuovo file chiamato app.py , quindi aggiungere il seguente codice:

    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)))
    

    Questo codice crea un web server di base che ascolti sulla porta definita dal PORT variabile d'ambiente.

La tua app è finita e pronta per essere containerizzata e caricata in Container Registry.

Giava

  1. Installare Java SE 8 o successiva JDK e CURL .

    Nota che abbiamo solo bisogno di farlo per creare il nuovo progetto web nel passaggio successivo. Il Dockerfile, descritto in seguito, caricherà tutte le dipendenze nel contenitore.

  2. Dalla console, crea un nuovo progetto web vuoto usando cURL quindi decomprimi i comandi:

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

    Questo crea un progetto SpringBoot.

  3. Aggiornare lo SpringBootApplication di classe in src/main/java/com/example/helloworld/HelloworldApplication.java con l'aggiunta di un @RestController per gestire l' / mappatura e anche aggiungere una @Value campo per fornire il TARGET variabile d'ambiente:

    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);
      }
    }
    

    Questo codice crea un web server di base che ascolti sulla porta definita dal PORT variabile d'ambiente.

La tua app è finita e pronta per essere containerizzata e caricata in Container Registry.

Fase 2: containerize un app e caricarlo su Container Registro

  1. Containerize l'applicazione di esempio con la creazione di un nuovo file denominato Dockerfile nella stessa directory dei file di origine. Copia il seguente contenuto nel tuo file.

    andare

    # Use the official Golang image to create a build artifact.
    # This is based on Debian and sets the GOPATH to /go.
    FROM golang:1.13 as builder
    
    # 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=linux 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"]
    

    Nodo.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" ]
    

    Pitone

    # 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
    

    Giava

    # 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. Crea la tua immagine del contenitore utilizzando Cloud Build eseguendo il comando seguente dalla directory contenente il tuo Dockerfile:

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

    In caso di successo, vedrai un messaggio SUCCESS contenente il nome dell'immagine
    ( gcr.io/ PROJECT_ID /helloworld ).

L'immagine del contenitore è ora archiviata in Container Registry e può essere riutilizzata se lo si desidera.

Si noti che, invece di Nuvola Genera, è possibile utilizzare una versione installata in locale di Docker per costruire il vostro contenitore a livello locale .

Fase 3: Distribuire l'immagine contenitore a Cloud Run

  1. Distribuisci utilizzando il seguente comando:

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

  2. Quando richiesto:

  3. Attendi qualche istante per il completamento della distribuzione. In caso di successo, la riga di comando visualizza l'URL del servizio. Ad esempio: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  4. Visita il tuo contenitore distribuito aprendo l'URL del servizio in un browser web.

Il passo successivo ti guida attraverso il modo di accedere a questa applicazione container da un Hosting URL Firebase in modo che possa generare contenuti dinamici per il tuo sito Firebase-hosted.

Fase 4: le richieste di hosting diretti per la vostra applicazione in container

Con regole di riscrittura , è possibile indirizzare le richieste che corrispondono a modelli specifici per una singola destinazione.

L'esempio seguente mostra come dirigere tutte le richieste dalla pagina /helloworld sul tuo sito di hosting per attivare l'avvio e l'esecuzione del vostro helloworld esempio contenitore.

  1. Assicurati che:

    Per istruzioni dettagliate sull'installazione del CLI e l'inizializzazione di Hosting, consultare la guida introduttiva Get per l'hosting .

  2. Aprire il firebase.json lima .

  3. Aggiungere il seguente rewrite configurazione con il hosting sezione:

    "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)
        }
      } ]
    }
    
  4. Distribuisci la tua configurazione di hosting sul tuo sito eseguendo il seguente comando dalla radice della directory del tuo progetto:

    firebase deploy

Il tuo contenitore è ora raggiungibile tramite i seguenti URL:

  • I tuoi sottodomini Firebase:
    PROJECT_ID .web.app/ e PROJECT_ID .firebaseapp.com/

  • Eventuali collegati domini personalizzati :
    CUSTOM_DOMAIN /

Visita la pagina di configurazione Hosting per maggiori dettagli su regole di riscrittura . È inoltre possibile conoscere l'ordine di priorità delle risposte per le varie configurazioni di hosting.

Prova localmente

Durante lo sviluppo, puoi eseguire e testare l'immagine del contenitore in locale. Per istruzioni dettagliate, visitare il documentazione di cloud Run .

Prossimi passi