Paket 2 · Praktik LanjutanModul B — CI/CD & Container Pipeline

Full CI/CD Pipeline

Studi kasus pipeline lengkap dari commit hingga deploy produksi: lint, test, scan, build image, push registry, deploy, dan rollback.

Halaman ini merangkai seluruh konsep menjadi satu pipeline produksi untuk aplikasi Node.js dengan Docker. Pipeline bersifat ilustratif; sesuaikan dengan platform dan infrastruktur Anda.

Gambaran pipeline

commit / PR
   │
   ├─ lint & unit test ──┐
   ├─ dependency scan ───┤ paralel
   └─ build ─────────────┘
             │
             ▼
      build & push image
             │
             ├─ deploy staging (otomatis)
             │
             └─ deploy production (approval)
                        │
                   health check
                        │
                   gagal? rollback

Prasyarat

  • Repository dengan Dockerfile.
  • Registry (GHCR/GitLab/Harbor).
  • Server tujuan dengan Docker Compose atau orchestrator.
  • Secret: DEPLOY_HOST, DEPLOY_USER, DEPLOY_KEY, REGISTRY_TOKEN.
  • Environment staging dan production.

Pipeline GitHub Actions

.github/workflows/pipeline.yml:

name: Full CI/CD

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:

permissions:
  contents: read
  packages: write

env:
  IMAGE: ghcr.io/${{ github.repository }}

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - name: Dependency audit
        run: npm audit --audit-level=high

  build:
    needs: quality
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: |
            ${{ env.IMAGE }}:git-${{ github.sha }}
            ${{ env.IMAGE }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Deploy staging
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            cd /srv/app
            export IMAGE_TAG=git-${{ github.sha }}
            docker compose pull
            docker compose up -d
            curl -f http://localhost:3000/health

  deploy-production:
    needs: deploy-staging
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy production
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            cd /srv/app
            export IMAGE_TAG=git-${{ github.sha }}
            docker compose pull
            docker compose up -d
            curl -f https://app.example.com/health

Compose untuk deployment

services:
  app:
    image: ghcr.io/org/app:${IMAGE_TAG}
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    env_file: .env
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 10s
      timeout: 3s
      retries: 5

IMAGE_TAG diambil dari environment saat deploy.

Gate dan approval

  • Staging otomatis setelah merge ke main.
  • Production hanya dari tag v* dan environment approval.
  • Reviewer memeriksa changelog dan hasil staging.
  • Deployment production mencatat siapa dan kapan.

Health check dan rollback

Health endpoint wajib:

curl -f https://app.example.com/health

Rollback dengan tag sebelumnya:

export IMAGE_TAG=git-<sha-sebelumnya>
docker compose pull
docker compose up -d
curl -f https://app.example.com/health

Simpan daftar tag yang pernah sukses di produksi.

GitLab CI padanan

stages: [quality, build, deploy]

quality:
  stage: quality
  image: node:22-alpine
  script:
    - npm ci
    - npm run lint
    - npm test

build:
  stage: build
  image: docker:27
  services: [docker:27-dind]
  script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
    - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"

deploy:
  stage: deploy
  tags: [shell]
  script:
    - cd /srv/app
    - IMAGE_TAG=$CI_COMMIT_SHA docker compose up -d
    - curl -f http://localhost:3000/health
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

Checklist produksi

  • Test dan lint wajib lulus.
  • Image di-scan sebelum deploy.
  • Tag image immutable.
  • Secret tidak masuk log.
  • Staging diuji sebelum production.
  • Health check tersedia.
  • Rollback diuji.
  • Deployment tercatat.
  • Notifikasi kegagalan dikirim.

Ringkasan

  • Pipeline lengkap menghubungkan kualitas, build image, registry, dan deploy.
  • Gate manual melindungi produksi.
  • Health check dan rollback adalah bagian wajib.
  • Setiap langkah harus dapat diaudit dan diulang.

Selanjutnya

Pelajari arsitektur rilis di Production Deployment Architecture.

On this page