Tutorial Setup GitHub Actions untuk CI/CD Docker Multi-Stage Build
AW
Axel W

Dipublikasikan 21 Agustus 2026

Tutorial Setup GitHub Actions untuk CI/CD Docker Multi-Stage Build

Continuous Integration dan Continuous Deployment (CI/CD) adalah fondasi dari software engineering modern. GitHub Actions menyediakan platform otomasi yang terintegrasi langsung dengan repository, memungkinkan tim untuk membangun, menguji, dan deploy aplikasi secara otomatis setiap kali ada perubahan kode. Dalam tutorial ini, kita akan membangun pipeline CI/CD lengkap menggunakan GitHub Actions dengan Docker multi-stage build untuk aplikasi Node.js.

Mengapa Docker Multi-Stage Build Penting

Multi-stage build adalah teknik yang memungkinkan kamu menggunakan beberapa image Docker dalam satu Dockerfile. Setiap stage dapat menggunakan base image yang berbeda dan hanya artefak yang diperlukan yang disalin ke stage final. Hasilnya adalah image production yang jauh lebih kecil, lebih aman, dan lebih cepat di-deploy. Untuk aplikasi Node.js, stage pertama bisa digunakan untuk install dependency dan build, sementara stage final hanya berisi file static dan runtime.

Keuntungan utama dari pendekatan ini adalah ukuran image. Image yang besar memperlambat proses pull dan deploy, terutama dalam environment Kubernetes atau ECS. Selain itu, image yang lebih kecil memiliki attack surface yang lebih kecil karena tidak menyertakan build tools yang tidak diperlukan di production.

Prasyarat dan Setup Awal

Pastikan kamu memiliki repository GitHub dengan aplikasi Node.js yang sudah berjalan secara lokal. Aplikasi harus memiliki script test dan build yang valid. Install Docker Desktop atau Docker Engine di mesin lokalmu untuk testing Dockerfile sebelum push ke GitHub. Pastikan juga kamu memiliki akun Docker Hub atau registry lain untuk menyimpan image hasil build.

Langkah 1: Buat Dockerfile Multi-Stage

Buat file Dockerfile di root proyek dengan struktur multi-stage. Stage pertama menggunakan image Node.js lengkap untuk install dependency dan build aplikasi. Stage kedua menggunakan image yang lebih minimal untuk runtime:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "dist/main.js"]

Perhatikan penggunaan npm ci instead of npm install. Perintah ci lebih cepat dan deterministik karena menggunakan package-lock.json. Flag --only=production memastikan devDependencies tidak ikut masuk ke image final.

Langkah 2: Setup GitHub Actions Workflow

Buat folder .github/workflows di root repository dan tambahkan file ci-cd.yml. Workflow ini akan berjalan setiap kali ada push ke branch main atau pull request. Pipeline terdiri dari tiga job: test, build, dan deploy.

name: CI/CD Pipeline
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run test
      - run: npm run lint

Job test menjalankan unit test dan linter untuk memastikan kode yang masuk ke branch main memenuhi standar kualitas. Cache npm akan mempercepat proses install dependency pada run berikutnya.

Langkah 3: Build dan Push Docker Image

Tambahkan job build yang membuat Docker image dan push ke registry. Gunakan GitHub Container Registry (GHCR) untuk integrasi yang lebih seamless dengan GitHub Actions:

  build:
    needs: test
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository }}:latest

Job build hanya berjalan jika job test sukses. Ini mencegah image yang gagal test di-push ke registry. Gunakan secrets GITHUB_TOKEN yang otomatis tersedia tanpa konfigurasi manual.

Langkah 4: Deploy ke Production

Tambahkan job deploy yang menarik image terbaru dan menjalankannya di production host. Untuk tutorial ini, kita asumsikan kamu menggunakan VPS dengan Docker yang sudah terinstall:

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            docker pull ghcr.io/${{ github.repository }}:latest
            docker stop app || true
            docker rm app || true
            docker run -d --name app -p 3000:3000 ghcr.io/${{ github.repository }}:latest

Job deploy menggunakan SSH action untuk terhubung ke production host. Image terbaru di-pull dari GHCR, container lama dihentikan, dan container baru dijalankan. Pattern ini cocok untuk deployment sederhana. Untuk skala besar, pertimbangkan menggunakan Kubernetes atau AWS ECS.

Langkah 5: Optimasi Cache dan Keamanan

Optimasi cache sangat penting untuk mempercepat build time. GitHub Actions menyediakan cache bawaan untuk npm, tetapi kamu juga bisa menambahkan layer caching untuk Docker build. Gunakan action cache dengan key berdasarkan hash dari package-lock.json dan Dockerfile.

Dari sisi keamanan, jangan pernah menyimpan credential hardcoded dalam workflow. Selalu gunakan GitHub Secrets untuk menyimpan password, token, dan private key. Aktifkan branch protection rule di repository untuk mencegah push langsung ke main tanpa pull request review. Tambahkan scanning vulnerability dengan tools seperti Trivy atau Snyk sebagai bagian dari pipeline.

Dokumentasi lengkap GitHub Actions tersedia di docs.github.com. Untuk best practices Docker multi-stage build, kunjungi docs.docker.com. Pipeline CI/CD yang baik tidak hanya mengotomasi deployment, tetapi juga meningkatkan kepercayaan tim terhadap kualitas kode yang masuk ke production.

Monitoring dan Troubleshooting Pipeline

Setelah pipeline berjalan, monitoring menjadi kunci untuk memastikan keandalan jangka panjang. Gunakan tab Actions di repository GitHub untuk melihat history setiap workflow run. Jika job gagal, log output akan menunjukkan step mana yang bermasalah. Perhatikan durasi setiap step untuk mengidentifikasi bottleneck.

Umumnya, step npm ci dan Docker build adalah yang paling memakan waktu. Optimasi dengan cache yang tepat dapat mengurangi durasi pipeline hingga 70 persen. Jangan lupa untuk mengatur notifikasi failure ke Slack atau email sehingga tim dapat merespons dengan cepat ketika deployment bermasalah.