วิธีติดตั้งใช้งานเว็บไซต์ Generative UI ใน Cloud Run

1. บทนำ

ภาพรวม

ในแล็บนี้ คุณจะได้สร้างและติดตั้งใช้งานเว็บไซต์ที่มีเนื้อหาซึ่งโมเดลภาษาขนาดใหญ่ Gemini ของ Google สร้างขึ้นแบบเรียลไทม์ เว็บไซต์จะเป็นเครื่องมือสำรวจหัวข้อในรูปแบบ "เลือกเส้นทางของคุณเอง" ที่เรียบง่าย โดยการคลิกแต่ละครั้งจะสร้างหน้าใหม่พร้อมลิงก์ใหม่ตามตัวเลือกของคุณ คุณจะสร้างแอปนี้ด้วย Node.js และ Fastify, ใช้ Vertex AI SDK เพื่อเรียก Gemini, ติดตั้งใช้งานเป็นบริการที่ปลอดภัยและพร้อมใช้งานจริงใน Cloud Run และรักษาความปลอดภัยโดยใช้ Identity-Aware Proxy (IAP)

สิ่งที่คุณต้องดำเนินการ

  • สร้างแอปพลิเคชัน Fastify ของ Node.js ที่ใช้ Vertex AI
  • ติดตั้งใช้งานแอปพลิเคชันไปยัง Cloud Run จากแหล่งที่มาโดยไม่ต้องใช้ Dockerfile
  • รักษาความปลอดภัยให้กับปลายทาง Cloud Run โดยใช้ Identity-Aware Proxy (IAP)

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

  • วิธีใช้ Vertex AI SDK สำหรับ Node.js เพื่อสร้างเนื้อหา
  • วิธีติดตั้งใช้งานแอปพลิเคชัน Node.js ใน Cloud Run
  • วิธีรักษาความปลอดภัยให้แอปพลิเคชัน Cloud Run ด้วย IAP

2. การตั้งค่าโปรเจ็กต์

  1. หากยังไม่มีบัญชี Google คุณต้องสร้างบัญชี Google
    • ใช้บัญชีส่วนตัวแทนบัญชีงานหรือบัญชีโรงเรียน บัญชีงานและบัญชีโรงเรียนอาจมีข้อจำกัดที่ทำให้คุณเปิดใช้ API ที่จำเป็นสำหรับ Lab นี้ไม่ได้
  2. ลงชื่อเข้าใช้ Google Cloud Console
  3. เปิดใช้การเรียกเก็บเงินใน Cloud Console
    • การทำ Lab นี้ควรมีค่าใช้จ่ายน้อยกว่า $1 USD ในทรัพยากรระบบคลาวด์
    • คุณสามารถทำตามขั้นตอนที่ส่วนท้ายของแล็บนี้เพื่อลบทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินเพิ่มเติม
    • ผู้ใช้ใหม่มีสิทธิ์ใช้ช่วงทดลองใช้ฟรีมูลค่า$300 USD
  4. สร้างโปรเจ็กต์ใหม่หรือเลือกใช้โปรเจ็กต์ที่มีอยู่ซ้ำ
    • หากเห็นข้อผิดพลาดเกี่ยวกับโควต้าโปรเจ็กต์ ให้ใช้โปรเจ็กต์ที่มีอยู่ซ้ำหรือลบโปรเจ็กต์ที่มีอยู่เพื่อสร้างโปรเจ็กต์ใหม่

3. เปิดเครื่องมือแก้ไข Cloud Shell

  1. คลิกลิงก์นี้เพื่อไปยัง Cloud Shell Editor โดยตรง
  2. หากระบบแจ้งให้ให้สิทธิ์ในวันนี้ ให้คลิกให้สิทธิ์เพื่อดำเนินการต่อ คลิกเพื่อให้สิทธิ์ Cloud Shell
  3. หากเทอร์มินัลไม่ปรากฏที่ด้านล่างของหน้าจอ ให้เปิดโดยทำดังนี้
    • คลิกดู
    • คลิก Terminalเปิดเทอร์มินัลใหม่ใน Cloud Shell Editor
  4. ในเทอร์มินัล ให้ตั้งค่าโปรเจ็กต์ด้วยคำสั่งนี้
    • รูปแบบ:
      gcloud config set project [PROJECT_ID]
      
    • ตัวอย่าง
      gcloud config set project lab-project-id-example
      
    • หากจำรหัสโปรเจ็กต์ไม่ได้ ให้ทำดังนี้
      • คุณแสดงรหัสโปรเจ็กต์ทั้งหมดได้โดยใช้คำสั่งต่อไปนี้
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      ตั้งค่ารหัสโปรเจ็กต์ในเทอร์มินัล Cloud Shell Editor
  5. คุณควรเห็นข้อความต่อไปนี้
    Updated property [core/project].
    
    หากเห็น WARNING และระบบขอให้คุณ Do you want to continue (Y/n)? แสดงว่าคุณอาจป้อนรหัสโปรเจ็กต์ไม่ถูกต้อง กด n กด Enter แล้วลองเรียกใช้คำสั่ง gcloud config set project อีกครั้ง
  1. ตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_CLOUD_PROJECT
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    

4. เปิดใช้ API

เปิดใช้ API ในเทอร์มินัลโดยทำดังนี้

gcloud services enable \
  run.googleapis.com \
  aiplatform.googleapis.com \
  cloudresourcemanager.googleapis.com \
  iap.googleapis.com

หากได้รับแจ้งให้ให้สิทธิ์ ให้คลิกให้สิทธิ์เพื่อดำเนินการต่อ คลิกเพื่อให้สิทธิ์ Cloud Shell

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

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

5. เตรียมโปรเจ็กต์ Node.js

  1. สร้างโฟลเดอร์ชื่อ gen-ui-on-cloudrun เพื่อจัดเก็บซอร์สโค้ดสำหรับการติดตั้งใช้งาน
    mkdir gen-ui-on-cloudrun && cd gen-ui-on-cloudrun
    
  2. เริ่มต้นโปรเจ็กต์ Node.js โดยทำดังนี้
    npm init -y
    
  3. กำหนดค่าโปรเจ็กต์ให้ใช้โมดูล ES และกำหนดสคริปต์เริ่มต้นโดยเรียกใช้คำสั่งต่อไปนี้
    npm pkg set type="module"
    
  4. ติดตั้ง fastify สำหรับเว็บเซิร์ฟเวอร์และ @google/genai สำหรับ Vertex AI SDK โดยทำดังนี้
    npm install fastify @google/genai
    

6. สร้างโค้ดของแอปพลิเคชัน

  1. สร้างและเปิดไฟล์ index.ts ใหม่สำหรับซอร์สโค้ดของแอปพลิเคชัน
    cloudshell edit ~/gen-ui-on-cloudrun/index.ts
    
    คำสั่ง cloudshell edit จะเปิดไฟล์ index.ts ในเครื่องมือแก้ไขเหนือเทอร์มินัล
  2. เพิ่มซอร์สโค้ดเซิร์ฟเวอร์ UI แบบ Generative ต่อไปนี้ในไฟล์ index.ts
    import fastifyLib from 'fastify';
    import { GoogleGenAI } from '@google/genai';
    
    const fastify = fastifyLib({ logger: true });
    
    const ai = new GoogleGenAI({
        vertexai: true,
        project: process.env.GOOGLE_CLOUD_PROJECT,
        location: process.env.GOOGLE_CLOUD_LOCATION || 'europe-west1',
    });
    
    const SYSTEM_INSTRUCTION = `The user should have submitted an html page and the id of the element just clicked.
    Given the next page description, create a new webpage with a link back to "Start Over" (the / route), a brief overview of the topic, and a list of clickable link elements related to the page.
    When an element is clicked, the webpage should link to the base route / with the nextPageDescription as a query string parameter.
    All information needed to generate the next page should be included in the nextPageDescription without additional context.
    Each nextPageDescription should be less than 1500 characters.
    
    Example:
    If the current HTML page is for a small pet store, it might include a link to an "About" page.
    The href for the about page link should be /?nextPageDescription=about%20page%20for%20small%20pet%20store%20website
    
    All responses should be valid HTML without markdown backticks.`;
    
    interface QueryParams {
        nextPageDescription?: string;
    }
    
    fastify.get<{ Querystring: QueryParams }>('/', async (request, reply) => {
        const {
            nextPageDescription = 'A web page with interesting fun facts where I can select a fact to learn more about that topic.'
        } = request.query;
    
        try {
            const response = await ai.models.generateContent({
                model: 'gemini-2.5-flash',
                contents: nextPageDescription,
                config: {
                    systemInstruction: SYSTEM_INSTRUCTION,
                    temperature: 0.9,
                }
            });
    
            reply.type('text/html; charset=utf-8').send(response.text);
        } catch (error: any) {
            request.log.error(error);
            reply.status(500).send('An error occurred calling the AI.');
        }
    });
    
    const start = async () => {
        try {
            await fastify.listen({ port: Number(process.env.PORT) || 8080, host: '0.0.0.0' });
        } catch (err) {
            fastify.log.error(err);
            process.exit(1);
        }
    };
    
    start();
    

โค้ดนี้จะตั้งค่าเว็บเซิร์ฟเวอร์ที่รอฟังคำขอ HTTP GET ในเส้นทางรูท (/) เมื่อได้รับคำขอ โค้ดจะใช้พารามิเตอร์การค้นหา nextPageDescription (หรือค่าเริ่มต้น) เป็นพรอมต์สำหรับโมเดล Gemini 2.5 Flash ผ่าน Vertex AI โมเดลได้รับคำสั่งจาก SYSTEM_INSTRUCTION ให้แสดงผลหน้า HTML ที่มีลิงก์ โดยแต่ละลิงก์จะมี nextPageDescription สำหรับสร้างหน้าถัดไป

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

คุณต้องมีบัญชีบริการสำหรับบริการ Cloud Run เพื่อตรวจสอบสิทธิ์กับ Vertex AI API

  1. สร้างบัญชีบริการชื่อ gen-navigator-sa โดยทำดังนี้
    gcloud iam service-accounts create gen-navigator-sa --display-name="Generative Navigator Service Account"
    
  2. ให้สิทธิ์บัญชีบริการในการใช้ Vertex AI โดยทำดังนี้
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role="roles/aiplatform.user"
    

8. ทำให้ใช้งานได้กับ Cloud Run

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

  1. เรียกใช้คำสั่ง gcloud เพื่อทำให้แอปพลิเคชันใช้งานได้
    cd ~/gen-ui-on-cloudrun
    gcloud beta run deploy generative-web-navigator \
        --source . \
        --no-build \
        --base-image=nodejs24 \
        --command="node" \
        --args="index.ts" \
        --region=europe-west1 \
        --no-allow-unauthenticated \
        --iap \
        --service-account="gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --set-env-vars GOOGLE_CLOUD_PROJECT="$GOOGLE_CLOUD_PROJECT",GOOGLE_CLOUD_LOCATION="europe-west1"
    
    เราใช้ฟีเจอร์ที่สำคัญ 2-3 อย่างดังนี้
    • --source . --no-build --base-image=nodejs24: คำสั่งนี้จะบอกให้ Cloud Run ทำให้ซอร์สโค้ดจากไดเรกทอรีปัจจุบันใช้งานได้ ข้ามระยะการสร้าง และเรียกใช้แอปพลิเคชันโดยใช้อิมเมจพื้นฐาน Node.js 24 ที่สร้างไว้ล่วงหน้า
    • --no-allow-unauthenticated: วิธีนี้จะช่วยให้มั่นใจได้ว่าเฉพาะผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์เท่านั้นที่จะเข้าถึงบริการได้
    • --iap: การดำเนินการนี้จะช่วยให้ Identity-Aware Proxy (IAP) จัดการการเข้าถึงแอปพลิเคชันได้ IAP ช่วยให้คุณควบคุมการเข้าถึงตามข้อมูลประจำตัวและบริบทของผู้ใช้ แทนที่จะใช้เพียงที่อยู่ IP
  2. หลังจากนั้นไม่กี่นาที คุณจะเห็นข้อความต่อไปนี้
    Service [generative-web-navigator] revision [generative-web-navigator-12345-abc] has been deployed and is serving 100 percent of traffic.
    

คุณได้ติดตั้งใช้งานแอปพลิเคชันแล้ว แต่ยังต้องกำหนดค่า IAP เพื่ออนุญาตการเข้าถึง

9. กำหนดค่าการเข้าถึง IAP

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

  • อนุญาตให้บริการ IAP เรียกใช้บริการ Cloud Run
  • อนุญาตให้ตัวคุณเอง (หรือผู้ใช้/กลุ่มอื่นๆ) เข้าถึงแอปพลิเคชันผ่าน IAP
  1. รับหมายเลขโปรเจ็กต์ซึ่งจำเป็นต่อการระบุตัวแทนบริการ IAP โดยทำดังนี้
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
  2. มอบบทบาท roles/run.invoker ให้กับตัวแทนบริการ IAP ในบริการ Cloud Run ซึ่งช่วยให้ IAP เรียกใช้บริการของคุณได้หลังจากตรวจสอบสิทธิ์และให้สิทธิ์ผู้ใช้
    gcloud run services add-iam-policy-binding generative-web-navigator \
        --region=europe-west1 \
        --member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-iap.iam.gserviceaccount.com" \
        --role="roles/run.invoker"
    
  3. ให้บทบาท roles/iap.httpsResourceAccessor แก่บัญชีผู้ใช้ ซึ่งจะช่วยให้คุณเข้าถึงทรัพยากร HTTPS ที่รักษาความปลอดภัยด้วย IAP ได้
    gcloud beta iap web add-iam-policy-binding \
        --resource-type=cloud-run \
        --region=europe-west1 \
        --service=generative-web-navigator \
        --member="user:$(gcloud config get-value account)" \
        --role="roles/iap.httpsResourceAccessor"
    

10. ทดสอบแอปพลิเคชัน

  1. รับ URL ของบริการที่ใช้งานจริง
    gcloud run services describe generative-web-navigator --format='value(status.url)' --region=europe-west1
    
  2. คัดลอก URL แล้วเปิดในเว็บเบราว์เซอร์ เนื่องจากบริการนี้มีความปลอดภัยด้วย IAP ระบบจะแจ้งให้คุณเข้าสู่ระบบด้วยบัญชี Google หากยังไม่ได้เข้าสู่ระบบ หลังจากตรวจสอบสิทธิ์แล้ว คุณควรเห็นหน้าแรกที่สร้างขึ้นโดยอัตโนมัติ
  3. คลิกลิงก์เพื่อไปยังหน้าใหม่ ซึ่ง AI จะสร้างขึ้นตามลิงก์ที่คุณคลิก

คุณทำสำเร็จแล้ว คุณได้ทําการติดตั้งใช้งานเว็บไซต์ UI แบบ Generative ใน Cloud Run และรักษาความปลอดภัยโดยใช้ IAP เรียบร้อยแล้ว

11. บทสรุป

ยินดีด้วย คุณได้ติดตั้งใช้งานและรักษาความปลอดภัยให้เว็บไซต์ UI แบบ Generative โดยใช้ Cloud Run, Vertex AI และ IAP เรียบร้อยแล้ว

(ไม่บังคับ) ล้างข้อมูล

หากต้องการล้างข้อมูลที่คุณสร้างไว้ คุณสามารถลบโปรเจ็กต์ Cloud เพื่อหลีกเลี่ยงการเรียกเก็บเงินเพิ่มเติม

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

หากต้องการ ให้ลบโปรเจ็กต์โดยทำดังนี้

gcloud projects delete $GOOGLE_CLOUD_PROJECT

นอกจากนี้ คุณอาจต้องการลบทรัพยากรที่ไม่จำเป็นออกจากดิสก์ Cloud Shell ด้วย สิ่งที่คุณทำได้มีดังนี้

  1. ลบไดเรกทอรีโปรเจ็กต์ Codelab
    rm -rf ~/gen-ui-on-cloudrun
    
  2. คำเตือน! การดำเนินการถัดไปนี้จะยกเลิกไม่ได้ หากต้องการลบทุกอย่างใน Cloud Shell เพื่อเพิ่มพื้นที่ว่าง คุณสามารถลบไดเรกทอรีหน้าแรกทั้งหมดได้ โปรดระมัดระวังและตรวจสอบว่าได้บันทึกทุกอย่างที่คุณต้องการเก็บไว้ที่อื่นแล้ว
    sudo rm -rf $HOME