ใช้ Git Deploy เว็บบน Hosting อัตโนมัติ (CI/CD เบื้องต้น)

นักพัฒนาที่ใช้ Shared Hosting มักเจอปัญหาต้องอัปโหลดไฟล์ทีละครั้งผ่าน FTP ทุกครั้งที่แก้โค้ด ทำให้เสียเวลาและเกิดข้อผิดพลาดได้ง่าย แต่ความจริงแล้ว Hosting ที่รองรับ SSH สามารถตั้งค่าให้ Deploy อัตโนมัติทุกครั้งที่ git push ได้ โดยใช้ Git Hook แบบ Bare Repository บทความนี้จะพาตั้งค่าตั้งแต่ต้นบน DirectAdmin Hosting

สิ่งที่ต้องมีก่อน: Hosting ที่รองรับ SSH access, Git ติดตั้งบนเครื่อง local, Git repository บน GitHub หรือ GitLab

1. CI/CD บน Hosting คืออะไร

CI/CD (Continuous Integration / Continuous Deployment) คือแนวคิดที่ทำให้กระบวนการ Deploy โค้ดเป็นอัตโนมัติ สำหรับ Shared Hosting แนวทางที่ทำได้จริงคือการใช้ Git Bare Repository บนเซิร์ฟเวอร์ผสมกับ post-receive hook ซึ่งเป็น shell script ที่ทำงานอัตโนมัติเมื่อมีโค้ดถูก push เข้ามา

ขั้นตอนทั้งหมดมีดังนี้: คุณ push โค้ดจากเครื่อง local ไปยัง Hosting → post-receive hook รันคำสั่ง git checkout อัตโนมัติ → ไฟล์ใหม่ปรากฏใน public_html ทันที

2. สิ่งที่ต้องมี

สำหรับ AsiaGB Hosting: เปิดใช้ SSH ได้โดยส่ง Support Ticket แจ้ง username และขอ SSH Access เจ้าหน้าที่จะเปิดให้ภายใน 24 ชั่วโมง

3. ตั้งค่า Git Bare Repository บน Hosting (SSH)

เชื่อมต่อ SSH เข้า Hosting แล้วสร้าง Bare Repository ใน home directory:

# เชื่อมต่อ SSH เข้า Hosting
ssh [email protected]

# สร้าง folder สำหรับ bare repo (อยู่นอก public_html)
mkdir ~/repos
cd ~/repos
git init --bare mysite.git

Bare Repository คือ Git repository ที่ไม่มี working directory — ใช้เป็น "กล่องกลาง" รับ push เท่านั้น ไม่เก็บไฟล์โค้ดโดยตรง

4. สร้าง post-receive Hook Script

Hook script คือ shell script ที่ Git รันให้อัตโนมัติหลังรับ push สร้างไฟล์ hook:

nano ~/repos/mysite.git/hooks/post-receive

วางเนื้อหาด้านล่าง แล้วเปลี่ยน /home/username/public_html ให้ตรงกับ path จริง:

#!/bin/bash
# post-receive hook — deploy to public_html
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE

GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR

git checkout -f main

echo "✅ Deploy เสร็จแล้ว: $(date)"

บันทึกไฟล์ แล้วให้ permission execute:

chmod +x ~/repos/mysite.git/hooks/post-receive

⚠️ ตรวจสอบชื่อ branch: ถ้า repository ของคุณใช้ branch ชื่อ master แทน main ให้เปลี่ยน git checkout -f main เป็น git checkout -f master

5. เพิ่ม Remote บนเครื่อง Local

บนเครื่อง local ของคุณ เพิ่ม Hosting เป็น Git remote:

# ไปที่ project folder บน local
cd ~/myproject

# เพิ่ม remote ชื่อ "hosting"
git remote add hosting ssh://[email protected]/home/username/repos/mysite.git

# ทดสอบ push ครั้งแรก
git push hosting main

ถ้าตั้งค่าถูกต้อง คุณจะเห็นข้อความ ✅ Deploy เสร็จแล้ว จาก hook และไฟล์ใหม่จะปรากฏใน public_html ทันที

6. ตั้ง Webhook จาก GitHub/GitLab (ขั้นสูง)

ถ้าต้องการให้ GitHub/GitLab trigger deploy อัตโนมัติเมื่อมี push ขึ้น remote ให้สร้าง PHP script รับ webhook:

# สร้างไฟล์ deploy.php ใน public_html
<?php
$secret = 'YOUR_WEBHOOK_SECRET';
$payload = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($sig, $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '')) {
    http_response_code(403); exit;
}

exec('cd /home/username/repos/mysite.git && git fetch && GIT_WORK_TREE=/home/username/public_html git checkout -f main 2>&1', $out);
echo implode("\n", $out);

จากนั้นตั้ง Webhook URL ใน GitHub → Settings → Webhooks เป็น https://yourdomain.com/deploy.php และใส่ Secret ให้ตรงกับในไฟล์

7. ทดสอบ Deploy อัตโนมัติ

แก้ไขไฟล์ใดก็ได้บน local แล้วทดสอบ:

git add .
git commit -m "test: auto deploy"
git push hosting main

เปิดเว็บไซต์ตรวจสอบ การเปลี่ยนแปลงควรปรากฏทันทีหลัง push สำเร็จ

8. ข้อจำกัดของ Hosting vs VPS

ความสามารถShared HostingVPS
Git bare repository✅ ทำได้✅ ทำได้
post-receive hook✅ ทำได้✅ ทำได้
รัน npm install / composer⚠️ จำกัด (แล้วแต่ server)✅ ทำได้ทั้งหมด
Docker / Container❌ ไม่รองรับ✅ ทำได้
GitHub Actions Runner❌ ไม่รองรับ✅ ทำได้
ราคาเริ่มต้น500฿/ปีสูงกว่า

สำหรับเว็บไซต์ทั่วไปที่ใช้ PHP + HTML + CSS การ Deploy ผ่าน Git Hook บน Shared Hosting เพียงพอและประหยัดมาก แต่ถ้าต้องการ Pipeline เต็มรูปแบบ (build, test, deploy) VPS จะเหมาะกว่า

เคล็ดลับ: เพิ่ม .gitignore เพื่อไม่ให้ push ไฟล์ที่ไม่จำเป็น เช่น node_modules/, .env, *.log ป้องกัน Secret หลุดขึ้น server

9. วางแผนโครงสร้าง Repository สำหรับ Hosting

ก่อนตั้งค่า Git Deploy ควรวางแผนโครงสร้าง Repository ให้เหมาะสมกับโปรเจกต์ โดยเฉพาะถ้ามีไฟล์บางประเภทที่ไม่ควรขึ้น Production เช่น ไฟล์ config ที่มีข้อมูลสำคัญ หรือไฟล์ที่ generate ได้เองเช่น node_modules

โครงสร้าง Repository ที่แนะนำ

myproject/
├── .git/
├── .gitignore          ← ระบุไฟล์ที่ไม่ต้อง push
├── .env.example        ← template ของ config (ไม่มีค่าจริง)
├── public/             ← ไฟล์ที่ไปที่ public_html
│   ├── index.php
│   ├── css/
│   └── js/
├── src/                ← source code (ถ้าต้องการ build)
└── deploy/             ← script และ config สำหรับ deploy

ตัวอย่างไฟล์ .gitignore ที่ครบถ้วน

# ห้าม push ไฟล์ config จริง
.env
config/database.php
config/secrets.php

# ไฟล์ที่ generate ได้
node_modules/
vendor/
*.log
*.cache
.DS_Store
Thumbs.db

# ไฟล์ editor
.vscode/
.idea/
*.swp

การแยก .env.example (template ไม่มีค่าจริง) ออกจาก .env (ค่าจริง ไม่ push) เป็น practice ที่ดีที่ช่วยให้สมาชิกทีมใหม่รู้ว่าต้องตั้งค่าตัวแปรอะไรบ้าง โดยไม่เสี่ยงให้ข้อมูลสำคัญหลุดขึ้น repository

10. ตั้งค่า SSH Key Authentication ให้ปลอดภัยสูงสุด

การใช้ SSH Key แทน Password ไม่เพียงแต่สะดวกกว่า แต่ยังปลอดภัยกว่ามาก เพราะ Key จะไม่ถูก brute-force ได้ง่ายเหมือน Password ขั้นตอนการตั้งค่ามีดังนี้

สร้าง SSH Key บนเครื่อง Local

# สร้าง Ed25519 key (แนะนำ — ปลอดภัยและรวดเร็ว)
ssh-keygen -t ed25519 -C "[email protected]"

# ดู public key ที่จะ copy ไปวางบน Hosting
cat ~/.ssh/id_ed25519.pub

วาง Public Key บน Hosting

# เชื่อมต่อ SSH ด้วย password ครั้งแรก
ssh [email protected]

# สร้างไฟล์ authorized_keys
mkdir -p ~/.ssh && chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
# วาง public key ที่ copy มา แล้วบันทึก
chmod 600 ~/.ssh/authorized_keys

หลังจากนี้การเชื่อมต่อ SSH จะใช้ Key โดยอัตโนมัติ โดยไม่ต้องพิมพ์ Password ทุกครั้ง และคำสั่ง git push hosting main จะทำงานได้ทันที

⚠️ ความปลอดภัย: ห้าม commit ไฟล์ ~/.ssh/id_ed25519 (private key) ขึ้น Git เด็ดขาด เก็บ private key ไว้บนเครื่อง local เท่านั้น ไม่แชร์กับใคร

11. Monitoring การ Deploy ด้วย Log และ Notification

การ Deploy อัตโนมัติต้องมีระบบ Monitoring เพื่อให้รู้ทันทีเมื่อเกิดข้อผิดพลาด วิธีที่ง่ายที่สุดคือการส่ง notification ผ่าน Email หรือ LINE Notify เมื่อ post-receive hook ทำงานเสร็จ ไม่ว่าจะสำเร็จหรือล้มเหลว

ส่ง Email แจ้งเตือนหลัง Deploy

#!/bin/bash
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE
GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR

COMMIT_MSG=$(git log -1 --pretty=format:"%s")
COMMIT_HASH=$(git log -1 --pretty=format:"%h")
DEPLOY_TIME=$(date "+%Y-%m-%d %H:%M:%S")

if git checkout -f main; then
  STATUS="สำเร็จ"
else
  STATUS="ล้มเหลว"
fi

# ส่งอีเมล์แจ้งผล (ต้องมี sendmail บน server)
echo "Deploy $STATUS: $COMMIT_MSG ($COMMIT_HASH) เวลา $DEPLOY_TIME" \
  | mail -s "[$STATUS] Deploy yourdomain.com" [email protected]

นอกจาก Email ยังสามารถ integrate กับ Slack, Discord หรือ LINE Notify โดยใช้ curl ส่ง HTTP request ไปยัง Webhook URL ของแต่ละบริการ ทำให้ทีมได้รับการแจ้งเตือนในช่องทางที่ใช้งานอยู่แล้ว

การมีระบบ Log ที่ดีช่วยให้ตรวจสอบประวัติการ Deploy ย้อนหลังได้ เช่น ใครเป็นคนสั่ง Deploy, โค้ด commit อะไรที่ขึ้น Production และเกิดข้อผิดพลาดเมื่อไหร่ ข้อมูลเหล่านี้มีประโยชน์มากเมื่อต้อง debug ปัญหาบน Production หรือทำ Post-mortem หลังเกิดเหตุการณ์ไม่พึงประสงค์ สำหรับทีมที่ทำงานพร้อมกันหลายคน ควรกำหนด Process ที่ชัดเจนว่าใครมีสิทธิ์ push ขึ้น branch ไหน เพื่อลดความเสี่ยงในการ deploy โค้ดที่ยังไม่ผ่านการ review

12. จัดการหลาย Branch — Development, Staging, Production

ในโปรเจกต์จริง มักแยก environment เป็น 3 ระดับ ซึ่งสามารถทำได้บน Hosting โดยสร้าง bare repository หลายชุดหรือใช้ Hook ที่ตรวจสอบ branch name ก่อน deploy

#!/bin/bash
# post-receive hook รองรับหลาย branch
while read oldrev newrev refname; do
  BRANCH=$(git rev-parse --symbolic --abbrev-ref "$refname")

  if [ "$BRANCH" = "main" ]; then
    GIT_WORK_TREE=/home/username/public_html git checkout -f main
    echo "Deploy to PRODUCTION เสร็จแล้ว: $(date)"

  elif [ "$BRANCH" = "staging" ]; then
    GIT_WORK_TREE=/home/username/staging git checkout -f staging
    echo "Deploy to STAGING เสร็จแล้ว: $(date)"
  fi
done

ด้วยวิธีนี้ การ push ไป main จะ deploy ไปยัง public_html โดยอัตโนมัติ ขณะที่การ push ไป staging จะ deploy ไปยัง subdirectory แยก ช่วยให้ทดสอบการเปลี่ยนแปลงก่อน release จริงได้สะดวก

Branch Deploy ไปที่ วัตถุประสงค์
mainpublic_html/Production — ผู้ใช้จริงเห็น
stagingstaging/ทดสอบก่อน release
developdev/สภาพแวดล้อมพัฒนา

13. เพิ่ม Rollback ใน Hook Script

สิ่งสำคัญอย่างหนึ่งของ Deploy Pipeline คือความสามารถในการ Rollback เมื่อเกิดข้อผิดพลาด สามารถเพิ่มลอจิกนี้ลงใน post-receive hook ได้โดยตรง

#!/bin/bash
GIT_WORK_TREE=/home/username/public_html
export GIT_WORK_TREE
GIT_DIR=/home/username/repos/mysite.git
export GIT_DIR

# บันทึก commit hash ก่อน deploy
PREV_COMMIT=$(git -C /home/username/public_html rev-parse HEAD 2>/dev/null || echo "none")

# Deploy โค้ดใหม่
if git checkout -f main; then
  echo "Deploy สำเร็จ: $(date)"
  echo "Commit: $(git rev-parse HEAD)"
else
  echo "Deploy ล้มเหลว — กำลัง Rollback..."
  git checkout -f "$PREV_COMMIT"
  echo "Rollback ไป $PREV_COMMIT เรียบร้อย"
fi

นอกจากนี้ควรเก็บ Log ไว้ตรวจสอบภายหลัง เพิ่มบรรทัดนี้เข้าไปในสคริปต์:

# บันทึก deploy log พร้อม timestamp
echo "$(date): Deploy branch=main commit=$(git rev-parse HEAD)" >> /home/username/deploy.log

14. เปรียบเทียบวิธี Deploy บน Hosting

มีหลายวิธีที่นักพัฒนาใช้สำหรับ Deploy บน Shared Hosting แต่ละวิธีมีข้อดีข้อเสียต่างกัน ดังตารางด้านล่าง

วิธี Deploy ความสะดวก ความเสี่ยง เหมาะกับ
FTP Manualยากสูง (human error)มือใหม่เริ่มต้น
Git Hook (bare repo)สูงต่ำโปรเจกต์ทั่วไป
Webhook PHPสูงมากต่ำ (ถ้าตั้ง secret)ทีมที่ใช้ GitHub/GitLab
GitHub Actions + SCPกลางต่ำโปรเจกต์ที่ต้องการ CI

สำหรับโปรเจกต์ PHP ขนาดเล็กถึงกลาง การใช้ Git Bare Repository + post-receive hook เป็นวิธีที่ให้ความสมดุลระหว่างความง่ายและความน่าเชื่อถือได้ดีที่สุด โดยเฉพาะบน Hosting ที่รองรับ SSH Access อยู่แล้ว

เคล็ดลับ: เพิ่ม .gitignore เพื่อไม่ให้ push ไฟล์ที่ไม่จำเป็น เช่น node_modules/, .env, *.log ป้องกัน Secret หลุดขึ้น server

Hosting รองรับ SSH พร้อม Git Deploy

AsiaGB Hosting เริ่มต้น 500 บาท/ปี SSD, DirectAdmin, PHP 7.4/8.2/8.3 รองรับ SSH access ขอเปิดได้ทันที

ดูแพ็กเกจ Hosting