了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

Cung cấp nội dung động và lưu trữ các dịch vụ nhỏ với Cloud Run

Ghép nối Cloud Run với Firebase Hosting để tạo và phân phát nội dung động của bạn hoặc xây dựng API REST dưới dạng vi dịch vụ.

Sử dụng Cloud Run , bạn có thể triển khai ứng dụng được đóng gói trong hình ảnh bộ chứa. Sau đó, bằng cách sử dụng Dịch vụ lưu trữ Firebase, bạn có thể chuyển hướng các yêu cầu HTTPS để kích hoạt ứng dụng được chứa trong vùng chứa của mình.

  • Cloud Run hỗ trợ một số ngôn ngữ (bao gồm Go, Node.js, Python và Java), cho phép bạn linh hoạt sử dụng ngôn ngữ lập trình và khung tùy chọn.
  • Cloud Run tự động chia tỷ lệ theo chiều ngang và hình ảnh vùng chứa của bạn để xử lý các yêu cầu đã nhận, sau đó giảm tỷ lệ khi nhu cầu giảm.
  • Bạn chỉ trả tiền cho CPU, bộ nhớ và kết nối mạng đã tiêu thụ trong quá trình xử lý yêu cầu.

Ví dụ: các trường hợp sử dụng và mẫu cho Cloud Run được tích hợp với Lưu trữ Firebase, hãy truy cập tổng quan về serverless của chúng tôi.


Hướng dẫn này chỉ cho bạn cách:

  1. Viết ứng dụng Hello World đơn giản
  2. Chứa một ứng dụng và tải nó lên Container Registry
  3. Triển khai hình ảnh vùng chứa lên Cloud Run
  4. Yêu cầu lưu trữ trực tiếp tới ứng dụng được đóng gói của bạn

Lưu ý rằng để cải thiện hiệu suất phục vụ nội dung động, bạn có thể tùy ý điều chỉnh cài đặt bộ đệm của mình .

Trước khi bắt đầu

Trước khi sử dụng Cloud Run, bạn cần hoàn thành một số tác vụ ban đầu, bao gồm thiết lập tài khoản Thanh toán qua đám mây, bật API Cloud Run và cài đặt công cụ dòng lệnh gcloud .

Thiết lập thanh toán cho dự án của bạn

Cloud Run cung cấp hạn mức sử dụng miễn phí nhưng bạn vẫn phải có tài khoản Thanh toán qua đám mây được liên kết với dự án Firebase của mình để sử dụng hoặc dùng thử Cloud Run.

Kích hoạt API và cài đặt SDK

  1. Kích hoạt Cloud Run API trong bảng điều khiển Google API:

    1. Mở trang Cloud Run API trong bảng điều khiển Google API.

    2. Khi được nhắc, hãy chọn dự án Firebase của bạn.

    3. Nhấp vào Bật trên trang Cloud Run API.

  2. Cài đặt và khởi tạo Cloud SDK.

  3. Kiểm tra xem công cụ gcloud có được định cấu hình cho đúng dự án không:

    gcloud config list

Bước 1 : Viết đơn xin việc mẫu

Lưu ý rằng Cloud Run hỗ trợ nhiều ngôn ngữ khác ngoài các ngôn ngữ được hiển thị trong mẫu sau.

Đi

  1. Tạo một thư mục mới có tên helloworld-go , sau đó thay đổi thư mục vào đó:

    mkdir helloworld-go
    cd helloworld-go
  2. Tạo một tệp mới có tên helloworld.go , sau đó thêm đoạn mã sau:

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

    Mã này tạo một máy chủ web cơ bản lắng nghe trên cổng được xác định bởi biến môi trường PORT .

Ứng dụng của bạn đã hoàn tất và sẵn sàng để được chứa và tải lên Cơ quan đăng ký vùng chứa.

Node.js

  1. Tạo một thư mục mới có tên helloworld-nodejs , sau đó thay đổi thư mục vào đó:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. Tạo tệp package.json với nội dung sau:

    {
      "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. Tạo một tệp mới có tên index.js , sau đó thêm đoạn mã sau:

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

    Mã này tạo một máy chủ web cơ bản lắng nghe trên cổng được xác định bởi biến môi trường PORT .

Ứng dụng của bạn đã hoàn tất và sẵn sàng để được chứa và tải lên Cơ quan đăng ký vùng chứa.

con trăn

  1. Tạo một thư mục mới có tên helloworld-python , sau đó thay đổi thư mục vào đó:

    mkdir helloworld-python
    cd helloworld-python
  2. Tạo một tệp mới có tên app.py , sau đó thêm đoạn mã sau:

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

    Mã này tạo một máy chủ web cơ bản lắng nghe trên cổng được xác định bởi biến môi trường PORT .

Ứng dụng của bạn đã hoàn tất và sẵn sàng để được chứa và tải lên Cơ quan đăng ký vùng chứa.

Java

  1. Cài đặt Java SE 8 trở lên JDKCURL .

    Lưu ý rằng chúng ta chỉ cần làm điều này để tạo dự án web mới trong bước tiếp theo. Dockerfile, được mô tả sau, sẽ tải tất cả các phụ thuộc vào vùng chứa.

  2. Từ bảng điều khiển, tạo một dự án web trống mới bằng cách sử dụng cURL sau đó giải nén các lệnh:

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

    Điều này tạo ra một dự án SpringBoot.

  3. Cập nhật lớp SpringBootApplication trong src/main/java/com/example/helloworld/HelloworldApplication.java bằng cách thêm @RestController để xử lý ánh xạ / và cũng thêm trường @Value để cung cấp biến môi trường 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 target;
    
      @RestController
      class HelloworldController {
        @GetMapping("/")
        String hello() {
          return "Hello " + target + "!";
        }
      }
    
      public static void main(String[] args) {
        SpringApplication.run(HelloworldApplication.class, args);
      }
    }
    

    Mã này tạo một máy chủ web cơ bản lắng nghe trên cổng được xác định bởi biến môi trường PORT .

Ứng dụng của bạn đã hoàn tất và sẵn sàng để được chứa và tải lên Cơ quan đăng ký vùng chứa.

Bước 2 : Containerize một ứng dụng và tải nó lên Container Registry

  1. Chứa ứng dụng mẫu bằng cách tạo một tệp mới có tên Dockerfile trong cùng thư mục với các tệp nguồn. Sao chép nội dung sau vào tệp của bạn.

    Đi

    # 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" ]
    

    con trăn

    # 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. Xây dựng hình ảnh bộ chứa của bạn bằng Cloud Build bằng cách chạy lệnh sau từ thư mục chứa Dockerfile của bạn:

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

    Khi thành công bạn sẽ thấy thông báo SUCCESS chứa tên ảnh
    ( gcr.io/ PROJECT_ID /helloworld ).

Hình ảnh bộ chứa hiện được lưu trữ trong Cơ quan đăng ký bộ chứa và có thể được sử dụng lại nếu muốn.

Lưu ý rằng, thay vì Cloud Build, bạn có thể sử dụng phiên bản Docker được cài đặt cục bộ để xây dựng vùng chứa của mình cục bộ .

Bước 3 : Triển khai hình ảnh vùng chứa lên Cloud Run

  1. Triển khai bằng lệnh sau:

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

  2. Khi được nhắc:

  3. Đợi một lát để quá trình triển khai hoàn tất. Khi thành công, dòng lệnh sẽ hiển thị URL dịch vụ. Ví dụ: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  4. Truy cập vùng chứa đã triển khai của bạn bằng cách mở URL dịch vụ trong trình duyệt web.

Bước tiếp theo sẽ hướng dẫn bạn cách truy cập ứng dụng được chứa trong bộ chứa này từ URL Lưu trữ Firebase để ứng dụng có thể tạo nội dung động cho trang web được lưu trữ trên Firebase của bạn.

Bước 4: Yêu cầu lưu trữ trực tiếp đến ứng dụng được đóng gói của bạn

Với quy tắc viết lại , bạn có thể hướng các yêu cầu khớp với các mẫu cụ thể đến một đích duy nhất.

Ví dụ sau đây cho thấy cách điều hướng tất cả các yêu cầu từ trang /helloworld trên Trang web lưu trữ của bạn để kích hoạt khởi động và chạy phiên bản bộ chứa helloworld của bạn.

  1. Đảm bảo rằng:

    Để biết hướng dẫn chi tiết về cách cài đặt CLI và khởi chạy Dịch vụ lưu trữ, hãy xem hướng dẫn Bắt đầu cho Dịch vụ lưu trữ .

  2. Mở tệp firebase.json của bạn.

  3. Thêm cấu hình rewrite sau trong phần hosting :

    "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. Triển khai cấu hình lưu trữ cho trang web của bạn bằng cách chạy lệnh sau từ thư mục gốc của thư mục dự án của bạn:

    firebase deploy --only hosting

Vùng chứa của bạn hiện có thể truy cập được qua các URL sau:

  • Tên miền phụ Firebase của bạn:
    PROJECT_ID .web.app/PROJECT_ID .firebaseapp.com/

  • Mọi miền tùy chỉnh được kết nối :
    CUSTOM_DOMAIN /

Truy cập trang cấu hình Hosting để biết thêm chi tiết về quy tắc viết lại . Bạn cũng có thể tìm hiểu về thứ tự ưu tiên phản hồi đối với các cấu hình Dịch vụ lưu trữ khác nhau.

Kiểm tra tại địa phương

Trong quá trình phát triển, bạn có thể chạy và kiểm tra cục bộ hình ảnh bộ chứa của mình. Để biết hướng dẫn chi tiết, hãy truy cập tài liệu Cloud Run .

Bước tiếp theo