- การใช้งาน GitLab CI/CD
- 1. ภาพรวมการทำงานของ GitLab CI/CD
- 2. Pipeline แรกด้วย .gitlab-ci.yml
- 3. Stage และ Job
- 4. เลือก Docker Image สำหรับ Job
- 5. before_script และ after_script
- 6. ใช้ Cache ลดเวลาติดตั้ง Dependency
- 7. Artifact
- 8. ใช้ rules ควบคุมว่า Job จะทำงานเมื่อใด
- 9. CI/CD Variables และ Secret
- 10. ตัวอย่าง Pipeline สำหรับ Node.js / React
- 11. Pipeline สำหรับ Merge Request
- 12. ใช้ needs เพื่อให้ Pipeline เร็วขึ้น
- 13. สร้าง Docker Image ด้วย GitLab CI
- 14. Environment: Staging และ Production
- 15. GitLab Runner คืออะไร
- 16. ตรวจสอบ Syntax ก่อน Commit
- 17. ใช้ Runner Tag
- 18. Retry และ Allow Failure
- 19. ตัวอย่างโครงสร้าง Pipeline ที่เหมาะกับ Web Application
- 20. แนวทางใช้งาน GitLab CI/CD ที่แนะนำ
- 21. ตัวอย่าง .gitlab-ci.yml แบบใช้งานจริง
- 22. GitLab CI/CD เทียบกับ GitHub Actions และ Jenkins
- 23. สรุป
- แหล่งอ้างอิง
#การใช้งาน GitLab CI/CD
GitLab CI/CD คือระบบ Continuous Integration / Continuous Delivery (Deployment) ที่รวมอยู่ใน GitLab โดยตรง ช่วยให้เราสามารถกำหนดกระบวนการตรวจสอบโค้ด ทดสอบ สร้างแพ็กเกจ สร้าง Docker Image และ Deploy ระบบแบบอัตโนมัติทุกครั้งที่เกิดเหตุการณ์ เช่น Push, Merge Request, Tag, Schedule หรือสั่งรัน Pipeline ด้วยตนเอง
หัวใจสำคัญของ GitLab CI/CD คือไฟล์:
.gitlab-ci.yml
ไฟล์นี้มักวางไว้ที่ root directory ของ repository และใช้ YAML สำหรับกำหนด Pipeline, Stage, Job, Script, Rule, Artifact, Cache, Variable และ Environment
#1. ภาพรวมการทำงานของ GitLab CI/CD
โครงสร้างโดยทั่วไปสามารถมองได้ดังนี้
Developer
|
| git push / Merge Request
v
GitLab Repository
|
v
GitLab Pipeline
|
+--> Stage: lint
|
+--> Stage: test
|
+--> Stage: build
|
+--> Stage: deploy
|
v
Server / Cloud
องค์ประกอบหลักมีดังนี้
| องค์ประกอบ | หน้าที่ |
|---|---|
| Pipeline | กระบวนการ CI/CD ทั้งหมดของการรันหนึ่งครั้ง |
| Stage | กลุ่มลำดับการทำงาน เช่น test, build, deploy |
| Job | งานย่อยที่ Runner ต้องรัน |
| Runner | Agent ที่รับ Job ไปประมวลผล |
| Script | คำสั่งที่ Job ต้องรัน |
| Artifact | ไฟล์ผลลัพธ์จาก Job ที่ต้องเก็บหรือส่งต่อ |
| Cache | ไฟล์ที่เก็บไว้เพื่อลดเวลาการติดตั้ง dependency |
| Rule | เงื่อนไขว่าจะให้ Job ทำงานเมื่อใด |
| Variable | ค่าคอนฟิกหรือ Secret ที่ใช้ใน Pipeline |
| Environment | สภาพแวดล้อม เช่น staging หรือ production |
โดยปกติ Stages ทำงานตามลำดับ แต่ Jobs ที่อยู่ใน Stage เดียวกันสามารถทำงานพร้อมกันได้ หากมี Runner รองรับเพียงพอ
#2. Pipeline แรกด้วย .gitlab-ci.yml
สร้างไฟล์:
.gitlab-ci.yml
ตัวอย่างพื้นฐาน:
stages:
- build
- test
- deploy
build-app:
stage: build
script:
- echo "Building application..."
test-app:
stage: test
script:
- echo "Running tests..."
deploy-app:
stage: deploy
script:
- echo "Deploying application..."
เมื่อ Commit และ Push ไฟล์นี้ขึ้น GitLab ระบบจะสร้าง Pipeline ตามเงื่อนไขที่กำหนด
git add .gitlab-ci.yml
git commit -m "Add GitLab CI pipeline"
git push
จากนั้นเปิด GitLab แล้วไปที่:
Build > Pipelines
ชื่อเมนูอาจแตกต่างเล็กน้อยตาม GitLab edition/version แต่สามารถค้นหา Pipeline ของโปรเจกต์ได้จากส่วน CI/CD/Build ของโปรเจกต์
#3. Stage และ Job
ตัวอย่าง:
stages:
- quality
- test
lint:
stage: quality
script:
- npm run lint
unit-test:
stage: test
script:
- npm test
Pipeline จะทำงานตามลำดับ:
quality
|
v
test
แต่ถ้ามีหลาย Job ใน Stage เดียวกัน:
stages:
- test
unit-test:
stage: test
script:
- npm test
type-check:
stage: test
script:
- npm run typecheck
unit-test และ type-check สามารถรันพร้อมกันได้
#4. เลือก Docker Image สำหรับ Job
หาก Runner ใช้ Docker executor สามารถกำหนด image ได้ เช่น:
image: node:22-alpine
test:
script:
- node --version
- npm ci
- npm test
หรือกำหนด image แยกแต่ละ Job:
node-test:
image: node:22-alpine
script:
- npm ci
- npm test
python-test:
image: python:3.13-slim
script:
- pip install -r requirements.txt
- pytest
ข้อดีคือแต่ละ Job มี environment ที่ค่อนข้างคงที่และ reproducible มากขึ้น
#5. before_script และ after_script
กรณีที่ต้องติดตั้ง dependency ก่อนรันทุก Job สามารถใช้ default ได้
default:
image: node:22-alpine
before_script:
- npm ci
test:
script:
- npm test
build:
script:
- npm run build
ส่วน after_script เหมาะกับงาน cleanup หรือ diagnostic เช่น:
test:
script:
- npm test
after_script:
- echo "Test job finished"
#6. ใช้ Cache ลดเวลาติดตั้ง Dependency
การรัน npm ci, pip install, Maven หรือ Gradle ซ้ำทุก Pipeline อาจใช้เวลามาก จึงสามารถใช้ cache
ตัวอย่าง npm:
default:
image: node:22-alpine
cache:
key:
files:
- package-lock.json
paths:
- .npm/
before_script:
- npm ci --cache .npm --prefer-offline
test:
script:
- npm test
แนวคิดสำคัญ:
cache = dependency ที่ใช้ซ้ำเพื่อให้ Job เร็วขึ้น
artifact = ผลลัพธ์ของ Job ที่ต้องเก็บหรือส่งต่อ
ไม่ควรใช้ Cache แทน Artifact โดยไม่จำเป็น
#7. Artifact
สมมติ frontend สร้างไฟล์ใน dist/
build:
image: node:22-alpine
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
GitLab จะเก็บ dist/ เป็น Artifact
สามารถนำไปใช้ใน Job ถัดไป เช่น deploy ได้
#8. ใช้ rules ควบคุมว่า Job จะทำงานเมื่อใด
ตัวอย่างให้ test ทำงานเมื่อ Push branch หรือ Merge Request:
test:
script:
- npm test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
ให้ Deploy เฉพาะ default branch:
deploy-production:
stage: deploy
script:
- ./deploy.sh
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
ให้ Deploy แบบ manual:
deploy-production:
stage: deploy
script:
- ./deploy.sh
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
วิธีนี้เหมาะกับ Production เพราะ Pipeline ผ่าน Test และ Build ได้ แต่ยังต้องกดอนุมัติ Job deploy เอง
#9. CI/CD Variables และ Secret
ไม่ควรเขียน Password, API Key, SSH Key หรือ Token ลงใน .gitlab-ci.yml
ตัวอย่างที่ ไม่ควรทำ:
variables:
DB_PASSWORD: "my-super-secret-password"
ค่าที่ไม่เป็นความลับสามารถเขียนใน YAML ได้:
variables:
NODE_ENV: "test"
ส่วน Secret ควรเพิ่มผ่าน:
Project
> Settings
> CI/CD
> Variables
ตัวอย่างชื่อ Variable:
DEPLOY_HOST
DEPLOY_USER
SSH_PRIVATE_KEY
SSH_KNOWN_HOSTS
DATABASE_URL
API_TOKEN
GitLab รองรับการตั้งค่า Variable แบบ Masked, Hidden และ Protected ตามความเหมาะสม
ใน Job สามารถใช้งานได้เหมือน environment variable:
deploy:
script:
- echo "Deploying to $DEPLOY_HOST"
หลีกเลี่ยงการ
echoSecret ออกสู่ Job log
#10. ตัวอย่าง Pipeline สำหรับ Node.js / React
ตัวอย่างนี้ครอบคลุม lint, test, build และ deploy แบบ manual
stages:
- quality
- test
- build
- deploy
default:
image: node:22-alpine
cache:
key:
files:
- package-lock.json
paths:
- .npm/
before_script:
- npm ci --cache .npm --prefer-offline
lint:
stage: quality
script:
- npm run lint
test:
stage: test
script:
- npm test
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
deploy-production:
image: alpine:3.22
stage: deploy
before_script:
- apk add --no-cache openssh-client rsync
- mkdir -p ~/.ssh
- cp "$SSH_PRIVATE_KEY" ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
- printf '%s\n' "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
script:
- rsync -az --delete dist/ "$DEPLOY_USER@$DEPLOY_HOST:/var/www/myapp/"
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
ตัวอย่างข้างต้นสมมติว่า
SSH_PRIVATE_KEYถูกสร้างเป็น CI/CD Variable ชนิด File และมีการเตรียมสิทธิ์บน Server ปลายทางเรียบร้อยแล้ว
#11. Pipeline สำหรับ Merge Request
CI ที่ดีควรตรวจโค้ดก่อน Merge เช่น:
test-merge-request:
image: node:22-alpine
script:
- npm ci
- npm test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
Workflow จะเป็น:
Create branch
|
v
Commit / Push
|
v
Create Merge Request
|
v
GitLab CI
|
+--> Lint
+--> Test
+--> Security Check
|
v
Code Review
|
v
Merge
#12. ใช้ needs เพื่อให้ Pipeline เร็วขึ้น
Pipeline แบบ Stage ปกติต้องรอทุก Job ใน Stage ก่อนหน้าเสร็จก่อน
บางระบบสามารถใช้ needs เพื่อกำหนด dependency ระหว่าง Jobs โดยตรง
stages:
- build
- test
- deploy
build-frontend:
stage: build
script:
- echo "Build frontend"
build-backend:
stage: build
script:
- echo "Build backend"
test-frontend:
stage: test
needs:
- build-frontend
script:
- echo "Test frontend"
test-backend:
stage: test
needs:
- build-backend
script:
- echo "Test backend"
โครงสร้างจะใกล้เคียง DAG:
build-frontend ---> test-frontend
build-backend ---> test-backend
จึงไม่จำเป็นต้องรอ Job ที่ไม่เกี่ยวข้องทุกตัว
#13. สร้าง Docker Image ด้วย GitLab CI
GitLab สามารถเชื่อมกับ Container Registry ได้โดยใช้ predefined variables เช่น:
CI_REGISTRY
CI_REGISTRY_IMAGE
CI_REGISTRY_USER
CI_REGISTRY_PASSWORD
CI_COMMIT_SHA
ตัวอย่าง Docker-in-Docker:
docker-build:
image: docker:27.5.1-cli
services:
- docker:27.5.1-dind
stage: build
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- echo "$CI_REGISTRY_PASSWORD" |
docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
script:
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
เพื่อความเสถียร ควร pin version ของ Docker image แทนการใช้ docker:latest
Docker-in-Docker อาจต้องการการตั้งค่า Runner เพิ่มเติม โดยเฉพาะ privileged mode ควรพิจารณาขอบเขตความปลอดภัยก่อนใช้งานในระบบจริง
#14. Environment: Staging และ Production
GitLab สามารถผูก Job กับ Environment ได้
deploy-staging:
stage: deploy
script:
- ./deploy-staging.sh
environment:
name: staging
url: https://staging.example.com
deploy-production:
stage: deploy
script:
- ./deploy-production.sh
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
แนวทางที่นิยม:
feature branch
|
v
Merge Request
|
v
lint + test
|
v
main/default branch
|
v
staging
|
v
manual approval
|
v
production
#15. GitLab Runner คืออะไร
Runner คือ Agent ที่รับ Job จาก GitLab มารัน
แนวคิด:
GitLab
|
| Job
v
GitLab Runner
|
+--> Shell Executor
+--> Docker Executor
+--> Kubernetes Executor
สำหรับ GitLab.com มี Instance Runner ให้ใช้งานในหลายกรณี ส่วน GitLab Self-Managed หรือระบบที่ต้องการทรัพยากรเฉพาะสามารถติดตั้ง Runner ของตนเองได้
Docker executor เหมาะกับงาน CI/CD จำนวนมาก เพราะช่วยแยก environment ของแต่ละ Job และกำหนด dependencies ผ่าน Docker image ได้ชัดเจน
#16. ตรวจสอบ Syntax ก่อน Commit
GitLab มี CI Lint สำหรับตรวจ .gitlab-ci.yml
สามารถเปิดจากส่วน CI/CD Editor หรือ Pipeline Editor ของโปรเจกต์เพื่อ Validate configuration ก่อนรันจริง
ข้อผิดพลาดที่พบบ่อย เช่น:
- YAML indentation ผิด
- stage ที่ Job อ้างถึงไม่มีใน stages
- rules เขียนเงื่อนไขผิด
- Runner ไม่มี tag ที่ Job ต้องการ
- Variable ไม่ถูกกำหนด
- Artifact path ไม่ตรงกับไฟล์ที่ Build
#17. ใช้ Runner Tag
กรณีมี Runner หลายประเภท:
runner-linux
runner-docker
runner-production
runner-gpu
สามารถกำหนด tag ใน Job:
deploy-production:
stage: deploy
tags:
- production
script:
- ./deploy.sh
Job จะถูกเลือกไปยัง Runner ที่ตรงกับเงื่อนไข tag
#18. Retry และ Allow Failure
บาง Job อาจต้อง retry เมื่อเกิดปัญหาชั่วคราว:
integration-test:
stage: test
script:
- npm run test:integration
retry: 2
Job ที่ไม่ต้องการให้ Pipeline ล้มทั้งหมด:
code-quality-experimental:
stage: test
script:
- ./experimental-check.sh
allow_failure: true
ควรใช้ allow_failure อย่างระมัดระวัง โดยเฉพาะ Security Test และ Quality Gate ที่มีผลต่อความถูกต้องของ Production
#19. ตัวอย่างโครงสร้าง Pipeline ที่เหมาะกับ Web Application
Git Push / MR
|
v
+-------------+
| Lint |
+-------------+
|
v
+--------------------------+
| Unit Test | Type Check |
+--------------------------+
|
v
+-------------+
| Build |
+-------------+
|
v
+-------------+
| Staging |
+-------------+
|
Manual Approval
|
v
+-------------+
| Production |
+-------------+
ตัวอย่าง Stage:
stages:
- quality
- test
- build
- staging
- production
#20. แนวทางใช้งาน GitLab CI/CD ที่แนะนำ
#20.1 อย่าเก็บ Secret ใน Git Repository
ใช้:
Settings > CI/CD > Variables
และพิจารณา Masked, Hidden, Protected หรือ External Secrets
#20.2 Pin Version ของ Image
ควรใช้:
image: node:22-alpine
แทน:
image: node:latest
เพื่อให้ Pipeline reproducible มากขึ้น
#20.3 แยก Test ออกจาก Deploy
ไม่ควร deploy หาก tests สำคัญยังไม่ผ่าน
#20.4 ใช้ Artifact เมื่อ Job ถัดไปต้องใช้ไฟล์ Build
เช่น:
build -> dist/ -> deploy
#20.5 ใช้ Cache สำหรับ Dependency
เช่น:
npm cache
pip cache
Maven repository
Gradle cache
#20.6 ใช้ rules แทนการรันทุก Job ทุก Branch
เช่น:
Merge Request -> Test
main -> Build
tag -> Release
production -> Manual
#20.7 ทำ Pipeline ให้ Feedback เร็ว
วางงานที่เร็วและสำคัญไว้ก่อน เช่น:
lint -> unit test -> integration test -> build -> deploy
และใช้ needs เมื่อมี dependency graph ที่สามารถรันขนานได้
#21. ตัวอย่าง .gitlab-ci.yml แบบใช้งานจริง
stages:
- quality
- test
- build
- deploy
default:
image: node:22-alpine
cache:
key:
files:
- package-lock.json
paths:
- .npm/
before_script:
- npm ci --cache .npm --prefer-offline
lint:
stage: quality
script:
- npm run lint
unit-test:
stage: test
script:
- npm test
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
deploy-production:
image: alpine:3.22
stage: deploy
before_script:
- apk add --no-cache openssh-client rsync
- mkdir -p ~/.ssh
- cp "$SSH_PRIVATE_KEY" ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
- printf '%s\n' "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
script:
- rsync -az --delete dist/ "$DEPLOY_USER@$DEPLOY_HOST:/var/www/myapp/"
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
Pipeline:
Commit
|
v
Lint
|
v
Unit Test
|
v
Build
|
v
Manual Deploy
|
v
Production
#22. GitLab CI/CD เทียบกับ GitHub Actions และ Jenkins
| หัวข้อ | GitLab CI/CD | GitHub Actions | Jenkins |
|---|---|---|---|
| Config | .gitlab-ci.yml |
.github/workflows/*.yml |
Jenkinsfile |
| Platform Integration | แนบกับ GitLab โดยตรง | แนบกับ GitHub โดยตรง | แยกเป็น CI Server |
| Runner/Agent | GitLab Runner | GitHub Runner | Jenkins Agent |
| Container Support | ดีมาก | ดีมาก | ดี แต่ต้องดูแลเพิ่ม |
| Self-hosted | รองรับ | รองรับ | จุดเด่นหลัก |
| Merge Request Integration | แน่น | ใช้ Pull Request | ต้องเชื่อม integration |
| Maintenance | ต่ำ-กลาง | ต่ำ | กลาง-สูง |
ถ้า Source Code อยู่บน GitLab อยู่แล้ว การใช้ GitLab CI/CD จะลดจำนวนเครื่องมือที่ต้องเชื่อมต่อและทำให้ Repository, Merge Request, Pipeline, Registry และ Deployment อยู่ใน workflow เดียวกันได้ง่าย
#23. สรุป
GitLab CI/CD สามารถเริ่มต้นได้จากแนวคิดเพียงไม่กี่ส่วน:
.gitlab-ci.yml
|
v
Pipeline
|
v
Stages
|
v
Jobs
|
v
Runner
|
v
Build / Test / Deploy
ขั้นตอนเริ่มต้นที่แนะนำคือ:
- สร้าง
.gitlab-ci.yml - เริ่มจาก
lintและtest - เพิ่ม
build - ใช้
artifactsเก็บผลลัพธ์ - ใช้
cacheลดเวลา dependency installation - เก็บ Secret ใน CI/CD Variables
- เพิ่ม staging
- ทำ production deployment แบบ manual ก่อน
- ใช้
rulesจำกัดเงื่อนไขการรัน - ปรับ Pipeline ด้วย
needsเมื่อระบบใหญ่ขึ้น
เมื่อวาง Pipeline อย่างเหมาะสม GitLab CI/CD จะช่วยให้ทีมตรวจโค้ดเร็วขึ้น ลดงาน deploy แบบ manual และทำให้กระบวนการส่งมอบซอฟต์แวร์มีความสม่ำเสมอและตรวจสอบย้อนหลังได้ง่ายขึ้น
#แหล่งอ้างอิง
-
GitLab Docs — Get started with GitLab CI/CD
https://docs.gitlab.com/ci/ -
GitLab Docs — CI/CD pipelines
https://docs.gitlab.com/ci/pipelines/ -
GitLab Docs — CI/CD YAML syntax reference
https://docs.gitlab.com/ci/yaml/ -
GitLab Docs — Pipeline architecture
https://docs.gitlab.com/ci/pipelines/pipeline_architectures/ -
GitLab Docs — CI/CD variables
https://docs.gitlab.com/ci/variables/ -
GitLab Docs — Caching in GitLab CI/CD
https://docs.gitlab.com/ci/caching/ -
GitLab Docs — Docker executor
https://docs.gitlab.com/runner/executors/docker/ -
GitLab Docs — Docker-in-Docker
https://docs.gitlab.com/ci/docker/docker_in_docker/