CI/CD (Continuous Integration / Continuous Deployment) เป็นแนวปฏิบัติสำคัญในการพัฒนาซอฟต์แวร์ที่ช่วยให้ทีมพัฒนาสามารถส่งมอบโค้ดอย่างรวดเร็ว มั่นคง และมีประสิทธิภาพ ด้วยการสร้าง GitHub Actions CI/CD Pipeline คุณสามารถอัตโนมัติขั้นตอนการทดสอบ สร้าง และปรับใช้แอปพลิเคชนของคุณได้ บทความนี้จะแนะนำวิธีสร้าง CI/CD Pipeline ตั้งแต่เริ่มต้นโดยใช้ GitHub Actions พร้อมการปรับใช้แอปพลิเคชน Node.js ไปยัง ผู้ให้บริการโฮสติ้ง Cloud VPS
CI/CD คืออะไร และเหตุใดจึงสำคัญ
Continuous Integration (CI) หมายถึงการรวมโค้ดจากหลายคนเข้าด้วยกันอย่างสม่ำเสมอ โดยทีมจะทำการ commit โค้ดไปยัง repository หลายครั้งในแต่ละวัน เมื่อมีการ commit ใหม่ ระบบจะทำการสร้าง (build) และทดสอบ (test) โค้ดโดยอัตโนมัติเพื่อตรวจหาข้อผิดพลาด
Continuous Deployment (CD) คือการปรับใช้โค้ดไปยังสภาพแวดล้อมการผลิตโดยอัตโนมัติ เมื่อการทดสอบทั้งหมดผ่านสำเร็จ ระบบจะทำการ deploy ออกไปในเซิร์ฟเวอร์จริงทันที ทำให้ผู้ใช้สามารถใช้ฟีเจอร์ใหม่ได้ดวนที่สุด
ประโยชน์ของ CI/CD:
- ลดข้อผิดพลาด – การทดสอบอัตโนมัติช่วยจับข้อผิดพลาดได้เร็ว
- เพิ่มความเร็ว – การปรับใช้อัตโนมัติทำให้ release ใหม่ได้เร็วขึ้น
- ปรับปรุงคุณภาพ – การทดสอบอย่างสม่ำเสมอรักษาคุณภาพโค้ด
- ลดค่าใช้จ่าย – อัตโนมัติลดการทำงานด้วยมือและความผิดพลาดของมนุษย์
- ส่งมอบได้เร็ว – ฟีเจอร์ใหม่ไปถึงผู้ใช้ได้เร็วกว่า
GitHub Actions คืออะไร
GitHub Actions เป็นแพลตฟอร์มการทำ workflow automation ที่สร้างเข้ามาในตัว GitHub ช่วยให้คุณสามารถสร้าง CI/CD pipeline โดยไม่ต้องใช้บริการภายนอก GitHub Actions ทำงานโดยการสร้างไฟล์ YAML ในโฟลเดอร์ .github/workflows/ ของ repository
แนวคิดหลักของ GitHub Actions:
- Workflow – ลำดับการทำงานโดยอัตโนมัติ บ้านใน .github/workflows/ เป็นไฟล์ YAML
- Event – สิ่งที่ทำให้ workflow ทำงาน เช่น push, pull_request, schedule
- Job – ชุดของขั้นตอน (steps) ที่ทำงานในเซิร์ฟเวอร์เดียวกัน
- Step – งานแต่ละงานในการทำงาน เช่น install dependencies, run tests
- Action – แอปพลิเคชันที่ใช้บ่อยสำหรับการทำงาน เช่น actions/checkout, actions/setup-node
Workshop: สร้าง CI/CD Pipeline ด้วย GitHub Actions
ในส่วนนี้ เราจะสร้าง CI/CD Pipeline สำหรับแอปพลิเคชน Node.js และปรับใช้ไปยัง ผู้ให้บริการโฮสติ้ง Cloud VPS ทีละขั้นตอน
ขั้นตอนที่ 1: สร้างไฟล์ Workflow
สร้างโฟลเดอร์และไฟล์ workflow ดังนี้:
mkdir -p .github/workflows
touch .github/workflows/deploy.yml
ไฟล์นี้จะเป็นหัวใจของ CI/CD Pipeline ของเรา
ขั้นตอนที่ 2: กำหนด Event Trigger
กำหนดให้ workflow ทำงานเมื่อมีการ push ไปยัง branch main หรือเมื่อมี pull request:
name: Deploy to Cloud VPS
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
on: กำหนด event ที่ทำให้ workflow ทำงาน ในที่นี้ตั้งให้ทำงานเมื่อ push ไปยัง main หรือมี pull request ไปยัง main runs-on: กำหนดระบบปฏิบัติการที่ใช้รัน job นี้
ขั้นตอนที่ 3: ติดตั้ง Dependencies และรัน Tests
เพิ่ม steps ในการ checkout โค้ด ติดตั้ง Node.js และ dependencies แล้วรันการทดสอบ:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build application
run: npm run build
ขั้นตอนนี้ใช้ GitHub Actions ที่สร้างเตรียมไว้แล้วเพื่อ checkout โค้ด setup Node.js และรันคำสั่ง npm
ขั้นตอนที่ 4: สร้าง Docker Image
ถ้าใช้ Docker สำหรับแพคเกจแอปพลิเคชน ให้เพิ่มขั้นตอนนี้:
- name: Build Docker image
run: |
docker build -t myapp:${{ github.sha }} .
docker tag myapp:${{ github.sha }} myapp:latest
${{ github.sha }} คือตัวแปรพิเศษที่ GitHub Actions มีให้ เก็บ commit hash ของ push ปัจจุบัน
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/myapp
git pull origin main
npm ci --production
npm run build
pm2 restart myapp || pm2 start npm --name myapp -- start
Action นี้ใช้ SSH เพื่อเชื่อมต่อไปยัง Cloud VPS และรันคำสั่งเพื่อ deploy แอปพลิเคชน
การจัดการ Secrets สำหรับความปลอดภัย
ข้อมูลที่ละเอียดอ่อนเช่น SSH key, server IP, และ port ต้องเก็บไว้ในการตั้งค่า Secrets ของ GitHub ไม่ใช่ในไฟล์ workflow
ในการตั้งค่า Secrets:
- ไปยัง GitHub repository ของคุณ
- คลิก Settings > Secrets and variables > Actions
- คลิก “New repository secret”
- เพิ่ม secrets ต่อไปนี้:
VPS_HOST: your-vps-ip-address
VPS_USER: your-ssh-username
VPS_PORT: 22
VPS_SSH_KEY: your-private-ssh-key-content
สร้าง SSH key pair ถ้ายังไม่มี:
ssh-keygen -t ed25519 -C "[email protected]"
# เพิ่ม public key ไปยัง ~/.ssh/authorized_keys ในเซิร์ฟเวอร์
cat ~/.ssh/id_ed25519.pub | ssh user@your-vps "cat >> ~/.ssh/authorized_keys"
Workflow File ตัวอย่างสมบูรณ์
นี่คือไฟล์ .github/workflows/deploy.yml สมบูรณ์สำหรับการ deploy Node.js ไปยัง ผู้ให้บริการโฮสติ้ง Cloud VPS:
name: Deploy to Cloud VPS
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test-and-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint --if-present
- name: Run tests
run: npm test --if-present
- name: Build application
run: npm run build
deploy:
needs: test-and-build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/myapp
git pull origin main
npm ci --production
npm run build
pm2 restart myapp || pm2 start npm --name myapp -- start
- name: Send Slack notification
uses: slackapi/[email protected]
with:
payload: |
{"text": "Deployment to Cloud VPS completed successfully!"}
if: success()
- name: Send Slack notification on failure
uses: slackapi/[email protected]
with:
payload: |
{"text": "Deployment to Cloud VPS failed!"}
if: failure()
การแจ้งเตือน Slack สำหรับผลการ Deploy
การแจ้งเตือน Slack ช่วยให้ทีมทราบผลการ deploy ทันที ก่อนอื่นให้ตั้งค่า Slack Webhook URL:
- ไปยัง Slack workspace ของคุณ
- ไปที่ Apps > Create New App
- เลือก “From scratch” และตั้งชื่อ app เป็น “GitHub Notifications”
- ไปที่ Incoming Webhooks และเปิดใช้งาน
- คลิก “Add New Webhook to Workspace” และเลือก channel ที่ต้องการ
- คัดลอก Webhook URL ไปยัง GitHub Secrets เป็น SLACK_WEBHOOK_URL
จากนั้นใน workflow file ให้อัพเดท Slack notification step:
- name: Send Slack notification
uses: slackapi/[email protected]
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
payload: |
{
"text": "GitHub Action",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Deploy Status*\nRepository: ${{ github.repository }}\nBranch: ${{ github.ref }}\nStatus: ${{ job.status }}"
}
}
]
}
if: always()
1. ใช้ Environment Protection
สำหรับสภาพแวดล้อม production ให้ตั้งค่า environment protection เพื่อต้องการการอนุมัติก่อน deploy:
jobs:
deploy:
environment:
name: production
url: https://your-app.de.co.th
runs-on: ubuntu-latest
สตระหว่าง GitHub repository Settings ให้ไปที่ Environments และตั้งค่า “Required reviewers” สำหรับ production environment
2. กำหนดเวลา Manual Approval
เพิ่ม step สำหรับการอนุมัติด้วยมือก่อน deploy ไปยัง production:
deploy:
needs: test-and-build
environment:
name: production
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
GitHub จะรอการอนุมัติจากผู้ตรวจสอบที่ตั้งค่าไว้โดยอัตโนมัติ
3. เก็บ Logs และทำการ Monitoring
เก็บบันทึก (logs) ของ workflow เพื่อการ troubleshooting:
- name: Upload logs
if: always()
uses: actions/upload-artifact@v3
with:
name: workflow-logs
path: logs/
retention-days: 30
4. ใช้ Caching เพื่อเพิ่มความเร็ว
ใช้ cache สำหรับ node_modules เพื่อลดเวลาในการติดตั้ง dependencies:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm' # GitHub จะ cache node_modules โดยอัตโนมัติ
5. ใช้ Conditional Steps
รันบาง steps เฉพาะในเงื่อนไขบางอย่าง:
- name: Deploy only on main branch
if: github.ref == 'refs/heads/main'
run: ./deploy.sh
การแก้ไขปัญหา CI/CD Pipeline
ปัญหา: GitHub Actions ไม่เริ่มทำงาน
วิธีแก้:
- ตรวจสอบว่าไฟล์ workflow อยู่ในโฟลเดอร์ .github/workflows/ ที่ถูกต้อง
- ตรวจสอบ YAML syntax โดยใช้เครื่องมือ YAML validator
- ตรวจสอบ trigger event กำหนดถูกต้องหรือไม่ (push, pull_request, schedule)
- ดูที่ Actions tab ใน GitHub repository เพื่อดูรายละเอียดข้อผิดพลาด
ปัญหา: Deploy ล้มเหลวเนื่องจาก SSH authentication error
วิธีแก้:
- ตรวจสอบว่า SSH key ถูกสร้างและเพิ่มไปยัง ~/.ssh/authorized_keys ในเซิร์ฟเวอร์เรียบร้อยแล้ว
- ตรวจสอบว่า private key ถูกเก็บไว้ใน GitHub Secrets ที่ชื่อ VPS_SSH_KEY
- ลองรัน SSH connection ด้วยตนเองเพื่อยืนยันว่าทำงาน
- ตรวจสอบ host key fingerprint โดยรัน ssh-keyscan
ปัญหา: Tests ไม่ผ่าน แต่ deploy ยังคงดำเนินการ
วิธีแก้:
- ตรวจสอบว่า deploy job มี
needs: test-and-buildเพื่อให้ test ต้องผ่านก่อน - ใส่
if: success()ใน deploy step เพื่อให้ deploy เฉพาะเมื่อ test ผ่าน
ขั้นตอนถัดไป: ขยาย CI/CD Pipeline
เมื่อ pipeline พื้นฐานทำงานได้เรียบร้อย คุณสามารถขยายด้วยเพิ่มเติม:
- Code Coverage Reports – ใช้ codecov หรือ codeclimate เพื่อติดตามความครอบคลุมของการทดสอบ
- Security Scanning – ใช้ Snyk หรือ GitHub Dependabot เพื่อตรวจหาช่องโหว่ในโครงการ
- Performance Testing – เพิ่ม load testing เพื่อตรวจสอบประสิทธิภาพ
- Blue-Green Deployment – ปรับใช้ไปยังสภาพแวดล้อมสำรองและสลับเมื่อ ready
- Database Migrations – รันการอัปเดตฐานข้อมูลก่อน deploy แอปพลิเคชน
บทสรุป
GitHub Actions CI/CD Pipeline เป็นเครื่องมือที่มีประสิทธิภาพสำหรับอัตโนมัติกระบวนการพัฒนาและปรับใช้ แอปพลิเคชน ด้วยการสร้าง workflow ที่ดีคุณสามารถตรวจสอบคุณภาพของโค้ด ทำการทดสอบอัตโนมัติ และปรับใช้ไปยัง ผู้ให้บริการโฮสติ้ง Cloud VPS ด้วยความมั่นใจ
ในการเริ่มต้นให้เลือกจากขั้นตอนพื้นฐานที่อธิบายไว้ในบทความนี้ แล้วค่อยขยาย pipeline ของคุณด้วยฟีเจอร์เพิ่มเติมเมื่อทีมเติบโตและความต้องการเปลี่ยนแปลง
