ในยุคของการพัฒนาซอฟต์แวร์สมัยใหม่ การทำ Continuous Deployment (CD) ผ่าน GitHub Actions ได้กลายเป็นเครื่องมือที่จำเป็นสำหรับทีมพัฒนา ช่วยให้การปล่อยรุ่นโปรแกรมเกิดขึ้นอัตโนมัติและลดข้อผิดพลาดที่มาจากการจัดการด้วยตนเอง บทความนี้จะแนะนำวิธีการสร้าง CD Pipeline ด้วย GitHub Actions เพื่อ Deploy ไปยัง Cloud VPS ของ ผู้ให้บริการโฮสติ้ง อย่างอัตโนมัติ
CD Pipeline คืออะไร และเหตุใดจึงสำคัญ
Continuous Deployment (CD) Pipeline เป็นกระบวนการอัตโนมัติที่ทำให้โค้ดใหม่สามารถปล่อยไปยังเซิร์ฟเวอร์ Production ได้อย่างรวดเร็วและปลอดภัย เมื่อมีการ Push โค้ดขึ้น GitHub แล้ว Pipeline จะทำการทดสอบและ Deploy โดยไม่ต้องแทรกแซงจากมนุษย์
- ความเร็ว: ลดเวลาในการปล่อย Feature ใหม่จากหลายชั่วโมงเหลือเพียงนาที
- ความปลอดภัย: ลดความเสี่ยงจากข้อผิดพลาดของมนุษย์ผ่านการทดสอบอัตโนมัติ
- ความเสถียร: มี Rollback อย่างรวดเร็วหากเกิดปัญหา
- เหมาะสมกับ Cloud VPS: เหมาะกับบริการ Cloud VPS ของ ผู้ให้บริการโฮสติ้ง ที่ให้ความยืดหยุ่นสูง
ตั้งค่า SSH Key สำหรับ Deploy
ขั้นตอนแรกในการสร้าง CD Pipeline คือการตั้งค่า SSH Key ที่ใช้สำหรับการเชื่อมต่อและ Deploy ไปยัง Cloud VPS ของคุณ ซึ่งเป็นวิธีที่ปลอดภัยที่สุด
# สร้าง SSH Key pair บน Cloud VPS
ssh-keygen -t ed25519 -f github-deploy-key -N ""
# เพิ่ม Public Key ไปยัง authorized_keys
cat github-deploy-key.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# ดูเนื้อหา Private Key (นำไปใส่ใน GitHub Secrets)
cat github-deploy-key
GitHub Secrets: การจัดการข้อมูลอย่างปลอดภัย
GitHub Secrets เป็นวิธีที่ปลอดภัยในการเก็บข้อมูลที่มีความสำคัญ เช่น SSH Keys, Passwords, และ API Tokens ไปที่ Repository Settings > Secrets and variables > Actions เพื่อเพิ่ม Secrets เหล่านี้:
- DEPLOY_PRIVATE_KEY — Private SSH Key สำหรับการเชื่อมต่อ
- DEPLOY_HOST — IP Address หรือ Domain ของ Cloud VPS
- DEPLOY_USER — Username สำหรับ SSH
- DEPLOY_PATH — Path สำหรับ Deploy บน Server
สร้าง GitHub Actions Workflow สำหรับ Deploy ผ่าน SSH
สร้างไฟล์ .github/workflows/deploy.yml ใน Repository:
name: CD Pipeline - Deploy to Cloud VPS
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to Cloud VPS
run: |
ssh -i ~/.ssh/deploy_key ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF'
cd ${{ secrets.DEPLOY_PATH }}
git pull origin main
npm install --production
npm run build
pm2 restart app
EOF
- name: Cleanup SSH key
if: always()
run: rm -f ~/.ssh/deploy_key
Deploy ด้วย rsync: วิธีที่มีประสิทธิภาพสูง
rsync เหมาะสำหรับการ Deploy ที่ต้องการความแม่นยำละเอียดไฟล์ ต้องการประหยัด Bandwidth หรือแอป Pre-built:
name: Deploy with rsync
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build application
run: |
npm ci
npm run build
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Deploy with rsync
run: |
rsync -avz --delete \
-e "ssh -i ~/.ssh/deploy_key" \
./dist/ \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/
- name: Restart service
run: |
ssh -i ~/.ssh/deploy_key \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \
"systemctl restart myapp"
- name: Cleanup
if: always()
run: rm -f ~/.ssh/deploy_key
Docker Deployment Workflow
สำหรับแอพพลิเคชันที่ใช้ Docker ให้สร้าง Workflow ที่ Build Image และ Deploy ได้อย่างอัตโนมัติ:
name: Docker CD Pipeline
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Deploy to Cloud VPS
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
ssh -i ~/.ssh/deploy_key \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF'
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
docker-compose down && docker-compose up -d
EOF
rm -f ~/.ssh/deploy_key
Environment Protection Rules
GitHub มี Environment Protection Rules ที่ช่วยควบคุมการ Deploy ไปยัง Production ไปที่ Repository Settings > Environments และสร้าง Environment ชื่อ "production":
- Required reviewers: เลือกสมาชิกที่ต้องอนุมัติการ Deploy
- Deployment branches: จำกัดให้เฉพาะ Branch "main" เท่านั้น
- Environment secrets: Secrets เฉพาะสำหรับ Production
Rollback Strategy: แผนการสำรองเมื่อเกิดปัญหา
การมี Rollback Strategy ที่ดีจึงเป็นสิ่งสำคัญใน CD Pipeline สามารถ Rollback ได้โดยใช้ workflow_dispatch:
name: Rollback Deployment
on:
workflow_dispatch:
inputs:
commit:
description: 'Commit SHA to rollback to'
required: true
type: string
jobs:
rollback:
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout specific commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit }}
- name: Deploy previous version
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
ssh -i ~/.ssh/deploy_key \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF'
cd ${{ secrets.DEPLOY_PATH }}
git fetch --all
git checkout ${{ github.event.inputs.commit }}
npm install --production && npm run build
pm2 restart app
EOF
rm -f ~/.ssh/deploy_key
ตัวอย่าง Complete CI/CD Workflow
ตัวอย่าง Workflow ครบวงจรที่รวมทั้ง CI และ CD ด้วยกัน:
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# Phase 1: CI - Test
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
# Phase 2: CD - Deploy (only on main branch push)
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- uses: actions/checkout@v4
- name: Build
run: |
npm ci
npm run build
- name: Deploy to ผู้ให้บริการโฮสติ้ง Cloud VPS
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_PRIVATE_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
rsync -avz --delete \
-e "ssh -i ~/.ssh/deploy_key" \
./dist/ \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/
ssh -i ~/.ssh/deploy_key \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \
"pm2 restart myapp"
rm -f ~/.ssh/deploy_key
- name: Notify on success
if: success()
run: echo "Deploy completed successfully!"
ข้อปฏิบัติที่ดีสำหรับ CD Pipeline
- ตั้งค่า Branch Protection: ใช้ Branch Protection Rules เพื่อให้ต้องผ่าน CI/CD ก่อน Merge
- ทำการทดสอบอัตโนมัติ: เพิ่ม Test Step ก่อน Deploy เสมอ
- จัดการ Secrets อย่างปลอดภัย: ไม่เคยใส่ Secrets ลงใน Workflow file โดยตรง
- Health Check: ตรวจสอบหลัง Deploy ว่าแอพตอบสนองเป็นปกติ
- Notification: ติดตั้ง Slack หรือ Email เพื่อแจ้งสถานะการ Deploy
สรุป
การสร้าง CD Pipeline ด้วย GitHub Actions สำหรับ Deploy ไปยัง Cloud VPS ของ ผู้ให้บริการโฮสติ้ง เป็นวิธีที่มีประสิทธิภาพในการเพิ่มความเร็วและความปลอดภัยในการปล่อยโปรแกรม ด้วยการตั้งค่า SSH Key อย่างถูกต้อง จัดการ GitHub Secrets อย่างปลอดภัย และสร้าง Workflow ที่เหมาะสม คุณจะสามารถ Deploy โปรแกรมของคุณได้อย่างอัตโนมัติและเชื่อถือได้
ผู้ให้บริการโฮสติ้ง Cloud VPS มอบความยืดหยุ่นและการควบคุมเต็มรูปแบบที่จำเป็นสำหรับการสร้าง CD Pipeline ที่มีประสิทธิภาพ สามารถติดตั้ง Software ใดๆ และตั้งค่าได้ตามต้องการ พร้อมทีม Support ที่พร้อมช่วยเหลือ
