คู่มือการ Deploy ระบบ dschool Attendance API ขึ้น Google Cloud Run อย่างละเอียด (ฉบับสมบูรณ์)

คู่มือฉบับปรับปรุงใหม่นี้จัดทำขึ้นสำหรับผู้ที่ต้องการนำระบบ dschool Attendance API ขึ้นไปรันบนระบบคลาวด์ Google Cloud Platform (GCP) โดยได้รับการตรวจสอบความถูกต้องทุกตัวอักษรเทียบกับเอกสารทางการของ Google Cloud เพื่อให้สามารถรันคำสั่งตามลำดับแล้วใช้งานได้จริง 100% โดยไม่ติดปัญหาเรื่องสิทธิ์ (IAM Permissions) หรือข้อผิดพลาดทางเทคนิค

1. สิ่งที่ต้องเตรียมล่วงหน้า (Prerequisites)

  1. บัญชี Google Cloud Platform (GCP):
    • มีบัญชี Google และเปิดใช้งาน Google Cloud Console (console.cloud.google.com)
    • มีการผูก Billing Account (บัตรเครดิต/เดบิต) เพื่อรับสิทธิ์เครดิตทดลองใช้งานฟรี $300 (Free Trial 90 วัน)
  2. Google Cloud SDK (gcloud CLI):
    • ติดตั้งบนเครื่องคอมพิวเตอร์ของคุณแล้ว (ตรวจสอบโดยพิมพ์ gcloud --version ใน Terminal)
  3. ซอร์สโค้ดโปรเจกต์:
    • โฟลเดอร์โปรเจกต์ที่มีไฟล์ Dockerfile, go.mod, โฟลเดอร์ cmd/, internal/ และ data/api_keys.json

2. ภาพรวมสถาปัตยกรรมระบบ (System Architecture)

ระบบถูกออกแบบให้มีความคุ้มค่าสูงสุด (ค่าใช้จ่ายจริงต่ำกว่า ~0.05 บาท/เดือน) และตอบสนองรวดเร็วที่สุด:

devices
Client / ผู้ใช้งาน
LINE Bot / Web / App
HTTPS /api/... arrow_forward
Google Cloud Platform
cloud_queue
Google Cloud Run
Region: Bangkok (asia-southeast3)
folder
Cloud Storage (Volume Mount)
/app/data/api_keys.json (IAM Verified)
memory
In-Memory Cache (RAM)
แคช 1-5 นาที (~50ms response)
Fetch Data arrow_forward
school
dschool System
gp-education.com
  • Google Cloud Run: รันเซิร์ฟเวอร์ Go API จะทำงานเฉพาะตอนมี Request เข้ามา และดับเครื่องเองเมื่อไม่มีการใช้งาน (min-instances=0)
  • Google Cloud Storage (GCS Volume Mount): ทำหน้าที่เสมือนฮาร์ดดิสก์เก็บไฟล์ api_keys.json ป้องกันข้อมูล Key หายแม้เซิร์ฟเวอร์จะดับลง
  • In-Memory Cache: เก็บผลลัพธ์ไว้ใน RAM ชั่วคราว ทำให้การเรียกดูซ้ำตอบสนองไวถึง ~50ms

ขั้นตอนที่ 1: ติดตั้งเครื่องมือและเข้าสู่ระบบ GCP

เปิดโปรแกรม Terminal (บน Mac/Linux) หรือ PowerShell (บน Windows) แล้วทำตามขั้นตอน:

  1. ตรวจสอบว่ามี gcloud หรือยัง:

    gcloud --version

    (ถ้ายังไม่มี ให้ดาวน์โหลดและติดตั้งจาก Google Cloud SDK Install Guide)

  2. ล็อกอินเข้าสู่ระบบ Google Cloud:

    gcloud auth login

    ระบบจะเปิดเบราว์เซอร์ ให้ล็อกอินด้วยอีเมล Google ที่มีสิทธิ์จัดการโปรเจกต์ และกดยอมรับสิทธิ์

  3. ล็อกอิน Application Default Credentials (สำหรับการเข้าถึงสิทธิ์เบื้องหลัง):

    gcloud auth application-default login

ขั้นตอนที่ 2: ตั้งค่า Project, บริการ และ Artifact Registry

  1. กำหนดตัวแปรประจำโปรเจกต์:
    ก๊อปปี้คำสั่งด้านล่างไปวางใน Terminal เพื่อตั้งค่าตัวแปร:

    export PROJECT_ID="krittamark-lab"
    export REGION="asia-southeast3"
    export SERVICE_NAME="dschool-attendance-api"
    export BUCKET_NAME="dschool-keystore-krittamark"
    export REPO_NAME="cloud-run-source-deploy"
    export IMAGE_TAG="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${SERVICE_NAME}:latest"
    export API_KEY="XXXXXX"
  2. ตั้งค่า Default Project ใน gcloud CLI:

    gcloud config set project ${PROJECT_ID}
  3. เปิดใช้งาน API ต่าง ๆ บน Google Cloud:

    gcloud services enable \
      run.googleapis.com \
      cloudbuild.googleapis.com \
      artifactregistry.googleapis.com \
      storage.googleapis.com

    (ขั้นตอนนี้อาจใช้เวลาประมาณ 30 - 60 วินาที ในการเปิดใช้งานบริการต่าง ๆ)

  4. สร้าง Artifact Registry Repository (ป้องกัน Error ในขั้นตอน Build):

    gcloud artifacts repositories create ${REPO_NAME} \
      --repository-format=docker \
      --location=${REGION} \
      --description="Docker repository for Cloud Run deployments" \
      --project=${PROJECT_ID} || true

    (คำสั่งใส่ || true ไว้ หากเคยมี Repository อยู่แล้วคำสั่งจะไม่หยุดทำงาน)

ขั้นตอนที่ 3: สร้าง Cloud Storage Bucket และผูกสิทธิ์ IAM (Keystore)

เนื่องจาก Cloud Run มีสถานะแบบ Stateless เราจึงใช้ Cloud Storage Mount เป็น Volume เสมือนฮาร์ดดิสก์ในเครื่อง โดยต้องตั้งค่าสิทธิ์ให้ Service Account เข้าถึงไฟล์ได้ถูกต้องตามมาตรฐานความปลอดภัยของ Google Cloud:

  1. สร้าง Bucket ในภูมิภาคกรุงเทพฯ (asia-southeast3):

    gcloud storage buckets create gs://${BUCKET_NAME} \
      --location=${REGION} \
      --project=${PROJECT_ID}
  2. เตรียมไฟล์ data/api_keys.json:
    ตรวจดูว่าในเครื่องของคุณมีไฟล์ data/api_keys.json ที่มีโครงสร้างดังนี้:

    [
      {
        "key": "XXXXXX",
        "name": "Production API Key",
        "is_active": true,
        "role": "admin",
        "created_at": "2026-09-08T20:42:55+07:00"
      }
    ]
  3. อัปโหลดไฟล์ Keystore ขึ้นไปยัง Bucket:

    gcloud storage cp data/api_keys.json gs://${BUCKET_NAME}/api_keys.json
  4. ผูกสิทธิ์ IAM ให้กับ Cloud Run Service Account (ขั้นตอนสำคัญที่สุด):
    Cloud Run Container จะรันภายใต้ Default Compute Service Account ซึ่งจำเป็นต้องได้รับสิทธิ์ roles/storage.objectUser ในการอ่านและเขียนไฟล์ใน Bucket มิฉะนั้น Container จะ Crash หรือติด Error Permission Denied:

    # 1. ดึง Project Number อัตโนมัติ
    PROJECT_NUMBER=(gcloud projects describe ${PROJECT_ID} --format='value(projectNumber)')
    
    # 2. ผูกสิทธิ์ Storage Object User ให้กับ Service Account
    gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \
      --member="serviceAccount:${PROJECT_NUMBER}[email protected]" \
      --role="roles/storage.objectUser" \
      --project=${PROJECT_ID}

ขั้นตอนที่ 4: Build Container Image ด้วย Cloud Build

เราจะใช้ Google Cloud Build ในการคอมไพล์โค้ด Go และสร้าง Docker Container Image บนคลาวด์โดยตรง ทำให้คุณไม่จำเป็นต้องลงโปรแกรม Docker ในเครื่องตัวเอง:

  1. ตรวจสอบให้แน่ใจว่าคุณอยู่ในโฟลเดอร์โปรเจกต์ (โฟลเดอร์ที่มีไฟล์ Dockerfile):

    ls Dockerfile
  2. สั่งเริ่มการ Build และ Push ขึ้น Artifact Registry:

    gcloud builds submit \
      --tag ${IMAGE_TAG} \
      --project=${PROJECT_ID}

    (ขั้นตอนนี้ใช้เวลาประมาณ 1 ถึง 1.5 นาที เมื่อเสร็จสิ้นจะขึ้นสถานะ SUCCESS)

ขั้นตอนที่ 5: Deploy ขึ้น Cloud Run (Bangkok Region)

สั่งรัน Service บน Cloud Run พร้อมตั้งค่าความปลอดภัย, ขนาดทรัพยากร, และผูก Volume Mount:

gcloud run deploy ${SERVICE_NAME} \
  --image=${IMAGE_TAG} \
  --region=${REGION} \
  --project=${PROJECT_ID} \
  --platform=managed \
  --allow-unauthenticated \
  --port=8080 \
  --cpu=1 \
  --memory=512Mi \
  --min-instances=0 \
  --max-instances=3 \
  --execution-environment=gen2 \
  --add-volume=name=keystore-vol,type=cloud-storage,bucket=${BUCKET_NAME} \
  --add-volume-mount=volume=keystore-vol,mount-path=/app/data \
  --set-env-vars="PORT=8080,TZ=Asia/Bangkok,DSCHOOL_BASE_URL=https://dschool-l1.gp-education.com,KEYS_FILE_PATH=/app/data/api_keys.json,API_KEY=${API_KEY},ADMIN_API_KEY=${API_KEY}"

คำอธิบายพารามิเตอร์สำคัญ:

  • --region=asia-southeast3: ให้เซิร์ฟเวอร์รันที่ Data Center ในกรุงเทพฯ เพื่อความเร็วสูงสุด (Latency ต่ำสุด)
  • --allow-unauthenticated: อนุญาตให้เรียก API ผ่านเน็ตสาธารณะได้ (แต่ยังต้องผ่านระบบตรวจ Header API Key ของเรา)
  • --min-instances=0: ประหยัดที่สุด เมื่อไม่มีคนเรียก ระบบจะดับตัวเองเป็น 0 ทันที ไม่คิดเงินค่าเครื่อง
  • --max-instances=3: ป้องกันค่าใช้จ่ายบานปลาย จำกัดจำนวนเครื่องขยายตัวสูงสุดไม่เกิน 3 เครื่อง
  • --execution-environment=gen2: จำเป็นสำหรับการใช้งาน Volume Mount จาก Cloud Storage
  • --add-volume & --add-volume-mount: เชื่อม Bucket ไปไว้ที่ตำแหน่ง /app/data ใน Container เพื่อให้เซิร์ฟเวอร์อ่าน/เขียน api_keys.json ได้ทันที

เมื่อ Deploy สำเร็จ ระบบจะแสดง Service URL ตัวอย่างเช่น:

Service [dschool-attendance-api] revision [dschool-attendance-api-00004-xxx] has been deployed and is serving 100 percent of traffic.
Service URL: https://dschool-attendance-api-415345638302.asia-southeast3.run.app

ขั้นตอนที่ 6: ตรวจสอบและทดสอบการทำงานของระบบ

นำ Service URL ที่ได้มาทดสอบด้วยคำสั่ง curl:

  1. ทดสอบ Health Check (ตรวจสอบสถานะเครื่อง):

    curl "https://${SERVICE_NAME}-415345638302.${REGION}.run.app/api/health"

    ผลลัพธ์ที่ถูกต้อง:

    {"success":true,"message":"Service is operational","data":{"service":"dschool-attendance-api","status":"healthy","timestamp":"..."}}
  2. ทดสอบดึงข้อมูลการลงเวลาเรียนห้อง 401 (โดยแนบ API Key ที่ถูกต้อง):

    curl -H "X-API-Key: ${API_KEY}" \
      "https://${SERVICE_NAME}-415345638302.${REGION}.run.app/api/attendance/daily?classroom=401"

    ผลลัพธ์ที่ได้จะเป็น JSON ข้อมูลนักเรียนและการสแกนใบหน้า/เข้าเรียนจริง

  3. ทดสอบความปลอดภัยเมื่อใส่ API Key ไม่ถูกต้อง (Unauthorized Test):

    curl -H "X-API-Key: WRONG_KEY" \
      "https://${SERVICE_NAME}-415345638302.${REGION}.run.app/api/attendance/daily?classroom=401"

    ระบบจะปฏิเสธการเข้าถึงและตอบกลับทันทีว่า:

    {"success":false,"error":"Unauthorized: Invalid or revoked API Key..."}

ขั้นตอนที่ 7: การอัปเดตระบบและการเปลี่ยน API Key ในอนาคต

เลือกวิธีการอัปเดตตามสถานการณ์ที่ต้องการ:

กรณีที่ 1: แก้ไขโค้ดโปรแกรม Go

เมื่อแก้ไขโค้ดโปรแกรม Go และต้องการอัปเดตขึ้น Cloud Run ทำเพียง 2 คำสั่ง:

# 1. Build อิมเมจใหม่
gcloud builds submit --tag ${IMAGE_TAG} --project=${PROJECT_ID}

# 2. Deploy อิมเมจใหม่ขึ้น Service เดิม
gcloud run deploy ${SERVICE_NAME} --image=${IMAGE_TAG} --region=${REGION} --project=${PROJECT_ID}

กรณีที่ 2: ต้องการเปลี่ยน API Key

ต้องการเปลี่ยน API Key โดยไม่ต้องคอมไพล์โค้ดใหม่ ทำเพียงคำสั่งเดียว:

gcloud run services update ${SERVICE_NAME} \
  --region=${REGION} \
  --project=${PROJECT_ID} \
  --update-env-vars API_KEY="ใส่_KEY_ใหม่_ตรงนี้",ADMIN_API_KEY="ใส่_KEY_ใหม่_ตรงนี้"

10. สรุปค่าใช้จ่ายและโควตาฟรี (Billing & Pricing Details)

ตารางแจกแจงค่าบริการอย่างละเอียดตามข้อเท็จจริงของ Google Cloud SLA และ Pricing Calculator:

บริการที่ใช้งาน ลักษณะการคิดเงิน เงื่อนไข Always Free ของ Google Cloud ค่าใช้จ่ายจริงที่เกิดขึ้น (Bangkok)
Google Cloud Run คิดตามเวลา CPU/RAM ที่ประมวลผลจริง ฟรี 2 ล้านคำขอ/เดือน, 180,000 vCPU-วินาที, 360,000 GiB-วินาที (เฉพาะ Tier 1 US Regions) ~0.00 บาท (ฟรีใน Free Trial $300 / ใช้จริงไม่เกิน 1-2 บาท/เดือน)
Cloud Storage (GCS) คิดตามพื้นที่จัดเก็บไฟล์รายเดือน ฟรี 5 GB-months (เฉพาะ US Regions) ~0.0001 บาท (ไฟล์ Key 200 Bytes ต่ำกว่าขั้นต่ำที่จะคิดเงิน)
Artifact Registry คิดตามขนาดพื้นที่ Container Image ฟรี 500 MB/เดือน สำหรับทุกภูมิภาค 0 บาท (อิมเมจของเราขนาดเพียง ~35 MB)
Cloud Build คิดตามเวลาที่ใช้คอมไพล์โค้ด ฟรี 120 นาที/วัน ต่อบัญชี 0 บาท (เราใช้ Build เพียง ~1.5 นาที)
Network Egress ปริมาณทราฟฟิกข้อมูลที่ส่งออกไปยังผู้ใช้ ฟรี 100 GB/เดือน จาก North America ~0.00 บาท (JSON ตอบกลับขนาดเล็กมาก ~2 KB)