Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

ให้บริการเนื้อหาแบบไดนามิกและโฮสต์ไมโครเซอร์วิสด้วย Cloud Run

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

จับคู่ Cloud Run กับ Firebase Hosting เพื่อสร้างและให้บริการเนื้อหาแบบไดนามิกของคุณ หรือสร้าง REST API เป็นไมโครเซอร์วิส

เมื่อใช้ Cloud Run คุณจะปรับใช้แอปพลิเคชันที่จัดแพ็กเกจในอิมเมจคอนเทนเนอร์ได้ จากนั้น เมื่อใช้โฮสติ้งของ Firebase คุณจะส่งคำขอ HTTPS เพื่อทริกเกอร์แอปที่มีคอนเทนเนอร์ได้

ตัวอย่างเช่น กรณีใช้งานและตัวอย่างสำหรับ Cloud Run ที่ผสานรวมกับ Firebase Hosting ไปที่ ภาพรวมแบบไร้เซิร์ฟเวอร์ ของเรา


คู่มือนี้จะแสดงวิธีการ:

  1. เขียนโปรแกรม Hello World ง่ายๆ
  2. Containerize แอปและอัปโหลดไปยัง Container Registry
  3. ทำให้อิมเมจคอนเทนเนอร์ใช้งานได้กับ Cloud Run
  4. คำขอโฮสติ้งโดยตรงไปยังแอปคอนเทนเนอร์ของคุณ

โปรดทราบว่าในการปรับปรุงประสิทธิภาพการแสดงเนื้อหาแบบไดนามิก คุณสามารถเลือกปรับ การตั้งค่าแคช

ก่อนจะเริ่ม

ก่อนใช้ Cloud Run คุณต้องทำงานเบื้องต้นบางอย่างให้เสร็จสิ้น รวมถึงการตั้งค่าบัญชี Cloud Billing การเปิดใช้ Cloud Run API และติดตั้งเครื่องมือบรรทัดคำสั่ง gcloud

ตั้งค่าการเรียกเก็บเงินสำหรับโครงการของคุณ

Cloud Run ให้โควต้าการใช้งานฟรี แต่คุณยังคงต้องมี บัญชี Cloud Billing ที่เชื่อมโยงกับโปรเจ็กต์ Firebase เพื่อใช้งานหรือทดลองใช้ Cloud Run

เปิดใช้งาน API และติดตั้ง SDK

  1. เปิดใช้งาน Cloud Run API ในคอนโซล Google APIs:

    1. เปิดหน้า Cloud Run API ในคอนโซล Google APIs

    2. เมื่อได้รับแจ้ง ให้เลือกโปรเจ็กต์ Firebase

    3. คลิก เปิดใช้งาน บนหน้า Cloud Run API

  2. ติดตั้งและเริ่มต้น Cloud SDK

  3. ตรวจสอบว่ามีการกำหนดค่าเครื่องมือ gcloud สำหรับโปรเจ็กต์ที่ถูกต้อง:

    gcloud config list

ขั้นตอนที่ 1 : เขียนใบสมัครตัวอย่าง

โปรดทราบว่า Cloud Run รองรับ ภาษาอื่นๆ มากมาย นอกเหนือจากภาษาที่แสดงในตัวอย่างต่อไปนี้

ไป

  1. สร้างไดเร็กทอรีใหม่ชื่อ helloworld-go แล้วเปลี่ยนไดเร็กทอรีเป็นไดเร็กทอรี:

    mkdir helloworld-go
    cd helloworld-go
  2. สร้างไฟล์ใหม่ชื่อ helloworld.go จากนั้นเพิ่มรหัสต่อไปนี้:

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

    รหัสนี้สร้างเว็บเซิร์ฟเวอร์พื้นฐานที่รับฟังพอร์ตที่กำหนดโดยตัวแปรสภาพแวดล้อม PORT

แอปของคุณเสร็จแล้วและพร้อมที่จะบรรจุและอัปโหลดไปยัง Container Registry

Node.js

  1. สร้างไดเร็กทอรีใหม่ชื่อ helloworld-nodejs จากนั้นเปลี่ยนไดเร็กทอรีเป็นไดเร็กทอรี:

    mkdir helloworld-nodejs
    cd helloworld-nodejs
  2. สร้างไฟล์ package.json ด้วยเนื้อหาต่อไปนี้:

    {
      "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. สร้างไฟล์ใหม่ชื่อ index.js จากนั้นเพิ่มรหัสต่อไปนี้:

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

    รหัสนี้สร้างเว็บเซิร์ฟเวอร์พื้นฐานที่รับฟังพอร์ตที่กำหนดโดยตัวแปรสภาพแวดล้อม PORT

แอปของคุณเสร็จแล้วและพร้อมที่จะบรรจุและอัปโหลดไปยัง Container Registry

Python

  1. สร้างไดเร็กทอรีใหม่ชื่อ helloworld-python จากนั้นเปลี่ยนไดเร็กทอรีเป็นไดเร็กทอรี:

    mkdir helloworld-python
    cd helloworld-python
  2. สร้างไฟล์ใหม่ชื่อ app.py จากนั้นเพิ่มรหัสต่อไปนี้:

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

    รหัสนี้สร้างเว็บเซิร์ฟเวอร์พื้นฐานที่รับฟังพอร์ตที่กำหนดโดยตัวแปรสภาพแวดล้อม PORT

แอปของคุณเสร็จแล้วและพร้อมที่จะบรรจุและอัปโหลดไปยัง Container Registry

Java

  1. ติดตั้ง Java SE 8 หรือใหม่กว่า JDK และ CURL

    โปรดทราบว่าเราจำเป็นต้องทำเช่นนี้เพื่อสร้างโครงการเว็บใหม่ในขั้นตอนต่อไป Dockerfile ซึ่งจะอธิบายในภายหลัง จะโหลดการพึ่งพาทั้งหมดลงในคอนเทนเนอร์

  2. จากคอนโซล ให้สร้างโปรเจ็กต์เว็บว่างใหม่โดยใช้ cURL จากนั้นคลายซิปคำสั่ง:

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

    สิ่งนี้จะสร้างโปรเจ็กต์ SpringBoot

  3. อัปเดตคลาส SpringBootApplication ใน src/main/java/com/example/helloworld/HelloworldApplication.java โดยเพิ่ม @RestController เพื่อจัดการ / mapping และเพิ่มฟิลด์ @Value เพื่อจัดเตรียมตัวแปรสภาพแวดล้อม 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);
      }
    }
    

    รหัสนี้สร้างเว็บเซิร์ฟเวอร์พื้นฐานที่รับฟังพอร์ตที่กำหนดโดยตัวแปรสภาพแวดล้อม PORT

แอปของคุณเสร็จแล้วและพร้อมที่จะบรรจุและอัปโหลดไปยัง Container Registry

ขั้นตอนที่ 2 : คอนเทนเนอร์แอปและอัปโหลดไปยัง Container Registry

  1. ทำให้แอปตัวอย่างเป็นคอนเทนเนอร์โดยสร้างไฟล์ใหม่ที่ชื่อ Dockerfile ในไดเร็กทอรีเดียวกันกับไฟล์ต้นฉบับ คัดลอกเนื้อหาต่อไปนี้ลงในไฟล์ของคุณ

    ไป

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

    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. สร้างอิมเมจคอนเทนเนอร์ของคุณโดยใช้ Cloud Build โดยเรียกใช้คำสั่งต่อไปนี้จากไดเร็กทอรีที่มี Dockerfile ของคุณ:

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

    เมื่อสำเร็จ คุณจะเห็นข้อความ SUCCESS ที่มีชื่อภาพ
    ( gcr.io/ PROJECT_ID /helloworld )

ตอนนี้อิมเมจคอนเทนเนอร์ถูกเก็บไว้ใน Container Registry และสามารถนำกลับมาใช้ใหม่ได้หากต้องการ

โปรดทราบว่าแทนที่จะใช้ Cloud Build คุณสามารถใช้ Docker เวอร์ชันที่ติดตั้งในเครื่องเพื่อ สร้างคอนเทนเนอร์ของคุณใน เครื่อง

ขั้นตอนที่ 3 : ปรับใช้อิมเมจคอนเทนเนอร์กับ Cloud Run

  1. ปรับใช้โดยใช้คำสั่งต่อไปนี้:

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

  2. เมื่อได้รับแจ้ง:

    • เลือกภูมิภาค (เช่น us-central1 )
    • ยืนยันชื่อบริการ (เช่น helloworld )
    • ตอบกลับ Y เพื่อ อนุญาตการเรียกใช้ ที่ไม่ผ่านการตรวจสอบสิทธิ์
  3. รอสักครู่เพื่อให้การทำให้ใช้งานได้เสร็จสมบูรณ์ เมื่อสำเร็จ บรรทัดคำสั่งจะแสดง URL ของบริการ ตัวอย่างเช่น: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  4. เยี่ยมชมคอนเทนเนอร์ที่ปรับใช้ของคุณโดยเปิด URL ของบริการในเว็บเบราว์เซอร์

ขั้นตอนต่อไปจะอธิบายวิธีเข้าถึงแอปที่มีคอนเทนเนอร์นี้ จาก URL โฮสติ้งของ Firebase เพื่อให้สามารถสร้างเนื้อหาแบบไดนามิกสำหรับไซต์ที่โฮสต์โดย Firebase ของคุณ

ขั้นตอนที่ 4: ส่งคำขอโฮสต์โดยตรงไปยังแอปที่มีคอนเทนเนอร์ของคุณ

ด้วย กฎการเขียน ซ้ำ คุณสามารถส่งคำขอที่ตรงกับรูปแบบเฉพาะไปยังปลายทางเดียวได้

ตัวอย่างต่อไปนี้แสดงวิธีการส่งคำขอทั้งหมดจากหน้า /helloworld บนไซต์โฮสติ้งของคุณเพื่อทริกเกอร์การเริ่มต้นและเรียกใช้อินสแตนซ์คอนเทนเนอร์ของ helloworld

  1. ทำให้เเน่นอน:

    สำหรับคำแนะนำโดยละเอียดเกี่ยวกับการติดตั้ง CLI และการเริ่มต้นโฮสต์ โปรดดู คู่มือเริ่มต้นใช้งานสำหรับโฮสติ้ง

  2. เปิด ไฟล์ firebase.json ของคุณ

  3. เพิ่มการกำหนดค่าการ rewrite ต่อไปนี้ในส่วน 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)
        }
      } ]
    }
    
  4. ปรับใช้การกำหนดค่าโฮสติ้งของคุณกับไซต์ของคุณโดยเรียกใช้คำสั่งต่อไปนี้จากรูทของไดเร็กทอรีโครงการของคุณ:

    firebase deploy

ขณะนี้สามารถเข้าถึงคอนเทนเนอร์ของคุณผ่าน URL ต่อไปนี้:

ไปที่หน้าการกำหนดค่าโฮสติ้งสำหรับ รายละเอียดเพิ่มเติมเกี่ยวกับกฎการเขียนใหม่ คุณยังสามารถเรียนรู้เกี่ยวกับ ลำดับความสำคัญของการตอบกลับ สำหรับการกำหนดค่าโฮสติ้งต่างๆ

ทดสอบในเครื่อง

ในระหว่างการพัฒนา คุณสามารถเรียกใช้และทดสอบอิมเมจคอนเทนเนอร์ในเครื่องได้ สำหรับคำแนะนำโดยละเอียด โปรดไปที่ เอกสาร Cloud Run

ขั้นตอนถัดไป