Catch up on everything we announced at this year's Firebase Summit. Learn more

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

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

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

  • เมฆ Run สนับสนุน หลายภาษา (รวมไป Node.js, งูหลามและ Java) เพื่อให้คุณมีความยืดหยุ่นในการใช้ภาษาการเขียนโปรแกรมและกรอบการทำงานของทางเลือกของคุณ
  • เมฆเรียกใช้ โดยอัตโนมัติและแนวนอนเครื่องชั่ง ภาพภาชนะของคุณเพื่อจัดการการร้องขอได้รับแล้วชั่งน้ำหนักลงเมื่อมีความต้องการลดลง
  • คุณ จ่าย สำหรับ CPU, หน่วยความจำและระบบเครือข่ายการบริโภคในระหว่างการจัดการคำขอ

สำหรับกรณีการใช้งานตัวอย่างและตัวอย่างสำหรับการเรียกใช้ระบบคลาวด์แบบบูรณาการกับ Firebase Hosting ไปที่ ภาพรวม serverless


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

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

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

ก่อนจะเริ่ม

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

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

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

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

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

    1. เปิด หน้าเมฆเรียกใช้ API ในคอนโซล Google APIs

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

    3. คลิกเปิดใช้งานบนหน้าเมฆเรียกใช้ API

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

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

    gcloud config list

ขั้นตอนที่ 1: เขียนโปรแกรมตัวอย่าง

โปรดทราบว่าเมฆ 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 ในการจัดการ / การทำแผนที่และยังเพิ่ม @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: containerize แอปและอัปโหลดไปยังตู้คอนเทนเนอร์ Registry

  1. containerize แอปตัวอย่างโดยการสร้างไฟล์ใหม่ชื่อ 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 และสามารถนำกลับมาใช้ใหม่ได้หากต้องการ

โปรดทราบว่าแทนที่จะเมฆรูปร่างคุณสามารถใช้รุ่นที่ติดตั้งภายในของหางเพื่อ สร้างภาชนะของคุณภายใน

ขั้นตอนที่ 3: การจัดวางภาพภาชนะที่มีเมฆเรียกใช้

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

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

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

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

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

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

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

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

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

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

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

  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 ต่อไปนี้:

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

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

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

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