Ir para o console

Exiba conteúdo dinâmico e hospede microsserviços com o Cloud Run

Pareie o Cloud Run com o Firebase Hosting para gerar e exibir o conteúdo dinâmico ou criar APIs REST como microsserviços.

Ao usar o Cloud Run, é possível implantar um aplicativo empacotado em uma imagem de contêiner. Em seguida, com o Firebase Hosting, é possível direcionar solicitações HTTPS para acionar seu aplicativo em contêiner.

  • O Cloud Run é compatível com várias linguagens, incluindo Go, Node.js, Python e Java, e oferece a flexibilidade de usar a linguagem de programação e o framework de sua escolha.
  • O Cloud Run escalona automática e horizontalmente a imagem do seu contêiner para lidar com as solicitações recebidas e reduz o escalonamento quando a demanda diminui.
  • Você paga apenas pela CPU, memória e rede consumida durante o processamento da solicitação.

Por exemplo, casos de uso e amostras para o Cloud Run integrado ao Firebase Hosting, visite nossa visão geral sem servidor.


Este guia mostra como:

  1. escrever uma simples aplicação Hello World;
  2. colocar em contêiner um aplicativo e fazer upload para o Container Registry;
  3. implantar a imagem do contêiner no Cloud Run;
  4. solicitar uma hospedagem direta para seu aplicativo em contêiner.

Observe que, para melhorar o desempenho da exibição de conteúdo dinâmico, é possível, opcionalmente, ajustar suas configurações de cache.

Antes de começar

Antes de usar o Cloud Run, você precisa concluir algumas tarefas iniciais, incluindo a configuração de uma conta de faturamento, a ativação da API Cloud Run e a instalação da ferramenta de linha de comando gcloud.

Configure o faturamento do seu projeto

O Cloud Run oferece cota de uso gratuito, mas você ainda precisa ter uma conta de faturamento associada ao seu projeto do Firebase para usar ou testar o Cloud Run.

Ative a API e instale o SDK

  1. Ative a API Cloud Run no console de APIs do Google:

    1. Abra a página da API Cloud Run no console de APIs do Google.

    2. Quando solicitado, selecione seu projeto do Firebase.

    3. Clique em Ativar na página da API Cloud Run.

  2. Instale e inicialize o SDK do Cloud.

Instale o componente gcloud Beta.

  1. Execute o seguinte comando para instalar o componente gcloud Beta:

    gcloud components install beta
  2. Atualize os componentes:

    gcloud components update
  3. Verifique se a ferramenta gcloud está configurada para o projeto correto:

    gcloud config list

Etapa 1: grave o aplicativo de amostra

Observe que o Cloud Run é compatível com muitas outras linguagens, além das linguagens mostradas na amostra a seguir.

Go

  1. Crie um novo diretório chamado helloworld-go, em seguida, altere o diretório para ele:

    mkdir helloworld-go
    cd helloworld-go
  2. Crie um novo arquivo chamado helloworld.go e adicione o seguinte código:

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

    Esse código cria um servidor da Web básico que detecta na porta definida pela variável de ambiente PORT.

O aplicativo está concluído e pronto para ficar em contêiner e enviado para o Container Registry.

Node.js

  1. Crie um novo diretório chamado helloworld-nodejs, em seguida, altere o diretório para ele:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. Crie um arquivo package.json com o seguinte conteúdo:

    {
      "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. Crie um novo arquivo chamado index.js e adicione o seguinte código:

    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}!`);
    });
    
    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log('Hello world listening on port', port);
    });
    

    Esse código cria um servidor da Web básico que detecta na porta definida pela variável de ambiente PORT.

O aplicativo está concluído e pronto para ficar em contêiner e enviado para o Container Registry.

Python

  1. Crie um novo diretório chamado helloworld-python, em seguida, altere o diretório para ele:

    mkdir helloworld-python
    cd helloworld-python
  2. Crie um novo arquivo chamado app.py e adicione o seguinte código:

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

    Esse código cria um servidor da Web básico que detecta na porta definida pela variável de ambiente PORT.

O aplicativo está concluído e pronto para ficar em contêiner e enviado para o Container Registry.

Java

  1. Instale o Java SE 8 ou o posterior JDK e CURL.

    Observe que só precisamos fazer isso para criar o novo projeto da Web na próxima etapa. O Dockerfile, descrito posteriormente, carregará todas as dependências no contêiner.

  2. No console, crie um novo projeto da Web vazio usando cURL e, em seguida, descompacte os comandos:

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

    Isso cria um projeto SpringBoot.

  3. Atualize a classe SpringBootApplication em src/main/java/com/example/helloworld/HelloworldApplication.java adicionando um @RestController para tratar o mapeamento / e também adicione um campo @Value para fornecer a variável de ambiente TARGET:

    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 message;
    
    	@RestController
    	class HelloworldController {
    		@GetMapping("/")
    		String hello() {
    			return "Hello " + message + "!";
    		}
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(HelloworldApplication.class, args);
    	}
    }
    

    Esse código cria um servidor da Web básico que detecta na porta definida pela variável de ambiente PORT.

O aplicativo está concluído e pronto para ficar em contêiner e enviado para o Container Registry.

Etapa 2 : colocar em contêiner um aplicativo e fazer upload para o Container Registry

  1. Para colocar em contêiner o aplicativo de amostra, basta criar um novo arquivo chamado Dockerfile no mesmo diretório dos arquivos de origem. Copie o seguinte conteúdo em seu arquivo.

    Go

    # Use the offical Golang image to create a build artifact.
    # This is based on Debian and sets the GOPATH to /go.
    # https://hub.docker.com/_/golang
    FROM golang as builder
    
    # Copy local code to the container image.
    WORKDIR /go/src/github.com/knative/docs/helloworld
    COPY . .
    
    # Build the outyet command inside the container.
    # (You may fetch or manage dependencies here,
    # either manually or with a tool like "godep".)
    RUN CGO_ENABLED=0 GOOS=linux go build -v -o helloworld
    
    # Use a Docker multi-stage build to create a lean production image.
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM alpine
    
    # Copy the binary to the production image from the builder stage.
    COPY --from=builder /go/src/github.com/knative/docs/helloworld/helloworld /helloworld
    
    # Service must listen to $PORT environment variable.
    # This default value facilitates local development.
    ENV PORT 8080
    
    # Run the web service on container startup.
    CMD ["/helloworld"]
    

    Node.js

    # Use the official Node.js 10 image.
    # https://hub.docker.com/_/node
    FROM node:10
    
    # 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 . .
    
    # Service must listen to $PORT environment variable.
    # This default value facilitates local development.
    ENV PORT 8080
    
    # Run the web service on container startup.
    CMD [ "npm", "start" ]
    

    Python

    # Use the official Python image.
    # https://hub.docker.com/_/python
    FROM python
    
    # Copy local code to the container image.
    ENV APP_HOME /app
    WORKDIR $APP_HOME
    COPY . .
    
    # Install production dependencies.
    RUN pip install Flask gunicorn
    
    # Service must listen to $PORT environment variable.
    # This default value facilitates local development.
    ENV PORT 8080
    
    # 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 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
    
    # Service must listen to $PORT environment variable.
    # This default value facilitates local development.
    ENV PORT 8080
    
    # Run the web service on container startup.
    CMD ["java","-Djava.security.egd=file:/dev/./urandom","-Dserver.port=${PORT}","-jar","/helloworld.jar"]
    

  2. Crie a imagem de contêiner usando o Cloud Build. Para isso, execute o seguinte comando no diretório que contém seu Dockerfile:

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

    Concluído com sucesso, você verá uma mensagem de SUCESSO contendo o nome da imagem
    (gcr.io/projectID/helloworld).

A imagem do contêiner agora está armazenada no Container Registry e pode ser reutilizada, se desejado.

Observe que, em vez do Cloud Build, é possível usar uma versão instalada localmente do Docker para criar seu contêiner localmente.

Etapa 3: implantar a imagem do contêiner no Cloud Run

  1. Implante usando o seguinte comando:

    gcloud beta run deploy --image gcr.io/projectID/helloworld

  2. Quando solicitado:

  3. Aguarde alguns instantes para que a implantação seja concluída. Ao concluir com sucesso, a linha de comando exibe o URL de serviço. Por exemplo:

    https://helloworld-random_hash-us-central1.a.run.app
  4. Consulte o contêiner implementado, Para isso, abra o URL de serviço em um navegador da Web.

A próxima etapa orienta você sobre como acessar esse aplicativo em contêiner de um URL de hospedagem do Firebase para que ele possa gerar conteúdo dinâmico para seu site hospedado pelo Firebase.

Etapa 4: direcionar solicitações de hospedagem para seu aplicativo em contêiner

Com as regras de substituição, é possível direcionar solicitações que correspondam a padrões específicos para um único destino.

O exemplo a seguir mostra como direcionar todas as solicitações da página /helloworld no site de hospedagem para acionar a inicialização e a execução de sua instância de contêiner helloworld.

  1. Verifique se:

    • você tem a versão mais recente da Firebase CLI executando npm install -g firebase-tools;

    • você inicializou o Firebase Hosting.

    Para receber instruções detalhadas sobre como instalar o CLI e inicializar o Hosting, consulte o guia de primeiros passos do Hosting.

  2. Abra seu arquivo firebase.json.

  3. Adicione a seguinte configuração de rewrite na seção de hosting:

    "hosting": {
      // ...
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "**",
        "run": {
          "serviceId": "helloworld",  // "service name" (from when you deployed the container image)
          "region": "us-central1"     // optional (if omitted, default is us-central1)
        }
      } ]
    }
    
  4. Implante a configuração de hospedagem no site ao executar o seguinte comando na raiz do diretório do seu projeto:

    firebase deploy

Seu contêiner agora pode ser acessado pelos seguintes URLs:

  • Seus subdomínios do Firebase: projectID.web.app/helloworld e projectID.firebaseapp.com/helloworld

  • Todos os domínios personalizados conectados: custom-domain/helloworld

Visite a página de configuração do Hosting para ver mais detalhes sobre regras de substituição. Saiba mais sobre a ordem de prioridade das respostas para várias configurações do Hosting.

Testar localmente

Durante o desenvolvimento, é possível executar e testar sua imagem de contêiner localmente. Para instruções detalhadas, consulte a documentação do Cloud Run.

Próximas etapas