1. Node.js API Deployment Pipeline
Pipeline สำหรับ Node.js Express API ที่มีการทดสอบ, linting, security scan และ deployment ไปยัง Heroku/DigitalOcean App Platform
Pipeline Flow Overview
.gitlab-ci.yml Example
image: node:18-alpine
stages:
- build
- test
- security
- deploy
# Cache node_modules for faster builds
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
# Build stage
build-job:
stage: build
script:
- npm ci --cache .npm --prefer-offline
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
# Test stage with parallel jobs
test-unit:
stage: test
script:
- npm run test:unit -- --coverage --passWithNoTests
artifacts:
reports:
junit: reports/junit.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
test-integration:
stage: test
script:
- npm run test:integration
dependencies:
- build-job
# Security scanning
security-audit:
stage: security
script:
- npm audit --audit-level=high
- npx snyk test --severity-threshold=high
allow_failure: false
# Linting job (runs in parallel)
lint:
stage: test
script:
- npm run lint
- npm run type-check
# Deploy to staging
deploy-staging:
stage: deploy
script:
- echo "Deploying to staging environment..."
- npm run deploy:staging
environment:
name: staging
url: https://staging-api.example.com
only:
- develop
# Deploy to production
deploy-production:
stage: deploy
script:
- echo "Deploying to production..."
- npm run deploy:production
environment:
name: production
url: https://api.example.com
when: manual
only:
- main
Key Features
Optimized Caching
ใช้ npm cache และ node_modules cache ลดเวลาการติด dependencies จาก 3-4 นาทีเหลือไม่ถึง 1 นาที
Security Scanning
npm audit และ Snyk สำหรับตรวจสอบ vulnerabilities ใน dependencies ก่อน deploy
Test Coverage Reports
Generate coverage reports ที่ integrate กับ GitLab CI/CD และแสดงผลใน Merge Requests
Environment-based Deployment
Automated deployment ไป staging สำหรับ branch develop และ manual deployment สำหรับ production
2. Docker Build & Push to GitLab Registry
Pipeline สำหรับ build Docker image, run security scans และ push ไปยัง GitLab Container Registry พร้อม support multi-architecture builds
.gitlab-ci.yml for Docker
# Use Docker-in-Docker (dind) service
image: docker:20.10
services:
- docker:20.10-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_DRIVER: overlay2
# Use GitLab Container Registry
CONTAINER_IMAGE: $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:$CI_COMMIT_SHA
CONTAINER_IMAGE_LATEST: $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:latest
stages:
- build
- test
- scan
- push
# Docker Build stage
docker-build:
stage: build
script:
# Login to GitLab Container Registry
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
# Build Docker image
- docker build --pull -t $CONTAINER_IMAGE -t $CONTAINER_IMAGE_LATEST .
# Save image as artifact
- docker save $CONTAINER_IMAGE > image.tar
artifacts:
paths:
- image.tar
expire_in: 1 hour
# Multi-architecture build (optional)
docker-buildx:
stage: build
script:
- |
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker buildx create --name multiarch --use
docker buildx inspect --bootstrap
docker buildx build --platform linux/amd64,linux/arm64 \
-t $CONTAINER_IMAGE \
-t $CONTAINER_IMAGE_LATEST \
--push .
only:
- main
- tags
# Security scan with Trivy
docker-scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL $CONTAINER_IMAGE
- trivy image --format template --template "@/contrib/gitlab.tpl" --output "gl-dependency-scanning-report.json" $CONTAINER_IMAGE
artifacts:
reports:
dependency_scanning: gl-dependency-scanning-report.json
allow_failure: false
# Push to GitLab Registry
docker-push:
stage: push
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
- docker push $CONTAINER_IMAGE
- docker push $CONTAINER_IMAGE_LATEST
dependencies:
- docker-build
- docker-scan
only:
- main
- develop
- /^release\/.*$/
Best Practices Checklist
- ใช้ Docker multi-stage builds เพื่อลดขนาด image ขั้นสุดท้าย
- ใช้ `--pull` flag เพื่อให้แน่ใจว่าได้ base image version ล่าสุด
- Scan image ด้วย Trivy หรือ Clair ก่อน push ไป registry
- Tag images ด้วย commit SHA สำหรับ traceability
- เก็บ Docker credentials ใน GitLab CI/CD Variables
- ใช้ buildx สำหรับ multi-architecture builds (amd64, arm64)
- Clean up old images จาก registry ด้วย retention policies
Dockerfile Example
# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:18-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
USER node
# Copy built application
COPY --from=builder --chown=node:node /app/dist ./dist
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/package*.json ./
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:${PORT:-3000}/health', (r) => {if(r.statusCode!==200)throw new Error()})"
EXPOSE 3000
CMD ["node", "dist/index.js"]
3. Kubernetes Deployment with Helm
Complete GitOps pipeline สำหรับ deploy applications ไปยัง Kubernetes cluster ด้วย Helm charts, ArgoCD และ automated rollback
GitOps Deployment Architecture
Helm Deployment Pipeline
image: alpine/helm:3.12
stages:
- lint
- test
- package
- deploy
variables:
HELM_EXPERIMENTAL_OCI: 1
KUBE_NAMESPACE: ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}
# Lint Helm charts
lint-helm:
stage: lint
script:
- helm lint ./charts/myapp
- helm lint ./charts/myapp --strict
# Test Helm charts with helm test
test-helm:
stage: test
script:
- helm install myapp-test ./charts/myapp --dry-run --debug
# Run helm test if tests are defined
- |
if [ -d "./charts/myapp/templates/tests" ]; then
helm install test-release ./charts/myapp --wait
helm test test-release
helm uninstall test-release
fi
# Package Helm chart
package-helm:
stage: package
script:
- helm package ./charts/myapp --version ${CI_COMMIT_TAG:-0.0.0+${CI_COMMIT_SHA:0:8}} --app-version ${CI_COMMIT_TAG:-0.0.0}
- ls -la *.tgz
artifacts:
paths:
- "*.tgz"
expire_in: 1 week
# Deploy to Kubernetes (Manual approval)
deploy-staging:
stage: deploy
image: bitnami/kubectl:latest
script:
- |
# Configure kubectl
echo "$KUBECONFIG_STAGING" | base64 -d > kubeconfig.yaml
export KUBECONFIG=kubeconfig.yaml
# Deploy with Helm
helm upgrade --install myapp ./charts/myapp \
--namespace ${KUBE_NAMESPACE} \
--values ./charts/myapp/values-staging.yaml \
--set image.tag=${CI_COMMIT_SHA} \
--atomic \
--timeout 5m \
--wait
environment:
name: staging
url: https://staging.myapp.example.com
only:
- develop
# Production deployment with manual trigger
deploy-production:
stage: deploy
image: bitnami/kubectl:latest
script:
- |
echo "$KUBECONFIG_PRODUCTION" | base64 -d > kubeconfig.yaml
export KUBECONFIG=kubeconfig.yaml
helm upgrade --install myapp ./charts/myapp \
--namespace ${KUBE_NAMESPACE} \
--values ./charts/myapp/values-production.yaml \
--set image.tag=${CI_COMMIT_SHA} \
--atomic \
--timeout 10m \
--wait \
--history-max 5
environment:
name: production
url: https://myapp.example.com
when: manual
only:
- main
- tags
# Rollback job
rollback-production:
stage: deploy
image: bitnami/kubectl:latest
script:
- |
echo "$KUBECONFIG_PRODUCTION" | base64 -d > kubeconfig.yaml
export KUBECONFIG=kubeconfig.yaml
helm rollback myapp 0 --namespace ${KUBE_NAMESPACE}
when: manual
only:
- main
allow_failure: false
Advanced Features
Atomic Deployments
ใช้ `--atomic` flag ใน Helm เพื่อให้การ deploy สำเร็จทั้งหมดหรือ rollback อัตโนมัติหากล้มเหลว
Revision History
ตั้งค่า `--history-max` เพื่อควบคุมจำนวน revision ที่เก็บไว้สำหรับ rollback
Manual Rollback Job
สร้าง manual job สำหรับ rollback เพื่อให้ทีม operations สามารถ revert deployment ได้อย่างรวดเร็ว
4. Database Migrations (PostgreSQL)
Pipeline สำหรับจัดการ database migrations แบบปลอดภัย ด้วย Liquibase/Flyway พร้อม rollback capability และ pre-deployment validation
Database Migration Pipeline
image: postgres:15-alpine
services:
- postgres:15-alpine
variables:
POSTGRES_DB: test_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
# Use GitLab CI/CD variables for production DB credentials
# DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
stages:
- validate
- test-migration
- migrate
- rollback-plan
# Validate migration files
validate-migrations:
stage: validate
script:
- |
# Check SQL syntax
for file in migrations/*.sql; do
echo "Validating $file"
psql -v ON_ERROR_STOP=1 -f "$file" --dry-run
done
# Validate with Liquibase/Flyway
- |
if [ -f "liquibase.properties" ]; then
liquibase validate
fi
artifacts:
paths:
- migrations/
# Test migrations on temporary database
test-migration:
stage: test-migration
script:
- |
# Create test database
createdb -U postgres migration_test
# Apply migrations
for file in migrations/*.sql; do
echo "Applying $file to test database"
psql -U postgres -d migration_test -f "$file"
done
# Run data integrity tests
psql -U postgres -d migration_test -f tests/data-integrity-check.sql
# Take schema snapshot for comparison
pg_dump -U postgres -s migration_test > schema_snapshot.sql
artifacts:
paths:
- schema_snapshot.sql
expire_in: 1 week
# Apply migrations to staging database
migrate-staging:
stage: migrate
script:
- |
# Use environment-specific credentials
export PGHOST=${STAGING_DB_HOST}
export PGPORT=${STAGING_DB_PORT}
export PGDATABASE=${STAGING_DB_NAME}
export PGUSER=${STAGING_DB_USER}
export PGPASSWORD=${STAGING_DB_PASSWORD}
# Backup before migration
pg_dump -Fc > backup_${CI_COMMIT_SHA}.dump
# Apply migrations with transaction
psql -v ON_ERROR_STOP=1 <
Safety Guidelines
Critical Safety Rules
- Always backup database before applying migrations
- Test migrations on staging environment first
- Use transactions for atomic migration operations
- Schedule production migrations during maintenance windows
- Have rollback plan ready before execution
Migration Tools Comparison
| Tool | Best For | GitLab Integration | Rollback Support |
|---|---|---|---|
| Liquibase | Enterprise, multiple database types | Excellent (Docker image available) | Built-in rollback commands |
| Flyway | Simple SQL-based migrations | Good (Community edition) | Manual rollback scripts |
| Prisma Migrate | Node.js/TypeScript projects | Good (npm package) | Automatic rollback on failure |
| Custom SQL scripts | Simple projects, full control | Manual (shown in example) | Manual planning required |
5. Monorepo Pipeline (Nx/Turborepo)
Advanced pipeline สำหรับ monorepo projects ที่ใช้ Nx หรือ Turborepo พร้อม selective builds, affected projects detection และ parallel execution
Monorepo Pipeline Architecture
Nx Monorepo Pipeline Example
image: node:18-alpine
services:
- postgres:15-alpine
- redis:7-alpine
# Install Nx CLI globally
before_script:
- npm install -g nx@latest
- npm ci
# Cache node_modules and Nx cache
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .nx/cache/
stages:
- affected
- build
- test
- deploy
# Determine affected projects
affected-projects:
stage: affected
script:
# Get list of affected projects
- npx nx show projects --affected --base=origin/main --head=HEAD --json > affected-projects.json
- echo "Affected projects:"
- cat affected-projects.json
artifacts:
paths:
- affected-projects.json
expire_in: 1 hour
# Build affected projects in parallel
build-affected:
stage: build
parallel:
matrix:
- PROJECT: ["api", "web", "shared", "admin"]
script:
# Check if project is affected
- |
if grep -q "\"$PROJECT\"" affected-projects.json; then
echo "Building $PROJECT..."
npx nx build $PROJECT
else
echo "$PROJECT not affected. Skipping."
fi
dependencies:
- affected-projects
artifacts:
paths:
- dist/apps/$PROJECT/
- dist/libs/$PROJECT/
expire_in: 1 week
# Run tests for affected projects
test-affected:
stage: test
parallel: 3
script:
# Run tests in parallel with Nx
- npx nx affected --target=test --base=origin/main --head=HEAD --parallel=3
artifacts:
reports:
junit: reports/junit/*.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
# Lint all projects (always run)
lint-all:
stage: test
script:
- npx nx run-many --target=lint --all --parallel=3
allow_failure: false
# E2E tests for affected apps
e2e-tests:
stage: test
script:
- npx nx affected --target=e2e --base=origin/main --head=HEAD
services:
- postgres:15-alpine
- redis:7-alpine
artifacts:
paths:
- coverage/
- reports/
expire_in: 1 week
# Deploy affected apps
deploy-affected:
stage: deploy
parallel:
matrix:
- APP: ["api", "web", "admin"]
script:
- |
if grep -q "\"$APP\"" affected-projects.json; then
echo "Deploying $APP..."
npx nx deploy $APP
else
echo "$APP not affected. Skipping deployment."
fi
environment:
name: staging
url: https://staging.example.com
when: manual
only:
- develop
# Full build for main branch (deploy all)
deploy-production:
stage: deploy
script:
- npx nx run-many --target=deploy --all --prod
environment:
name: production
url: https://example.com
when: manual
only:
- main
- tags
Performance Optimization Tips
Nx Cloud Caching
ใช้ Nx Cloud สำหรับ distributed task caching ทำให้ build times ลดลง 70-90% เมื่อ multiple developers หรือ CI runners ทำงานพร้อมกัน
Affected Projects Detection
Build เฉพาะ projects ที่มีการเปลี่ยนแปลงจริง ลดเวลา build จาก 15 นาทีเหลือ 2-3 นาทีสำหรับ minor changes
Parallel Execution
ใช้ parallel matrix jobs และ Nx's built-in parallel execution เพื่อรัน tasks พร้อมกันหลาย project
Dependency Graph Optimization
วิเคราะห์ dependency graph เพื่อหา critical path และ optimize build order สำหรับความเร็วสูงสุด
6. Architecture Overview & Diagrams
ภาพรวม architecture ของ GitLab CI/CD pipeline สำหรับองค์กรขนาดกลางถึงใหญ่ พร้อม integration กับ tools ต่างๆ
Complete CI/CD Architecture Diagram
Key Architecture Decisions
Modular Pipeline Design
แยก pipeline เป็น modules ที่ reuse ได้ เช่น security scanning, deployment templates, test frameworks
Security-First Approach
Embed security scanning ในทุก stage ของ pipeline แทนที่จะเป็นขั้นตอนแยกต่างหาก
Observability Integration
ส่ง metrics, logs และ traces ไปยัง monitoring system สำหรับ real-time feedback
7. สรุปและ Next Steps
ในบทความนี้เราได้เรียนรู้ GitLab CI/CD pipeline สำหรับโปรเจคจริง 5 ประเภท พร้อมตัวอย่างโค้ดที่สามารถนำไปปรับใช้ได้ทันที
สรุป Key Takeaways
-
1
Pipeline Design Patterns
แต่ละ project type มี pipeline pattern เฉพาะตัวที่เหมาะสมกับ workflow และ deployment target
-
2
Security Integration
Security scanning ควร embedded อยู่ใน pipeline ไม่ใช่ separate process
-
3
Performance Optimization
Caching, parallel execution และ affected projects detection ลด build time ได้มากกว่า 50%
-
4
GitOps & Automation
ใช้ GitOps principles สำหรับ deployment ที่มีความเสถียรและสามารถ audit ได้
-
5
Real-World Readiness
ตัวอย่างโค้ดทั้งหมดสามารถนำไปใช้ใน production environment ได้จริง
Next Steps & Recommendations
สำหรับทีมที่เพิ่งเริ่มต้น
- เริ่มจาก Node.js API pipeline ก่อน (Project 1)
- Implement Docker pipeline ตาม (Project 2)
- เพิ่ม security scanning โดยใช้ Trivy
- วัด pipeline performance ก่อนและหลัง optimization
สำหรับทีมระดับกลาง
- Implement Kubernetes deployment pipeline (Project 3)
- เพิ่ม database migration pipeline (Project 4)
- ใช้ GitOps workflow ด้วย ArgoCD
- Implement monitoring และ alerting
สำหรับทีมระดับสูง
- Implement monorepo pipeline (Project 5)
- ใช้ Nx Cloud สำหรับ distributed caching
- สร้าง pipeline templates สำหรับ reuse
- Implement canary deployments และ feature flags
สำหรับองค์กรขนาดใหญ่
- สร้าง internal CI/CD platform บน GitLab
- Implement compliance scanning และ audit trails
- ใช้ GitLab Ultimate features (SAST, DAST, Container Scanning)
- สร้าง self-service pipeline templates
8. Series Recap (Part 1-5)
มาสรุปสิ่งที่เราได้เรียนรู้ตลอดทั้ง 5 parts ของ GitLab CI/CD Series
Part 1: Fundamentals
พื้นฐาน GitLab CI/CD, YAML syntax, jobs, stages, variables
Part 2: Intermediate
Advanced features, artifacts, dependencies, environments
Part 3: Optimization
Performance tuning, caching, parallel jobs, resource usage
Part 4: Best Practices
Security, cost optimization, code quality gates, maturity model
Part 5: Real-World Projects
Production pipelines, complete examples, architecture patterns
Learning Journey Progress
Congratulations!
คุณได้สำเร็จการเรียนรู้ GitLab CI/CD ทั้ง 5 parts และพร้อมนำความรู้ไปใช้ในโปรเจคจริงแล้ว!
ทักษะที่คุณได้เรียนรู้สามารถนำไปใช้ได้กับทีม DevOps, Platform Engineering, หรือ Software Development ทุกประเภท
9. Additional Resources
แหล่งข้อมูลเพิ่มเติมสำหรับศึกษาต่อและนำไปประยุกต์ใช้