با Cloud Run، محتوای پویا را ارائه دهید و میکروسرویس ها را میزبانی کنید

Cloud Run با Firebase Hosting جفت کنید تا محتوای پویا خود را تولید و ارائه دهید یا API های REST را به عنوان ریزسرویس بسازید.

با استفاده از Cloud Run ، می‌توانید یک برنامه بسته‌بندی شده در یک تصویر ظرف را مستقر کنید. سپس، با استفاده از Firebase Hosting ، می‌توانید درخواست‌های HTTPS را برای راه‌اندازی برنامه کانتینری خود هدایت کنید.

به عنوان مثال از موارد و نمونه‌ها برای Cloud Run یکپارچه با Firebase Hosting استفاده کنید، از نمای کلی بدون سرور ما دیدن کنید.


این راهنما به شما نشان می دهد که چگونه:

  1. یک برنامه ساده Hello World بنویسید
  2. یک برنامه را کانتینر کنید و آن را در Container Registry آپلود کنید
  3. تصویر کانتینر را در Cloud Run مستقر کنید
  4. درخواست های Hosting مستقیم به برنامه کانتینری شما

توجه داشته باشید که برای بهبود عملکرد ارائه محتوای پویا، می‌توانید به صورت اختیاری تنظیمات حافظه پنهان خود را تنظیم کنید.

قبل از شروع

قبل از استفاده از Cloud Run ، باید چند کار اولیه از جمله راه‌اندازی حساب Cloud Billing ، فعال کردن Cloud Run API و نصب ابزار خط فرمان gcloud را انجام دهید.

صورتحساب پروژه خود را تنظیم کنید

Cloud Run سهمیه استفاده رایگان را ارائه می دهد، اما برای استفاده یا امتحان کردن Cloud Run همچنان باید یک حساب Cloud Billing مرتبط با پروژه Firebase خود داشته باشید.

API را فعال کرده و SDK را نصب کنید

  1. Cloud Run API را در کنسول Google APIs فعال کنید:

    1. صفحه Cloud Run API را در کنسول Google APIs باز کنید.

    2. وقتی از شما خواسته شد، پروژه Firebase خود را انتخاب کنید.

    3. در صفحه Cloud Run API روی Enable کلیک کنید.

  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.21.1"
      }
    }
    
  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 بارگذاری شود.

پایتون

  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 بارگذاری شود.

جاوا

  1. جاوا 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 : یک برنامه را کانتینر کنید و آن را در 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:latest AS builder
    
    ARG TARGETOS
    ARG TARGETARCH
    
    # Create and change to the app directory.
    WORKDIR /app
    
    # Copy local code to the container image.
    COPY . ./
    
    # Install dependencies and tidy up the go.mod and go.sum files.
    RUN go mod tidy
    
    # 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" ]
    

    پایتون

    # 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
    

    جاوا

    # 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. با اجرای دستور زیر از دایرکتوری حاوی Dockerfile، تصویر کانتینر خود را با استفاده از Cloud Build بسازید:

    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. وقتی از شما خواسته شد:

برای بهترین عملکرد، سرویس Cloud Run خود را با Hosting با استفاده از مناطق زیر یکجا قرار دهید:

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

بازنویسی در Cloud Run از Hosting در مناطق زیر پشتیبانی می شود:

  • asia-east1
  • asia-east2
  • asia-northeast1
  • asia-northeast2
  • asia-northeast3
  • asia-south1
  • asia-south2
  • asia-southeast1
  • asia-southeast2
  • australia-southeast1
  • australia-southeast2
  • europe-central2
  • europe-north1
  • europe-southwest1
  • europe-west1
  • europe-west12
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west6
  • europe-west8
  • europe-west9
  • me-central1
  • me-west1
  • northamerica-northeast1
  • northamerica-northeast2
  • southamerica-east1
  • southamerica-west1
  • us-central1
  • us-east1
  • us-east4
  • us-east5
  • us-south1
  • us-west1
  • us-west2
  • us-west3
  • us-west4
  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1
  1. چند لحظه صبر کنید تا استقرار کامل شود. در صورت موفقیت، خط فرمان URL سرویس را نمایش می دهد. به عنوان مثال: https://helloworld- RANDOM_HASH -us-central1.a.run.app

  2. با باز کردن URL سرویس در یک مرورگر وب، از کانتینر مستقر شده خود دیدن کنید.

مرحله بعدی نحوه دسترسی به این برنامه کانتینری شده از URL Firebase Hosting را به شما نشان می دهد تا بتواند محتوای پویا برای سایت میزبان Firebase شما تولید کند.

مرحله 4: درخواست های میزبانی را به برنامه کانتینری خود مستقیم کنید

با بازنویسی قوانین ، می‌توانید درخواست‌هایی را که با الگوهای خاص مطابقت دارند به یک مقصد هدایت کنید.

مثال زیر نشان می‌دهد که چگونه می‌توانید تمام درخواست‌ها را از صفحه /helloworld در سایت Hosting خود هدایت کنید تا راه‌اندازی و اجرای نمونه کانتینر helloworld خود را آغاز کنید.

  1. اطمینان حاصل کنید که:

    برای دستورالعمل های دقیق در مورد نصب CLI و مقداردهی اولیه Hosting ، به راهنمای شروع برای 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)
          "pinTag": true              // optional (see note below)
        }
      } ]
    }
  4. با اجرای دستور زیر از ریشه دایرکتوری پروژه خود، پیکربندی هاست خود را در سایت خود قرار دهید:

    firebase deploy --only hosting

اکنون ظرف شما از طریق URL های زیر قابل دسترسی است:

  • زیر دامنه های Firebase شما:
    PROJECT_ID .web.app/ و PROJECT_ID .firebaseapp.com/

  • هر دامنه سفارشی متصل:
    CUSTOM_DOMAIN /

برای جزئیات بیشتر در مورد قوانین بازنویسی، از صفحه پیکربندی Hosting بازدید کنید. همچنین می‌توانید با ترتیب اولویت پاسخ‌ها برای پیکربندی‌های مختلف Hosting آشنا شوید.

به صورت محلی تست کنید

در طول توسعه، می توانید تصویر کانتینر خود را به صورت محلی اجرا و آزمایش کنید. برای دستورالعمل‌های دقیق، از مستندات Cloud Run دیدن کنید.

مراحل بعدی