Belajar DevOps Engineer - Docker & Containerization
Episode 7 of 28

Belajar DevOps Engineer - Docker & Containerization

Container membungkus aplikasi beserta seluruh dependensinya menjadi unit yang portabel dan konsisten di laptop, CI, maupun server produksi; di episode ini kalian menguasai image, Dockerfile best practices, multi-stage build, registry, dan Docker Compose, lalu meng-containerisasi aplikasi nyata

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Di episode 6 kita belajar bahwa strategi deployment baru terasa aman jika environment konsisten: yang diuji di staging harus persis yang berjalan di produksi. Masalahnya, environment menempel pada mesin — versi library, interpreter, konfigurasi sistem. Container memecahkan masalah ini dengan membungkus aplikasi beserta seluruh dependensinya menjadi satu unit portabel.

Containerization bukan sekadar "cara menjalankan aplikasi", melainkan standar kemasan. Analoginya seperti peti kemas di dunia logistik: sebelum ada container, memindahkan barang membutuhkan bongkar-muat manual yang berbeda untuk setiap jenis barang. Setelah ada peti kemas, satu bentuk standar bisa dipindahkan dengan crane yang sama di kapal, truk, dan kereta. Docker adalah "peti kemas" untuk software — dan Docker menjadi fondasi dari semua praktik yang akan kalian bangun di episode-episode berikutnya, termasuk Kubernetes.

Container vs Virtual Machine

Sebelum masuk ke Docker, kalian harus paham bedanya container dengan VM — keduanya sering tertukar:

AspekVirtual MachineContainer
IsolasiVirtualisasi perangkat keras (hypervisor)Virtualisasi OS level (kernel bersama)
KernelSendiri (guest OS penuh)Berbagi kernel host
Ukuran imageRatusan MB hingga GBPuluhan hingga ratusan MB
Waktu startDetik hingga menitMilidetik hingga detik
OverheadTinggiRendah

VM mengisolasi seluruh sistem operasi; container mengisolasi proses dan filesystem-nya saja dengan memakai kernel yang sama. Inilah mengapa container ringan — tetapi juga mengapa container tidak bisa menjalankan OS yang kernelnya berbeda dari host (misalnya image Linux di host Windows membutuhkan VM pembantu).

Image dan Container

Dua konsep inti yang wajib kalian bedakan sejak awal:

  1. Image — template read-only berisi filesystem, aplikasi, dan konfigurasi. Image bersifat immutable: sekali dibuat, isinya tidak pernah berubah.
  2. Containerinstance runtime yang dijalankan dari image. Container bisa di-start, di-stop, dihapus, dan punya filesystem writable di lapisan paling atas.

Image tersusun dari layer. Setiap perintah dalam Dockerfile menciptakan satu layer, dan layer ini bisa dipakai ulang (cached) antar image:

text
ubuntu:22.04                ← base image (layer OS)
  + COPY package.json        ← layer 1
  + RUN npm install          ← layer 2
  + COPY src ./src           ← layer 3
  + CMD ["npm", "start"]     ← metadata runtime

Karena layer di-cache, perubahan pada src/ hanya mengulang dari layer 3 ke atas — tanpa membangun ulang seluruh image. Inilah alasan mengapa urutan perintah dalam Dockerfile sangat menentukan kecepatan build.

Best Practices Dockerfile

Dockerfile yang baik adalah Dockerfile yang kecil, aman, dan memanfaatkan cache dengan benar. Aturan yang paling sering kalian jumpai di review code:

  • Jangan jalankan sebagai root — tambahkan user non-privileged sebelum menjalankan aplikasi.
  • Salin file dependency dulu, baru source — agar npm install hanya berjalan ketika package.json berubah.
  • Gunakan base image yang spesifik (tag lengkap, bukan latest).
  • Minimalkan jumlah layer — gabungkan perintah apt-get yang berurutan.
  • Perkecil ukuran — hapus cache paket dan artifact yang tidak dibutuhkan runtime.
  • Gunakan multi-stage build untuk memisahkan environment build dan runtime.
Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
 
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S app && adduser -S app -G app
COPY --from=build --chown=app:app /app/package*.json ./
COPY --from=build --chown=app:app /app/node_modules ./node_modules
COPY --from=build --chown=app:app /app/dist ./dist
USER app
EXPOSE 3000
CMD ["node", "dist/server.js"]

Perhatikan bagian FROM build: ini adalah multi-stage build. Tahap pertama mengompilasi aplikasi beserta dependency; tahap kedua menyalin hanya hasil akhir (dist dan node_modules) ke image runtime yang kecil. Image produksi tidak membawa source code maupun toolchain build.

Registry: Tempat Image Disimpan

Image yang sudah dibangun perlu disimpan di container registry agar bisa diunduh dari mana saja — CI, staging, maupun produksi:

  • Docker Hub — registry publik default.
  • GHCR (GitHub Container Registry) — terintegrasi dengan GitHub, cocok untuk image yang berasal dari repository privat.
  • ECR, GAR, ACR — registry terkelola dari AWS, GCP, dan Azure.
Tag dan push ke registry
docker tag myapp:1.2.0 ghcr.io/username/myapp:1.2.0
docker push ghcr.io/username/myapp:1.2.0

Important

Jangan pernah memakai tag latest untuk image yang dirilis ke produksi. latest bersifat mutable — kalian tidak akan pernah tahu versi apa yang sedang berjalan di cluster. Gunakan tag versi semver (1.2.0) atau digest image (sha256:...) yang immutable. Kita bahas lebih dalam di episode 17.

Praktik: Containerisasi Aplikasi

Mari praktikkan. Ambil aplikasi Node.js sederhana, lalu bungkus dengan Dockerfile di atas. Pastikan file .dockerignore dibuat agar direktori node_modules dan .git tidak ikut masuk konteks build:

.dockerignore
node_modules
.git
dist

Lalu bangun dan jalankan:

Build dan jalankan
docker build -t myapp:0.1.0 .
docker run -d -p 3000:3000 --name myapp myapp:0.1.0
docker logs -f myapp
docker ps

Verifikasi ukuran image yang dihasilkan:

Periksa ukuran image
docker images myapp

Image multi-stage di atas seharusnya berukuran jauh lebih kecil daripada hasil build satu tahap — ini bukti nyata bahwa praktik tidak hanya soal estetika.

Docker Compose untuk Lingkungan Multi-Service

Aplikasi produksi jarang hanya satu service: ada database, cache, message queue. Docker Compose mendefinisikan seluruh lingkungan multi-container dalam satu file compose.yaml:

compose.yaml
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://app:secret@db:5432/app
    depends_on:
      - db
 
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
 
volumes:
  pgdata:
Jalankan stack
docker compose up -d
docker compose ps
docker compose logs app
docker compose down

Compose adalah alat yang sempurna untuk environment dev dan staging. Untuk produksi yang perlu scaling, self-healing, dan rolling update, kalian akan memindahkannya ke Kubernetes di episode 8.

Pitfall Umum

  • Image terlalu besar — build berjalan lambat, download lambat, biaya storage membengkak. Solusi: multi-stage build dan base image ringan (-alpine, distroless).
  • Menjalankan sebagai root — container dengan privilege root adalah pintu masuk utama jika attacker menembus aplikasi.
  • Menaruh secret di image — nilai ENV dan file .env yang ikut ter-build akan tertanam permanen di image. Pakai inject secrets saat runtime (episode 16).
  • Mengabaikan .dockerignore — konteks build membesar dan bisa menyalin node_modules secara tidak sengaja.
  • Menganggap container sebagai VM — jangan apt-get update di dalam container yang berjalan; itu sinyal image kalian kurang lengkap.

Penutup

Inti yang harus dibawa pulang:

  • Container = kemasan aplikasi + dependensi; image adalah template immutable, container adalah instance runtime.
  • Dockerfile best practices: urutan layer, user non-root, base image spesifik, multi-stage build.
  • Image disimpan di registry dengan tag versi yang immutable — bukan latest.
  • Docker Compose merakit lingkungan multi-service untuk dev dan staging.

Di episode 8 selanjutnya kita masuk ke Kubernetes — orkestrator yang mengelola ratusan container di banyak mesin: scheduling, self-healing, scaling, dan networking. Image yang kalian buat di episode ini adalah bahan baku utama yang akan dijalankan cluster Kubernetes.

Belajar DevOps Engineer - Docker & Containerization | Belajar DevOps Engineer