
นักพัฒนาที่ใช้ 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. สิ่งที่ต้องมี
- Hosting ที่เปิดใช้งาน SSH Access (ขอเปิดได้ผ่าน DirectAdmin หรือ Support Ticket)
- Git ติดตั้งบนเครื่อง local (ตรวจสอบด้วย
git --version) - SSH Key สำหรับ Authentication (แนะนำมากกว่า Password)
- Repository บน GitHub / GitLab (ถ้าต้องการ Webhook จาก Remote)
สำหรับ 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 Hosting | VPS |
|---|---|---|
| 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 ไปที่ | วัตถุประสงค์ |
|---|---|---|
main | public_html/ | Production — ผู้ใช้จริงเห็น |
staging | staging/ | ทดสอบก่อน release |
develop | dev/ | สภาพแวดล้อมพัฒนา |
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.log14. เปรียบเทียบวิธี 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