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

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

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

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

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

ระบบถูกออกแบบให้มีความคุ้มค่าสูงสุด (เกือบ 0 บาท) และตอบสนองรวดเร็วที่สุด:

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
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 และเปิดใช้งาน Cloud Services

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

    export PROJECT_ID="krittamark-lab"
    export REGION="asia-southeast3"
    export SERVICE_NAME="dschool-attendance-api"
    export BUCKET_NAME="dschool-keystore-krittamark"
    export IMAGE_TAG="asia-southeast3-docker.pkg.dev/${PROJECT_ID}/cloud-run-source-deploy/${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 วินาที ในการเปิดใช้งานบริการต่าง ๆ)

ขั้นตอนที่ 3: สร้าง Cloud Storage Bucket สำหรับเก็บ API Key (Keystore)

เนื่องจาก Cloud Run มีสถานะแบบ Stateless (ไฟล์ในเครื่องจะหายไปเมื่อเซิร์ฟเวอร์ดับ) เราจึงใช้ Cloud Storage มา Mount เสมือนเป็นโฟลเดอร์ในเครื่อง

  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: 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. ทดสอบความปลอดภัยเมื่อไม่ใส่ Key หรือใส่ Key ผิด:

    curl "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 & Free Tier)

บริการที่ใช้งาน การคิดเงิน โควตาฟรีต่อเดือน (Free Tier) ค่าใช้จ่ายจริงที่คาดว่าจะเกิดขึ้น
Google Cloud Run คิดตามเวลา CPU/RAM ที่รันตอนมีคนเรียก ฟรี 2,000,000 ครั้ง/เดือน 0 บาท
Cloud Storage (GCS) คิดตามพื้นที่เก็บไฟล์ เก็บไฟล์ api_keys.json (~200 Bytes) 0 บาท
Artifact Registry คิดตามขนาด Container Image ฟรี 500 MB/เดือน (อิมเมจเรา ~35 MB) 0 บาท
Cloud Build คิดตามเวลารันตอน Build โค้ด ฟรี 120 นาที/วัน (เราใช้ ~1.5 นาที) 0 บาท
Network Egress ปริมาณข้อมูลที่ส่งกลับไปยังผู้ใช้ ฟรี 100 GB/เดือน 0 บาท