Auto Deploy ด้วย Git Hooks: post-receive บน VPS

Git Hooks เป็นสคริปต์ที่ทำงานเมื่อเหตุการณ์ Git เกิดขึ้น ในบทความนี้เราจะสอนการใช้ post-receive hook เพื่อ Deploy เว็บไซต์อัตโนมัติเมื่อ Push โค้ดไปยัง VPS พร้อมตัวอย่างการประยุกต์ใช้จริง

Git Hooks คืออะไร

Git Hooks เป็นโปรแกรมอัตโนมัติที่ทำงานตอบสนองต่อเหตุการณ์ Git เช่น Pre-commit, Post-commit, Post-receive เป็นต้น ช่วยให้คุณสามารถเพิ่มพฤติกรรมการทำงานที่กำหนดเองได้ ซึ่งเป็นพื้นฐานของการทำ CI/CD (Continuous Integration/Continuous Deployment)

ประเภทของ Git Hooks ที่ใช้บ่อย:

  • Pre-commit: ทำงานก่อน Commit
  • Post-commit: ทำงานหลังจาก Commit
  • Pre-receive: ทำงานก่อนรับ Push บน Server
  • Post-receive: ทำงานหลังรับ Push บน Server
  • Pre-push: ทำงานก่อน Push

Post-receive Hook คือ

Post-receive hook ทำงานหลังจากที่ Server ได้รับ Git Push เสร็จสิ้น นี่คือจุดที่เหมาะสำหรับการ Deploy โดยอัตโนมัติ Hook นี้จะรับข้อมูลจาก stdin ซึ่งประกอบด้วย old revision, new revision และชื่อ branch

ข้อดีของการใช้ post-receive:

  • ทำงานบน Server โดยตรง
  • สามารถเข้าถึง Repository อย่างเต็มที่
  • ช่วยให้ Deploy เว็บไซต์ได้ทันที
  • สามารถรัน Command ต่างๆ เช่น npm install, build, restart service

สร้าง Post-receive Hook Script

ไปยัง Bare Repository บน VPS:

cd /var/git/myproject.git/hooks
nano post-receive

ใส่สคริปต์พื้นฐานต่อไปนี้:

#!/bin/bash
WORK_TREE=/var/www/myproject
GIT_DIR=/var/git/myproject.git

while read oldrev newrev ref
do
    if [[ $ref =~ .*/master$ ]] || [[ $ref =~ .*/main$ ]]; then
        git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f
        echo "Deploy to production completed!"
    fi
done

สคริปต์นี้จะ:

  1. ตรวจสอบว่า branch ที่ push มาเป็น master หรือ main
  2. ทำการ checkout ไฟล์ไปยัง /var/www/myproject
  3. แสดงข้อความบอกว่า Deploy สำเร็จ

ทำให้ Script สามารถ Execute ได้

chmod +x /var/git/myproject.git/hooks/post-receive

สร้าง Working Directory

ต้องสร้าง Directory ที่ Checkout ไฟล์ไป:

mkdir -p /var/www/myproject
chown -R git:git /var/www/myproject
chmod -R 755 /var/www/myproject

ตั้งค่า Bare Repository

หากยังไม่มี Bare Repository ให้สร้างด้วยคำสั่ง:

git init --bare /var/git/myproject.git
chown -R git:git /var/git/myproject.git

อ่านเพิ่มเติม: ตั้งค่า Bare Git Repository บน VPS สำหรับ Deploy

ทดสอบ Deployment Workflow

จากเครื่อง Local ทำการ Push:

git add .
git commit -m "Test deploy"
git push origin main

ตรวจสอบไฟล์ใน /var/www/myproject บน VPS:

ssh root@your-vps-ip
ls -la /var/www/myproject

ตัวอย่าง Advanced Post-receive Hook

สำหรับโครงการที่มีความซับซ้อนมากขึ้น สามารถเพิ่มลอจิก เช่น ติดตั้ง dependencies, build project, restart service:

#!/bin/bash
WORK_TREE=/var/www/myproject
GIT_DIR=/var/git/myproject.git
LOG_FILE=/var/log/deploy.log
BRANCH_NAME="main"

while read oldrev newrev ref
do
    if [[ $ref =~ .*/main$ ]]; then
        {
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting deployment..."
            
            # Checkout files
            git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout -f $BRANCH_NAME
            
            # Install dependencies
            cd $WORK_TREE
            if [ -f "package.json" ]; then
                echo "Installing npm dependencies..."
                npm install --production
            fi
            
            # Build project if needed
            if [ -f "package.json" ] && grep -q '"build"' package.json; then
                echo "Building project..."
                npm run build
            fi
            
            # Restart service
            if [ -f "/etc/systemd/system/myapp.service" ]; then
                echo "Restarting application..."
                systemctl restart myapp
            fi
            
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deploy completed successfully!"
        } >> $LOG_FILE 2>&1
    fi
done

ดูข้อมูล Logs ของ Deployment

tail -f /var/log/deploy.log

การแก้ไขปัญหา

ปัญหา: Hook ไม่ทำงาน

  • ตรวจสอบว่า chmod +x ได้ทำแล้ว
  • ตรวจสอบ Shebang line (#!/bin/bash) ถูกต้อง
  • ดู logs เพื่อหาข้อผิดพลาด

ปัญหา: Checkout ล้มเหลว

  • ตรวจสอบสิทธิ์ของ /var/www/myproject
  • ลองรัน Hook script ด้วยมือเพื่อดูข้อผิดพลาด

สำหรับการติดตั้ง Git และตั้งค่าอื่นๆ ดู ตั้งค่า Git บน VPS ให้ Deploy เว็บอัตโนมัติด้วย SSH

สรุป

ด้วยการใช้ Git Hooks โดยเฉพาะ post-receive hook คุณสามารถสร้าง CI/CD Pipeline อย่างง่ายๆ ที่ Deploy เว็บไซต์อัตโนมัติทุกครั้งที่มีการ Push โค้ดใหม่ ซึ่งช่วยประหยัดเวลาและลดข้อผิดพลาดในการ Deploy บน ผู้ให้บริการโฮสติ้ง Cloud VPS ให้คุณเน้นไปที่การพัฒนาฟีเจอร์ใหม่แทนการจัดการ Deployment ด้วยตนเอง