วิธีนำการเปลี่ยนแปลงจาก GitHub ไปใช้ Cloud Run โดยอัตโนมัติด้วย Cloud Build

1. บทนำ

ภาพรวม

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

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

สิ่งที่คุณจะได้เรียนรู้

  • เขียนเว็บแอปพลิเคชัน Express ด้วย Cloud Shell Editor
  • เชื่อมต่อบัญชี GitHub กับ Google Cloud เพื่อการติดตั้งใช้งานอย่างต่อเนื่อง
  • ทำให้แอปพลิเคชันของคุณใช้งานได้โดยอัตโนมัติกับ Cloud Run
  • ดูวิธีใช้ HTMX และ TailwindCSS

2. การตั้งค่าและข้อกำหนด

ข้อกำหนดเบื้องต้น

เปิดใช้งาน Cloud Shell

  1. คลิกเปิดใช้งาน Cloud Shell d1264ca30785e435.png จาก Cloud Console

cb81e7c8e34bc8d.png

หากเริ่มต้นใช้งาน Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอตรงกลางที่อธิบายว่านี่คืออะไร หากระบบแสดงหน้าจอตรงกลาง ให้คลิกต่อไป

d95252b003979716.png

การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที

7833d5e1c5d18f54.png

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

เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นข้อความตรวจสอบสิทธิ์และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว

  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list

เอาต์พุตจากคำสั่ง

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้เกี่ยวกับโปรเจ็กต์ของคุณ
gcloud config list project

เอาต์พุตจากคำสั่ง

[core]
project = <PROJECT_ID>

หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้

gcloud config set project <PROJECT_ID>

เอาต์พุตจากคำสั่ง

Updated property [core/project].

3. เปิดใช้ API และตั้งค่าตัวแปรสภาพแวดล้อม

เปิดใช้ API

Codelab นี้ต้องใช้ API ต่อไปนี้ คุณเปิดใช้ API เหล่านั้นได้โดยเรียกใช้คำสั่งต่อไปนี้

gcloud services enable run.googleapis.com \
    cloudbuild.googleapis.com \
    firestore.googleapis.com \
    iamcredentials.googleapis.com

ตั้งค่าตัวแปรสภาพแวดล้อม

คุณกำหนดตัวแปรสภาพแวดล้อมที่จะใช้ตลอดทั้ง Codelab ได้

REGION=<YOUR-REGION>
PROJECT_ID=<YOUR-PROJECT-ID>
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
SERVICE_ACCOUNT="firestore-accessor"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

4. สร้างบัญชีบริการ

Cloud Run จะใช้บัญชีบริการนี้เพื่อเรียกใช้ Vertex AI Gemini API บัญชีบริการนี้จะมีสิทธิ์ในการอ่านและเขียนใน Firestore รวมถึงอ่านข้อมูลลับจาก Secret Manager ด้วย

ก่อนอื่น ให้สร้างบัญชีบริการโดยเรียกใช้คำสั่งนี้

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run access to Firestore"

จากนั้นให้สิทธิ์การอ่านและเขียน Firestore แก่บัญชีบริการ

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/datastore.user

5. สร้างและกำหนดค่าโปรเจ็กต์ Firebase

  1. ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์
  2. ป้อน <YOUR_PROJECT_ID> เพื่อเพิ่ม Firebase ไปยังหนึ่งในโปรเจ็กต์ Google Cloud ที่คุณมีอยู่
  3. หากได้รับข้อความแจ้ง ให้ตรวจสอบและยอมรับข้อกำหนดของ Firebase
  4. คลิกต่อไป
  5. คลิกยืนยันแผนเพื่อยืนยันแผนการเรียกเก็บเงินของ Firebase
  6. คุณเลือกที่จะเปิดใช้ Google Analytics สำหรับ Codelab หรือไม่ก็ได้
  7. คลิกเพิ่ม Firebase
  8. เมื่อสร้างโปรเจ็กต์แล้ว ให้คลิกต่อไป
  9. จากเมนู Build ให้คลิกฐานข้อมูล Firestore
  10. คลิกสร้างฐานข้อมูล
  11. เลือกภูมิภาคจากเมนูแบบเลื่อนลงสถานที่ แล้วคลิกถัดไป
  12. ใช้ค่าเริ่มต้นเริ่มต้นในโหมดใช้งานจริง จากนั้นคลิกสร้าง

6. เขียนแอปพลิเคชัน

ขั้นแรก ให้สร้างไดเรกทอรีสำหรับซอร์สโค้ดและ cd ลงในไดเรกทอรีนั้น

mkdir cloud-run-github-cd-demo && cd $_

จากนั้นสร้างไฟล์ package.json ที่มีเนื้อหาต่อไปนี้

{
  "name": "cloud-run-github-cd-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node app.js",
    "nodemon": "nodemon app.js",
    "tailwind-dev": "npx tailwindcss -i ./input.css -o ./public/output.css --watch",
    "tailwind": "npx tailwindcss -i ./input.css -o ./public/output.css",
    "dev": "npm run tailwind && npm run nodemon"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@google-cloud/firestore": "^7.3.1",
    "axios": "^1.6.7",
    "express": "^4.18.2",
    "htmx.org": "^1.9.10"
  },
  "devDependencies": {
    "nodemon": "^3.1.0",
    "tailwindcss": "^3.4.1"
  }
}

ก่อนอื่นให้สร้างไฟล์ต้นฉบับ app.js ที่มีเนื้อหาด้านล่าง ไฟล์นี้ประกอบด้วยจุดแรกเข้าสำหรับบริการและประกอบด้วยตรรกะหลักสำหรับแอป

const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const path = require("path");
const { get } = require("axios");

const { Firestore } = require("@google-cloud/firestore");
const firestoreDb = new Firestore();

const fs = require("fs");
const util = require("util");
const { spinnerSvg } = require("./spinnerSvg.js");

const service = process.env.K_SERVICE;
const revision = process.env.K_REVISION;

app.use(express.static("public"));

app.get("/edit", async (req, res) => {
    res.send(`<form hx-post="/update" hx-target="this" hx-swap="outerHTML">
                <div>
  <p>
    <label>Name</label>    
    <input class="border-2" type="text" name="name" value="Cloud">
    </p><p>
    <label>Town</label>    
    <input class="border-2" type="text" name="town" value="Nibelheim">
    </p>
  </div>
  <div class="flex items-center mr-[10px] mt-[10px]">
  <button class="btn bg-blue-500 text-white px-4 py-2 rounded-lg text-center text-sm font-medium mr-[10px]">Submit</button>
  <button class="btn bg-gray-200 text-gray-800 px-4 py-2 rounded-lg text-center text-sm font-medium mr-[10px]" hx-get="cancel">Cancel</button>  
                ${spinnerSvg} 
                </div>
  </form>`);
});

app.post("/update", async function (req, res) {
    let name = req.body.name;
    let town = req.body.town;
    const doc = firestoreDb.doc(`demo/${name}`);

    //TODO: fix this bug
    await doc.set({
        name: name
        /* town: town */
    });

    res.send(`<div hx-target="this" hx-swap="outerHTML" hx-indicator="spinner">
                <p>
                <div><label>Name</label>: ${name}</div>
                </p><p>
                <div><label>Town</label>: ${town}</div>
                </p>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>               
            </div>`);
});

app.get("/cancel", (req, res) => {
    res.send(`<div hx-target="this" hx-swap="outerHTML">
                <p>
                <div><label>Name</label>: Cloud</div>
                </p><p>
                <div><label>Town</label>: Nibelheim</div>
                </p>
                <div>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>                
                </div>
            </div>`);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, async () => {
    console.log(`booth demo: listening on port ${port}`);

    //serviceMetadata = helper();
});

app.get("/helper", async (req, res) => {
    let region = "";
    let projectId = "";
    let div = "";

    try {
        // Fetch the token to make a GCF to GCF call
        const response1 = await get(
            "http://metadata.google.internal/computeMetadata/v1/project/project-id",
            {
                headers: {
                    "Metadata-Flavor": "Google"
                }
            }
        );

        // Fetch the token to make a GCF to GCF call
        const response2 = await get(
            "http://metadata.google.internal/computeMetadata/v1/instance/region",
            {
                headers: {
                    "Metadata-Flavor": "Google"
                }
            }
        );

        projectId = response1.data;
        let regionFull = response2.data;
        const index = regionFull.lastIndexOf("/");
        region = regionFull.substring(index + 1);

        div = `
        <div>
        This created the revision <code>${revision}</code> of the 
        Cloud Run service <code>${service}</code> in <code>${region}</code>
        for project <code>${projectId}</code>.
        </div>`;
    } catch (ex) {
        // running locally
        div = `<div> This is running locally.</div>`;
    }

    res.send(div);
});

สร้างไฟล์ชื่อ spinnerSvg.js

module.exports.spinnerSvg = `<svg id="spinner" alt="Loading..."
                    class="htmx-indicator animate-spin -ml-1 mr-3 h-5 w-5 text-blue-500"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 24 24"
                >
                    <circle
                        class="opacity-25"
                        cx="12"
                        cy="12"
                        r="10"
                        stroke="currentColor"
                        stroke-width="4"
                    ></circle>
                    <path
                        class="opacity-75"
                        fill="currentColor"
                        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                    ></path>
                </svg>`;

สร้างไฟล์ input.css สำหรับ tailwindCSS

@tailwind base;
@tailwind components;
@tailwind utilities;

และสร้างไฟล์ tailwind.config.js สำหรับ tailwindCSS

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: ["./**/*.{html,js}"],
    theme: {
        extend: {}
    },
    plugins: []
};

และสร้างไฟล์ .gitignore

node_modules/

npm-debug.log
coverage/

package-lock.json

.DS_Store

จากนั้นสร้างไดเรกทอรี public ใหม่

mkdir public
cd public

และภายในไดเรกทอรีสาธารณะนั้น ให้สร้างไฟล์ index.html สำหรับส่วนหน้า ซึ่งจะใช้ htmx

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
        />
        <script
            src="https://unpkg.com/htmx.org@1.9.10"
            integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
            crossorigin="anonymous"
        ></script>

        <link href="./output.css" rel="stylesheet" />
        <title>Demo 1</title>
    </head>
    <body
        class="font-sans bg-body-image bg-cover bg-center leading-relaxed"
    >
        <div class="container max-w-[700px] mt-[50px] ml-auto mr-auto">
            <div class="hero flex items-center">                    
                <div class="message text-base text-center mb-[24px]">
                    <h1 class="text-2xl font-bold mb-[10px]">
                        It's running!
                    </h1>
                    <div class="congrats text-base font-normal">
                        Congratulations, you successfully deployed your
                        service to Cloud Run. 
                    </div>
                </div>
            </div>

            <div class="details mb-[20px]">
                <p>
                    <div hx-trigger="load" hx-get="/helper" hx-swap="innerHTML" hx-target="this">Hello</div>                   
                </p>
            </div>

            <p
                class="callout text-sm text-blue-700 font-bold pt-4 pr-6 pb-4 pl-10 leading-tight"
            >
                You can deploy any container to Cloud Run that listens for
                HTTP requests on the port defined by the
                <code>PORT</code> environment variable. Cloud Run will
                scale automatically based on requests and you never have to
                worry about infrastructure.
            </p>

            <h1 class="text-2xl font-bold mt-[40px] mb-[20px]">
                Persistent Storage Example using Firestore
            </h1>
            <div hx-target="this" hx-swap="outerHTML">
                <p>
                <div><label>Name</label>: Cloud</div>
                </p><p>
                <div><label>Town</label>: Nibelheim</div>
                </p>
                <div>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>                
                </div>
            </div>

            <h1 class="text-2xl font-bold mt-[40px] mb-[20px]">
                What's next
            </h1>
            <p class="next text-base mt-4 mb-[20px]">
                You can build this demo yourself!
            </p>
            <p class="cta">
                <button
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-center text-sm font-medium"
                >
                    VIEW CODELAB
                </button>
            </p> 
        </div>
   </body>
</html>

7. เรียกใช้แอปพลิเคชันในเครื่อง

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

ก่อนอื่น คุณจะต้องมีบทบาทผู้ใช้ Datastore เพื่อเข้าถึง Firestore (หากใช้ข้อมูลประจำตัวในการตรวจสอบสิทธิ์ เช่น คุณกำลังเรียกใช้ใน Cloud Shell) หรือสวมบทบาทเป็นบัญชีผู้ใช้ที่สร้างไว้ก่อนหน้านี้ก็ได้

การใช้ ADC เมื่อทำงานในเครื่อง

หากคุณเรียกใช้ใน Cloud Shell ก็หมายความว่าคุณกำลังทำงานบนเครื่องเสมือนของ Google Compute Engine อยู่แล้ว ข้อมูลเข้าสู่ระบบเริ่มต้นแอปพลิเคชัน (ADC) จะใช้ข้อมูลเข้าสู่ระบบของคุณที่เชื่อมโยงกับเครื่องเสมือนนี้ (ตามที่แสดงโดยการเรียกใช้ gcloud auth list) โดยอัตโนมัติ คุณจึงไม่จำเป็นต้องใช้คำสั่ง gcloud auth application-default login อย่างไรก็ตาม ข้อมูลระบุตัวตนของคุณยังคงต้องมีบทบาทผู้ใช้ Datastore คุณสามารถข้ามไปยังส่วนเรียกใช้แอปในเครื่อง

แต่หากคุณกำลังทำงานบนเทอร์มินัลในเครื่อง (ไม่ใช่ใน Cloud Shell) คุณจะต้องใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชันเพื่อตรวจสอบสิทธิ์ Google APIs วิธีการ 1) เข้าสู่ระบบโดยใช้ข้อมูลเข้าสู่ระบบ (ในกรณีที่คุณมีบทบาทผู้ใช้ Datastore) หรือ 2) คุณสามารถเข้าสู่ระบบโดยแอบอ้างบัญชีบริการที่ใช้ใน Codelab นี้

ตัวเลือกที่ 1) การใช้ข้อมูลเข้าสู่ระบบสำหรับ ADC

หากต้องการใช้ข้อมูลเข้าสู่ระบบ ให้เรียกใช้ gcloud auth list เพื่อยืนยันวิธีตรวจสอบสิทธิ์ใน gcloud ก่อน ถัดไป คุณอาจต้องมอบบทบาทผู้ใช้ Vertex AI ให้กับข้อมูลระบุตัวตนของคุณ หากข้อมูลประจำตัวของคุณมีบทบาทเจ้าของ แสดงว่าคุณมีบทบาทของผู้ใช้พื้นที่เก็บข้อมูลนี้แล้ว หากไม่มี ให้เรียกใช้คำสั่งนี้เพื่อมอบบทบาทของผู้ใช้ Vertex AI และบทบาทผู้ใช้ Datastore

USER=<YOUR_PRINCIPAL_EMAIL>

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member user:$USER \
  --role=roles/datastore.user

จากนั้นเรียกใช้คำสั่งต่อไปนี้

gcloud auth application-default login

ตัวเลือกที่ 2) การแอบอ้างเป็นบัญชีบริการสำหรับ ADC

หากต้องการใช้บัญชีบริการที่สร้างใน Codelab นี้ บัญชีผู้ใช้ของคุณจะต้องมีบทบาทผู้สร้างโทเค็นบัญชีบริการ คุณสามารถรับบทบาทนี้ได้โดยการเรียกใช้คำสั่งต่อไปนี้:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member user:$USER \
  --role=roles/iam.serviceAccountTokenCreator

ถัดไป คุณจะต้องเรียกใช้คำสั่งต่อไปนี้เพื่อใช้ ADC กับบัญชีบริการ

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

เรียกใช้แอปในเครื่อง

ถัดไป ตรวจสอบว่าคุณอยู่ในไดเรกทอรีราก cloud-run-github-cd-demo สำหรับ Codelab

cd .. && pwd

ถึงตอนนี้คุณจะต้องติดตั้งทรัพยากร Dependency

npm install

สุดท้าย คุณสามารถเริ่มแอปได้โดยเรียกใช้สคริปต์ต่อไปนี้ สคริปต์นี้จะสร้างไฟล์ Export.css จาก tailwindCSS ด้วย

npm run dev

จากนั้นเปิดเว็บเบราว์เซอร์ที่ http://localhost:8080 หากอยู่ใน Cloud Shell คุณจะเปิดเว็บไซต์ได้โดยเปิดปุ่มแสดงตัวอย่างเว็บและเลือก "แสดงตัวอย่างพอร์ต 8080"

การแสดงตัวอย่างเว็บ - ปุ่มแสดงตัวอย่างบนพอร์ต 8080

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

หยุดแอป Express ไม่ให้ทำงานภายในเครื่อง (เช่น Ctrl^c ใน MacOS)

8. สร้างที่เก็บ GitHub

ในไดเรกทอรีในเครื่อง ให้สร้างที่เก็บใหม่โดยมีหลักเป็นชื่อสาขาเริ่มต้น

git init
git branch -M main

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

git add .
git commit -m "first commit for express application"

ไปที่ GitHub และสร้างที่เก็บที่ว่างเปล่าซึ่งเป็นส่วนตัวสำหรับคุณหรือสาธารณะ Codelab นี้แนะนำให้ตั้งชื่อที่เก็บของคุณ cloud-run-auto-deploy-codelab หากต้องการสร้างที่เก็บที่ว่างเปล่า คุณจะต้องปล่อยการตั้งค่าเริ่มต้นทั้งหมดไว้โดยไม่เลือกหรือตั้งค่าเป็น ไม่มี เพื่อให้เนื้อหาไม่อยู่ในที่เก็บโดยค่าเริ่มต้นเมื่อสร้าง เช่น

การตั้งค่าเริ่มต้นของ GitHub

หากทำตามขั้นตอนนี้อย่างถูกต้องแล้ว คุณจะเห็นคำแนะนำต่อไปนี้ในหน้าที่เก็บที่ว่างเปล่า

วิธีการสำหรับที่เก็บ GitHub ที่ว่างเปล่า

คุณจะทำตามวิธีพุชที่เก็บที่มีอยู่จากบรรทัดคำสั่งได้โดยการเรียกใช้คำสั่งต่อไปนี้

ก่อนอื่นให้เพิ่มที่เก็บระยะไกลโดยการเรียกใช้

git remote add origin <YOUR-REPO-URL-PER-GITHUB-INSTRUCTIONS>

จากนั้นพุช Branch หลักไปยังที่เก็บอัปสตรีม

git push -u origin main

9. ตั้งค่าการทำให้ใช้งานได้อย่างต่อเนื่อง

เมื่อคุณมีโค้ดใน GitHub แล้ว คุณก็สามารถตั้งค่าการทำให้ใช้งานได้อย่างต่อเนื่อง ไปที่ Cloud Console for Cloud Run

  • คลิกสร้างบริการ
  • คลิกทำให้ใช้งานได้อย่างต่อเนื่องจากที่เก็บ
  • คลิกตั้งค่า Cloud BUILD
  • ภายใต้ที่เก็บซอร์ส
    • เลือก GitHub เป็นผู้ให้บริการที่เก็บ
    • คลิกจัดการที่เก็บที่เชื่อมต่อเพื่อกำหนดค่าการเข้าถึงที่เก็บของ Cloud Build
    • เลือกที่เก็บแล้วคลิกถัดไป
  • ภายใต้การกำหนดค่าบิลด์
    • ปล่อยให้ Branch เป็น ^main$
    • สำหรับประเภทบิลด์ ให้เลือก Go, Node.js, Python, Java, .NET Core, Ruby หรือ PHP ผ่านบิลด์แพ็กของ Google Cloud
  • ออกจากไดเรกทอรีบริบทของบิลด์เป็น /
  • คลิกบันทึก
  • ภายใต้การตรวจสอบสิทธิ์
    • คลิก อนุญาตการเรียกใช้ที่ไม่ผ่านการตรวจสอบสิทธิ์
  • ภายใต้คอนเทนเนอร์ วอลุ่ม เครือข่าย ความปลอดภัย
    • ในแท็บ "ความปลอดภัย" ให้เลือกบัญชีบริการที่สร้างไว้ในขั้นตอนก่อนหน้า เช่น Cloud Run access to Firestore
  • คลิกสร้าง

การดำเนินการนี้จะทำให้บริการ Cloud Run ที่มีข้อบกพร่องซึ่งคุณจะได้แก้ไขในส่วนถัดไปใช้งานได้

10. แก้ไขข้อบกพร่อง

แก้ไขข้อบกพร่องในโค้ด

ใน Cloud Shell Editor ให้เพิ่มไฟล์ app.js แล้วไปที่ความคิดเห็นที่ระบุว่า //TODO: fix this bug

เปลี่ยนบรรทัดต่อไปนี้จาก

 //TODO: fix this bug
    await doc.set({
        name: name
    });

ถึง

//fixed town bug
    await doc.set({
        name: name,
        town: town
    });

ยืนยันการแก้ไขโดยการเรียกใช้

npm run start

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

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

git add .
git commit -m "fixed town bug"

แล้วพุชไปยังที่เก็บอัปสตรีมบน GitHub

git push origin main

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

ยืนยันการแก้ไขในเวอร์ชันที่ใช้งานจริง

เมื่อ Cloud Console สำหรับบริการ Cloud Run แสดงให้เห็นว่าการแก้ไขที่ 2 กำลังให้บริการรับส่งข้อมูล 100% แล้ว เช่น https://console.cloud.google.com/run/detail/<YOUR_REGION>/<YOUR_SERVICE_NAME>/revisions คุณสามารถเปิด URL บริการ Cloud Run ในเบราว์เซอร์และตรวจสอบว่าข้อมูลของเมืองที่ป้อนใหม่ยังคงอยู่หลังจากรีเฟรชหน้าเว็บ

11. ยินดีด้วย

ขอแสดงความยินดีที่เรียน Codelab จนจบ

เราขอแนะนำให้อ่านเอกสารประกอบเกี่ยวกับ Cloud Run และการทำให้ใช้งานได้อย่างต่อเนื่องจาก git

หัวข้อที่ครอบคลุม

  • เขียนเว็บแอปพลิเคชัน Express ด้วย Cloud Shell Editor
  • เชื่อมต่อบัญชี GitHub กับ Google Cloud เพื่อการติดตั้งใช้งานอย่างต่อเนื่อง
  • ทำให้แอปพลิเคชันของคุณใช้งานได้โดยอัตโนมัติกับ Cloud Run
  • ดูวิธีใช้ HTMX และ TailwindCSS

12. ล้างข้อมูล

เพื่อหลีกเลี่ยงการเรียกเก็บเงินที่ไม่ตั้งใจ (เช่น หากมีการเรียกใช้บริการ Cloud Run โดยไม่ได้ตั้งใจมากกว่าการจัดสรรการเรียกใช้ Cloud Run รายเดือนในรุ่นฟรี) คุณจะลบ Cloud Run หรือลบโปรเจ็กต์ที่สร้างไว้ในขั้นตอนที่ 2 ก็ได้

หากต้องการลบบริการ Cloud Run ให้ไปที่ Cloud Run บน Cloud Console ที่ https://console.cloud.google.com/run แล้วลบบริการ Cloud Run ที่คุณสร้างไว้ใน Codelab เช่น ลบบริการ cloud-run-auto-deploy-codelab

หากเลือกลบทั้งโปรเจ็กต์ ให้ไปที่ https://console.cloud.google.com/cloud-resource-manager เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 แล้วเลือกลบ หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณสามารถดูรายการโปรเจ็กต์ที่ใช้ได้ทั้งหมดโดยเรียกใช้ gcloud projects list