Git code version control deployment

Deploy อัตโนมัติด้วย Git บน VPS ไม่ต้อง FTP อีกต่อไป

มิถุนายน 2026 · อ่าน 7 นาที

การ deploy ด้วย FTP หรือ copy ไฟล์ด้วยมือทุกครั้งเสียเวลาและเสี่ยงผิดพลาด ใช้ Git bare repository บน VPS ร่วมกับ post-receive hook เพื่อให้ git push ครั้งเดียว deploy ให้อัตโนมัติ


แนวคิด

ขั้นที่ 1: ตั้งค่าบน VPS

# สร้าง user สำหรับ deploy (ถ้ายังไม่มี)
adduser deploy
usermod -aG www-data deploy

# สร้าง bare repo
mkdir -p /var/repo/mysite.git
cd /var/repo/mysite.git
git init --bare

ขั้นที่ 2: เขียน post-receive Hook

nano /var/repo/mysite.git/hooks/post-receive
#!/bin/bash
TARGET="/var/www/html/mysite"
GIT_DIR="/var/repo/mysite.git"
BRANCH="main"

while read oldrev newrev ref; do
  if [[ $ref = refs/heads/$BRANCH ]]; then
    echo "Deploying $BRANCH..."
    git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
    echo "Done."
  fi
done
chmod +x /var/repo/mysite.git/hooks/post-receive

ขั้นที่ 3: ตั้งค่า Permission

mkdir -p /var/www/html/mysite
chown -R deploy:www-data /var/www/html/mysite
chown -R deploy:deploy /var/repo/mysite.git

ขั้นที่ 4: เพิ่ม Remote บนเครื่องตัวเอง

# ใน project directory บนเครื่องตัวเอง
git remote add vps deploy@your-vps-ip:/var/repo/mysite.git

# Deploy ครั้งแรก
git push vps main

เพิ่ม Hook สำหรับ Restart Service

ถ้าแอปต้องการ restart หลัง deploy เพิ่มใน hook:

# ต่อท้ายใน post-receive หลัง checkout
systemctl restart php8.3-fpm
# หรือ
pm2 restart myapp
SSH Key: ให้ copy public key ของเครื่องตัวเองไปใส่ใน /home/deploy/.ssh/authorized_keys บน VPS เพื่อไม่ต้องพิมพ์รหัสผ่านทุกครั้งที่ push

ทดสอบ workflow

# บนเครื่องตัวเอง
echo "test" >> README.md
git add README.md
git commit -m "test deploy"
git push vps main
# ดูว่า hook ทำงานและไฟล์ถูก copy ไป web root

สรุป

หลังตั้งค่าครั้งเดียว การ deploy ง่ายเหมือนพิมพ์ git push vps main ลดโอกาสผิดพลาดจากการ copy ไฟล์ และมี Git history เป็น audit trail ตลอดเวลา

ตรวจสอบว่า Deploy ทำงานถูกต้อง

# ดู output ที่ terminal หลัง git push
git push vps main
# ควรเห็น: "Deploying main..." และ "Done."

# ตรวจไฟล์ใน web root บน VPS
ls -la /var/www/html/mysite/

# ทดสอบว่าเว็บ response
curl -I https://example.com
เพิ่ม log ใน hook: ใส่ exec > /tmp/deploy.log 2>&1 ที่บรรทัดแรกของ post-receive เพื่อ debug ง่ายขึ้น แล้วดูด้วย tail -f /tmp/deploy.log

แก้ปัญหาที่พบบ่อย

Error: "Permission denied (publickey)" ตอน git push

SSH public key ยังไม่ได้เพิ่มบน VPS ตรวจสอบและเพิ่ม:

# บนเครื่องตัวเอง: copy public key
cat ~/.ssh/id_rsa.pub

# บน VPS: ใส่ใน authorized_keys ของ user deploy
mkdir -p /home/deploy/.ssh
nano /home/deploy/.ssh/authorized_keys
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh

Error: "remote: bash: post-receive: Permission denied"

ลืม chmod +x ให้ hook file:

chmod +x /var/repo/mysite.git/hooks/post-receive
ls -la /var/repo/mysite.git/hooks/post-receive
# ต้องเห็น -rwxr-xr-x

Error: ไฟล์ถูก push แต่ไม่ปรากฏใน web root

อาจเป็น branch name ไม่ตรง hook ใช้ main แต่ push ไป master:

# ดู branch ปัจจุบัน
git branch

# ถ้าชื่อ master ให้ rename
git branch -m master main
git push vps main

Error: hook รันแต่ไฟล์ไม่ถูก overwrite

ตรวจสิทธิ์ user deploy ต้องเขียนได้:

ls -la /var/www/html/ | grep mysite
chown -R deploy:www-data /var/www/html/mysite

Error: "error: src refspec main does not match any"

ยังไม่ได้ commit ใดๆ บนเครื่องตัวเอง ต้องมี commit ก่อนถึง push ได้:

git add .
git commit -m "initial commit"
git push vps main

คำถามที่พบบ่อย

จะ deploy หลาย project บน VPS เดียวกันได้ไหม?

ได้ สร้าง bare repo แยกกันได้เลย เช่น /var/repo/site1.git, /var/repo/site2.git แต่ละตัวมี hook และ target directory เป็นของตัวเอง

จะ rollback ไปเวอร์ชันก่อนหน้าได้ไหม?

ได้ เพราะ Git เก็บ history ครบ:

# revert แล้ว push ใหม่
git revert HEAD
git push vps main

Environment variable จัดการยังไง?

ไม่ควร commit .env ไฟล์เข้า repo ให้สร้างไฟล์ .env บน VPS โดยตรง แล้วเพิ่มใน .gitignore

ใช้กับ GitHub Actions แทน bare repo ได้ไหม?

ได้ แต่วิธี bare repo ทำงานได้เองโดยไม่ต้องพึ่ง third party และ push ครั้งเดียวถึง VPS เลย ไม่ผ่าน cloud