IT General
เอาแบบบ้านๆ เลยนะ CI/CD Pipeline เนี่ย มันคือระบบอัตโนมัติที่เราใช้ในการพัฒนาซอฟต์แวร์ สมัยผมทำร้านเน็ตฯ ต้องมานั่งลงโปรแกรมทีละเครื่อง โอ้โห! กว่าจะเสร็จแต่ละที... แต่ CI/CD มันเหมือนมีหุ่นยนต์มาช่วยเราทำงานพวกนี้แทนไง ตั้งแต่เขียนโค้ด ทดสอบ ไปจนถึงเอาขึ้นระบบจริง
CI ย่อมาจาก Continuous Integration แปลว่า "รวมโค้ดกันตลอดเวลา" คือเวลาโปรแกรมเมอร์หลายคนช่วยกันเขียนโค้ดเนี่ย มันต้องมีการเอามารวมกันเรื่อยๆ ไม่ใช่รอจนเสร็จค่อยรวมทีเดียว เพราะจะเจอปัญหาเยอะมาก CI จะช่วยให้การรวมโค้ดเป็นไปอย่างราบรื่น
CD มีสองความหมาย Continuous Delivery กับ Continuous Deployment แล้วแต่บริบท Continuous Delivery คือส่งมอบซอฟต์แวร์ได้ตลอดเวลา ส่วน Continuous Deployment คือเอาขึ้นระบบจริงแบบอัตโนมัติเลย
ทำไมถึงสำคัญน่ะเหรอ? สมัยก่อนกว่าจะออกโปรแกรมใหม่ได้ทีนึง ต้องใช้เวลาเป็นเดือนๆ เดี๋ยวนี้โลกมันหมุนเร็ว ถ้าเรายังทำแบบเดิมๆ ก็สู้คนอื่นไม่ได้ CI/CD ช่วยให้เราออกโปรแกรมใหม่ได้เร็วขึ้น แก้บั๊กได้ไวขึ้น แถมยังลดความเสี่ยงที่จะเกิดข้อผิดพลาดด้วย
Git คือระบบจัดการเวอร์ชันของโค้ด (Version Control System) Github ก็คือเว็บที่เอาไว้เก็บโค้ด Git นั่นแหละ คิดซะว่า Git คือสมุดจด ส่วน Github คือตู้เก็บสมุดจดของเรา เวลาทำงานเป็นทีม ทุกคนก็ใช้ Git ในการแก้ไขโค้ด แล้วก็ผลัก (push) โค้ดขึ้น Github เพื่อให้คนอื่นเห็น
git clone [repository_url]
git add .
git commit -m "แก้ไขโค้ด"
git push origin main
YAML คือภาษาที่ใช้เขียนไฟล์ Configuration ของ Github Actions มันอ่านง่ายกว่า XML เยอะ (สมัยก่อนผมเจอแต่ XML ปวดหัวมาก) YAML จะใช้ Indentation (การเยื้อง) เพื่อบอกโครงสร้างของข้อมูล
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy
run: echo "Deploying to production..."
Docker คือระบบ Containerization ที่ทำให้เราแพ็กโปรแกรมของเราพร้อมกับ Dependencies ทั้งหมด แล้วเอาไปรันที่ไหนก็ได้ Docker ช่วยให้ CI/CD Pipeline ของเรามีความสม่ำเสมอมากขึ้น เพราะไม่ว่าเราจะรัน Pipeline บนเครื่องไหน ผลลัพธ์ก็จะเหมือนเดิมเสมอ
เริ่มจากสร้าง Repository บน Github ก่อนเลย แล้วก็สร้างโฟลเดอร์ .github/workflows ใน Repository นั้น ในโฟลเดอร์นี้แหละที่เราจะใส่ไฟล์ YAML ที่เป็น Configuration ของ Github Actions
ไฟล์ YAML แต่ละไฟล์ จะแทน Workflow หนึ่ง Workflow Workflow ก็คือชุดของงาน (Jobs) ที่เราต้องการให้ Github Actions ทำ
สร้างไฟล์ YAML ในโฟลเดอร์ .github/workflows ตั้งชื่ออะไรก็ได้ เช่น deploy.yml แล้วก็ใส่โค้ด YAML ที่เราต้องการลงไป ลองดูตัวอย่างนี้
name: Deploy to Production
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy
run: echo "Deploying to production..."
โค้ดนี้จะทำอะไรบ้าง? name คือชื่อ Workflow on คือ Trigger ที่จะทำให้ Workflow ทำงาน ในที่นี้คือเมื่อมีการ Push โค้ดขึ้น Branch main jobs คือชุดของงาน ในที่นี้มีสองงานคือ build กับ deploy build จะทำการติดตั้ง Dependencies แล้วก็ Build โปรแกรม ส่วน deploy จะทำการ Deploy โปรแกรมขึ้น Production
สังเกตว่า deploy มี needs: build นั่นแปลว่า deploy จะรอให้ build เสร็จก่อนถึงจะเริ่มทำงาน
หลังจากสร้างไฟล์ Workflow แล้ว ก็ Push โค้ดขึ้น Github เลย Github Actions จะตรวจจับไฟล์ Workflow ของเรา แล้วก็เริ่มทำงานตามที่เรากำหนด
เราสามารถเข้าไปดู Log ของ Workflow ได้ใน Tab "Actions" ของ Repository ของเรา ถ้ามีอะไรผิดพลาด เราก็จะเห็น Error Message ใน Log นั่นแหละ
บางครั้งเราต้องใช้ Credentials ใน Workflow ของเรา เช่น API Key หรือ Password เราไม่ควรใส่ Credentials เหล่านี้ลงไปในไฟล์ YAML โดยตรง เพราะมันจะไม่ปลอดภัย Github Actions มีระบบ Secrets ที่เราสามารถเก็บ Credentials ไว้ แล้วเรียกใช้ใน Workflow ได้
เข้าไปที่ "Settings" ของ Repository แล้วเลือก "Secrets" จากนั้นก็ Add New Secret ตั้งชื่อ Secret แล้วก็ใส่ Value ลงไป ใน Workflow เราสามารถเรียกใช้ Secret ได้โดยใช้ ${{ secrets.SECRET_NAME }}
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy
run: |
echo "Deploying to production with API Key: ${{ secrets.API_KEY }}"
# โค้ด Deploy ของเรา
อย่าลืมเข้าไปดู SiamCafe Blog เพื่ออ่านบทความอื่นๆ ที่น่าสนใจด้วยนะครับ
นอกจาก Github Actions แล้ว ก็ยังมี CI/CD Tools อื่นๆ อีกเยอะแยะ เช่น Jenkins, Gitlab CI, CircleCI แต่ละตัวก็มีข้อดีข้อเสียต่างกันไป
Jenkins เป็น Open Source ที่เก่าแก่และมี Plugin เยอะมาก แต่ว่า Configuration ค่อนข้างซับซ้อน Gitlab CI ก็เป็นที่นิยม เพราะมัน Integrate กับ Gitlab ได้อย่างลงตัว CircleCI ก็ใช้งานง่าย แต่ว่าอาจจะมีราคาสูงกว่า
| เครื่องมือ | ข้อดี | ข้อเสีย | เหมาะกับใคร |
|---|---|---|---|
| Github Actions | ใช้งานง่าย, ฟรีสำหรับ Open Source Project, Integrate กับ Github ได้ดี | อาจจะไม่ยืดหยุ่นเท่า Jenkins | โปรเจ็กต์ขนาดเล็กถึงกลางที่ใช้ Github |
| Jenkins | ยืดหยุ่นสูง, มี Plugin เยอะ, Open Source | Configuration ซับซ้อน | โปรเจ็กต์ขนาดใหญ่ที่ต้องการความยืดหยุ่นสูง |
| Gitlab CI | Integrate กับ Gitlab ได้ดี, ใช้งานง่าย | อาจจะไม่ยืดหยุ่นเท่า Jenkins | โปรเจ็กต์ที่ใช้ Gitlab |
| CircleCI | ใช้งานง่าย, เร็ว | อาจจะมีราคาสูงกว่า | โปรเจ็กต์ที่ต้องการความเร็ว |
สมัยผมทำร้านเน็ตฯ ผมต้องเลือกเครื่องมือที่มันเหมาะกับงบประมาณและความสามารถของทีมเรา ตอนนั้น Jenkins นี่แหละตอบโจทย์ที่สุด แต่เดี๋ยวนี้ Github Actions มันฟรีสำหรับ Open Source Project แล้ว ก็เป็นตัวเลือกที่น่าสนใจมากๆ
เลือกเครื่องมือที่มันเหมาะกับเราที่สุดนะครับ ไม่มีเครื่องมือไหนที่ดีที่สุดในทุกสถานการณ์
อย่าลืมเข้าไปดู SiamCafe Blog เพื่ออ่านบทความอื่นๆ ที่น่าสนใจด้วยนะครับ
ดูวิดีโอเพิ่มเติมเกี่ยวกับGithub Actions Cicd Pipeline:
เอาล่ะน้องๆ มาถึงตรงนี้แล้ว แสดงว่าพอจะเห็นภาพรวมของ Github Actions CI/CD Pipeline กันบ้างแล้วเนอะ สมัยผมทำร้านเน็ต SiamCafe ก็เคยเจอปัญหาคล้ายๆ กัน คือต้องอัพเดทเกมส์ อัพเดทโปรแกรม ให้เครื่องลูกข่ายพร้อมใช้งานตลอดเวลา ซึ่งสมัยนั้นมันไม่มีอะไรแบบนี้หรอก อาศัยสคริปต์ง่ายๆ กับความอดทนล้วนๆ เลย
แต่ยุคนี้มันสบายกว่าเยอะ มีเครื่องมือดีๆ อย่าง Github Actions มาช่วย เราก็ต้องใช้ให้คุ้มค่า วันนี้พี่เลยจะมาแชร์เคล็ดลับที่ได้จากประสบการณ์ตรง หวังว่าจะเป็นประโยชน์นะ
อย่าพยายามยัดทุกอย่างลงไปใน Workflow เดียว มันจะรก แล้วแก้ปัญหายาก ให้แยก Workflow ตามหน้าที่ เช่น Workflow สำหรับ Build, Workflow สำหรับ Test, Workflow สำหรับ Deploy
# .github/workflows/build.yml
name: Build
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
การ Build แต่ละครั้งมันเสียเวลา ถ้า Dependencies เราไม่ได้เปลี่ยนบ่อยๆ ให้ใช้ Caching เพื่อลดเวลาในการ Build
# .github/workflows/build.yml
name: Build
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
การ Test เป็นหัวใจสำคัญของ CI/CD Pipeline อย่าขี้เกียจ Test นะน้อง! เขียน Test Case ให้ครอบคลุมทุก Functionality เพื่อให้มั่นใจว่า Code ที่เรา Deploy ไปมันทำงานได้อย่างถูกต้อง
# .github/workflows/test.yml
name: Test
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
พวก API Key, Password หรือ Credentials ต่างๆ อย่าใส่ไว้ใน Code ตรงๆ เด็ดขาด! ให้ใช้ Github Secrets ในการเก็บข้อมูลเหล่านี้ แล้วเรียกใช้ใน Workflow แทน
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to server
run: |
sshpass -p ${{ secrets.SSH_PASSWORD }} scp -r dist/* ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/var/www/html
ฟรีครับ แต่ก็มี Limit ในเรื่องของเวลาที่ใช้ในการ Run Workflow และ Storage ที่ใช้ ถ้าเกิน Limit ก็ต้องเสียเงินเพิ่ม ซึ่งส่วนใหญ่สำหรับ Project เล็กๆ กลางๆ ก็เหลือเฟือครับ
ลองดูว่า Process ไหนที่มันกินเวลาเยอะ แล้ว Optimize Process นั้นๆ เช่น ใช้ Caching, ใช้ Docker Image ที่มี Dependencies ครบแล้ว หรือเพิ่ม Resources ให้กับ Runner
อ่าน Log ครับ! Github Actions จะมี Log ละเอียดให้เราดูว่า Error มันเกิดจากอะไร แล้วก็ Debug ตาม Log นั้นเลย ถ้าแก้ไม่ได้ ลอง Search Google หรือ Stack Overflow ดู ส่วนใหญ่จะมีคนเคยเจอปัญหาเดียวกันแล้ว
ใช้ Branching Strategy ครับ เช่น สร้าง Branch สำหรับ Development, Staging, Production แล้วกำหนดให้ Workflow Deploy ไป Environment ต่างๆ ตาม Branch ที่ Push เข้ามา
Github Actions CI/CD Pipeline เป็นเครื่องมือที่ทรงพลังมากๆ ที่ช่วยให้เรา Automate กระบวนการ Build, Test, Deploy ได้อย่างมีประสิทธิภาพ ทำให้เราสามารถ Release Software ได้เร็วขึ้น และลดความผิดพลาดที่เกิดจาก Human Error ได้เยอะมากๆ
หวังว่าบทความนี้จะเป็นประโยชน์กับน้องๆ นะครับ ลองเอาไปปรับใช้กับ Project ของตัวเองดู แล้วจะรู้ว่ามัน Work จริงๆ iCafeForex ก็ใช้แนวคิดนี้ในการพัฒนา Platform เหมือนกันนะ
อย่าลืมติดตาม SiamCafe Blog ด้วยนะครับ จะมีบทความ IT ดีๆ มาให้อ่านกันเรื่อยๆ แน่นอน!