File System & Layer #

Hampir semua orang yang menggunakan Docker tahu dua hal: image itu immutable, dan container itu ephemeral. Tapi sangat sedikit yang benar-benar paham mengapa kedua sifat itu muncul. Jawabannya ada di satu tempat — filesystem berlapis yang dipakai Docker di bawah permukaan.

Tanpa memahami layered filesystem, kamu akan terus menulis Dockerfile yang image-nya membengkak, build yang lambat, dan deploy yang tidak konsisten. Dengan memahaminya, kamu bisa menulis Dockerfile yang ramping, build yang cepat, dan storage yang efisien di production.

Artikel ini membongkar fondasi storage Docker dari bawah: union filesystem, image layer, container writable layer, copy-on-write, dan bagaimana semuanya bekerja sama. Tujuannya bukan supaya kamu hafal istilah, tapi supaya kamu punya model mental yang benar tentang apa yang sebenarnya terjadi setiap kali kamu menjalankan docker build atau docker run.

Mengapa Storage Docker Penting Dipahami #

Container sering digambarkan sebagai “mesin virtual yang ringan”, tapi analogi itu menyesatkan. Container bukan VM mini. Ia tidak membawa filesystem sendiri, tidak punya disk image, dan tidak melakukan provisioning disk saat start. Yang ia lakukan adalah mengikat (bind) banyak layer filesystem read-only menjadi satu mount point, lalu menambahkan satu layer writable di atasnya saat runtime.

flowchart TB
    subgraph IMG["Image — Read-Only Layers"]
        L1[Base Image Layer<br/>ubuntu:22.04 — 77 MB]
        L2[apt install nginx — 50 MB]
        L3[COPY config — 0.1 MB]
        L4[CMD nginx — 0 MB]
        L1 --> L2 --> L3 --> L4
    end
    L4 --> UNION[Union Mount<br/>filesystem yang dilihat container]
    UNION --> RUNTIME[Container Writable Layer<br/>perubahan runtime — top layer]

Struktur ini punya tiga konsekuensi besar yang akan kamu temui di seluruh seri storage ini:

  • Image kecil, cache tinggi. Layer yang sama dipakai bersama banyak image. Build inkremental hanya men-download layer yang berubah.
  • Container cepat start. Tidak ada copy filesystem saat start. Yang ditambahkan hanya satu writable layer kosong.
  • Container mudah hilang. Writable layer adalah satu-satunya tempat perubahan runtime — dan ia ikut mati saat container dihapus.

Ketiga konsekuensi ini menentukan semua keputusan storage lain yang akan kamu pelajari di artikel-artikel selanjutnya: kenapa volume dibutuhkan, kenapa data harus dipisahkan, dan kenapa backup berfokus pada data, bukan container.

Apa Itu Docker Filesystem? #

Docker tidak membuat filesystem baru dari nol untuk setiap image. Docker memanfaatkan filesystem Linux yang sudah matang untuk melakukan dua hal:

  • Union mount — menggabungkan banyak direktori menjadi satu tampilan tunggal.
  • Copy-on-write (CoW) — menduplikasi blok hanya saat ada perubahan.

Kombinasi keduanya adalah inti dari seluruh sistem storage Docker. Ia membuat image bisa kecil, container bisa start cepat, dan banyak container bisa berbagi layer yang sama tanpa duplikasi di disk.

flowchart LR
    A[Image Layer A] --> U[Union View]
    B[Image Layer B] --> U
    C[Image Layer C] --> U
    U --> CON[Container melihat<br/>satu filesystem utuh]

Filesystem inilah yang membuat Docker image bersifat immutable (tidak bisa berubah) dan container bersifat ephemeral (sementara). Dua sifat ini bukan fitur tambahan — ia adalah konsekuensi langsung dari cara layer disusun.

Detail menarik: Union filesystem adalah salah satu teknologi yang membuat Docker benar-benar praktis. Tanpa ini, setiap perubahan kode akan mengharuskan build image dari awal dan re-download semua dependency. Dengan layering, build inkremental di Docker biasanya hanya butuh detik.

Jenis-Jenis Storage Driver #

Docker tidak menentukan satu implementasi union filesystem. Ia menyediakan abstraksi storage driver yang bisa memilih implementasi sesuai OS dan kondisi host.

Storage Driver Status Use Case
overlay2 Default & direkomendasikan Linux modern (kernel 4.0+)
btrfs Supported Host filesystem Btrfs
zfs Supported Host filesystem ZFS
fuse-overlayfs Supported Rootless container
vfs Fallback Tidak ada CoW (testing only)
aufs Legacy Tidak direkomendasikan untuk instalasi baru
devicemapper Deprecated RHEL lama, CentOS 7

overlay2 adalah default di semua distribusi Linux modern dan pilihan yang direkomendasikan oleh Docker. Ia stabil, cepat, hemat memori, dan didukung penuh oleh komunitas. Kecuali kamu punya alasan spesifik, gunakan overlay2.

Cek driver yang sedang dipakai di host kamu:

docker info | grep "Storage Driver"

Output yang diharapkan:

Storage Driver: overlay2
Hindari driver legacy. aufs sudah tidak dikembangkan dan hanya ada di kernel lama. devicemapper sudah deprecated di Docker modern. Jika kamu menemukannya di server production, pertimbangkan migrasi ke host dengan overlay2 — driver legacy bisa menimbulkan masalah performa dan stabilitas yang sulit di-debug.

Konsep Union Filesystem #

Union filesystem adalah teknologi yang memungkinkan beberapa direktori di-mount bersamaan di satu path, sehingga pengguna (atau container) melihatnya sebagai satu filesystem utuh.

Contoh konseptual:

Layer A:  /app/main.go
Layer B:  /app/config.yaml

Union View di /app:
  /app/main.go        ← dari Layer A
  /app/config.yaml    ← dari Layer B

Docker menggunakan konsep ini untuk menumpuk image layer dan menampilkannya sebagai satu filesystem ke container. Container tidak tahu ada berapa layer di belakangnya — yang ia lihat adalah satu pohon direktori yang utuh.

Cara Kerja di Overlay2 #

Untuk memahami implementasi nyata, perhatikan struktur internal overlay2:

flowchart TB
    subgraph HOST["Host Filesystem"]
        LOWER[/var/lib/docker/overlay2/.../diff<br/>LOWERDIR — read-only]
        UPPER[/var/lib/docker/overlay2/.../diff<br/>UPPEDIR — writable, per container]
        WORK[/var/lib/docker/overlay2/.../work<br/>WORKDIR — internal atomic ops]
        MERGED[/var/lib/docker/overlay2/.../merged<br/>MERGED — view untuk container]
    end
    LOWER --> MERGED
    UPPER --> MERGED
    WORK -.-> UPPER
  • Lowerdir — kumpulan image layer (read-only). Dipakai bersama oleh banyak container.
  • Upperdir — writable layer milik satu container. Di sinilah perubahan runtime disimpan.
  • Workdir — direktori internal yang digunakan kernel untuk operasi atomic saat copy-up.
  • Merged — hasil union yang dilihat oleh container saat membaca path.

Container tidak pernah langsung mengakses lowerdir atau upperdir. Ia hanya melihat merged — satu filesystem utuh yang merupakan gabungan keduanya.


Apa Itu Layer di Docker? #

Layer adalah snapshot filesystem yang bersifat read-only. Setiap layer merepresentasikan satu perubahan filesystem — biasanya satu instruksi di Dockerfile.

Contoh Dockerfile:

FROM alpine:3.19
RUN apk add --no-cache curl
COPY app.sh /app.sh
CMD ["sh", "/app.sh"]

Layer yang terbentuk:

  1. Base layer — Alpine Linux 3.19 (~7 MB).
  2. Layer RUN — hasil instalasi curl (~1 MB).
  3. Layer COPY — file app.sh (~0.01 MB).
  4. Layer CMD — tidak menambah filesystem (instruksi metadata, bukan data).

Setiap layer:

  • Immutable — tidak bisa diubah setelah dibuat. Konten layer di-hash (SHA256) dan hash itu jadi identitas layer.
  • Reusable — bisa dipakai bersama oleh image lain yang punya instruksi identik.
  • Cacheable — Docker build cache melihat layer berdasarkan hash instruksi + konteks. Jika tidak berubah, layer dipakai ulang dari cache.
flowchart TB
    A[FROM alpine:3.19] --> B[RUN apk add curl]
    B --> C[COPY app.sh /app.sh]
    C --> D[CMD app.sh]
    
    A -.->|Layer 1: base alpine| LA[alpine-base.tar]
    B -.->|Layer 2: apk result| LB[curl-install.tar]
    C -.->|Layer 3: app.sh| LC[app-sh.tar]
    D -.->|Metadata| LD[cmd-meta.json]

Layer dan Dockerfile #

Prinsip krusial yang harus kamu pegang:

Satu instruksi Dockerfile = satu layer baru (untuk instruksi yang mengubah filesystem).

Instruksi Membuat Layer? Alasan
FROM Ya Menarik base image (beberapa layer)
RUN Ya Eksekusi command yang menghasilkan perubahan filesystem
COPY Ya Menambahkan file ke image
ADD Ya Sama seperti COPY, plus fitur ekstrak tar & URL
CMD Tidak Hanya metadata default command
ENTRYPOINT Tidak Hanya metadata executable
ENV Tidak Environment variable, tidak menambah file
WORKDIR Tidak Hanya mengubah direktori kerja
EXPOSE Tidak Hanya metadata port
LABEL Tidak Hanya metadata key-value
ARG Tidak Build-time variable
USER Tidak Mengubah user context, tidak menambah file
VOLUME Tidak Mendeklarasikan mount point

Implikasinya langsung: urutan instruksi di Dockerfile sangat berpengaruh pada ukuran image dan kecepatan build. Setiap RUN, COPY, dan ADD menambah layer permanen di image final.


Copy-on-Write — Kunci Efisiensi Docker #

Docker menggunakan mekanisme copy-on-write (CoW) saat container berjalan. CoW adalah optimasi: file hanya disalin saat ada upaya untuk mengubahnya, bukan saat dibaca.

Alurnya:

  1. Container membaca file → langsung dari image layer (lowerdir), tidak ada copy.
  2. Container mengubah file → file disalin dari lowerdir ke upperdir (writable layer), lalu diubah di sana.
  3. Perubahan hanya terjadi di upperdir — image layer tetap utuh dan bisa dipakai container lain.
flowchart TB
    subgraph READ["Container baca /etc/nginx.conf"]
        R1[Request baca] --> R2{File ada<br/>di upperdir?}
        R2 -- Tidak --> R3[Baca langsung<br/>dari lowerdir]
        R2 -- Ya --> R4[Baca dari upperdir]
    end
    
    subgraph WRITE["Container tulis /etc/nginx.conf"]
        W1[Request tulis] --> W2{File ada<br/>di upperdir?}
        W2 -- Tidak --> W3[COPY-UP<br/>copy file ke upperdir]
        W2 -- Ya --> W4[Modifikasi di upperdir]
        W3 --> W4
    end

Keuntungan CoW untuk Performa #

  • Read cepat — file yang tidak berubah langsung dibaca dari image layer. Tidak ada overhead.
  • Write hanya saat perlu — container yang hanya membaca konfigurasi tidak pernah memicu copy.
  • Image tetap aman — perubahan runtime tidak pernah menyentuh image layer asli. Image selalu bisa di-reuse.
  • Container terisolasi — setiap container punya upperdir sendiri, sehingga perubahan di satu container tidak memengaruhi container lain yang dari image sama.
Insight praktis: Ini menjelaskan kenapa container start dalam detik, bukan menit. Saat docker run dieksekusi, Docker tidak menyalin filesystem image. Ia hanya membuat upperdir kosong dan me-mount union. Pekerjaan copy baru benar-benar terjadi saat aplikasi pertama kali menulis file — dan bahkan itu pun lazy.

Writable Layer pada Container #

Saat container dibuat dari image, Docker menambahkan satu writable layer di atas semua image layer. Layer ini sering disebut container layer atau runtime layer.

Karakteristiknya:

  • Unik per container — setiap container dari image yang sama punya upperdir sendiri.
  • Bersifat sementara — hilang saat container dihapus.
  • Tidak cocok untuk data permanen — karena sifatnya yang sementara, menyimpan data penting di sini adalah anti-pattern.
flowchart TB
    subgraph SHARED["Shared Image Layers (read-only)"]
        L1[Base]
        L2[RUN]
        L3[COPY]
    end
    
    subgraph C1["Container A"]
        L1 --> UA[Upperdir A<br/>writable]
        L2 --> UA
        L3 --> UA
    end
    
    subgraph C2["Container B"]
        L1 --> UB[Upperdir B<br/>writable]
        L2 --> UB
        L3 --> UB
    end
    
    SHARED --> C1
    SHARED --> C2

Ini menjelaskan banyak perilaku Docker yang sering membuat bingung:

  • Mengapa docker commit bisa membuat image baru? Karena docker commit membekukan upperdir menjadi image layer baru. Isi upperdir menjadi layer di image baru.
  • Mengapa data MySQL hilang saat container dihapus? Karena /var/lib/mysql ada di upperdir, dan upperdir ikut hilang saat container dihapus.
  • Mengapa docker run dari image yang sama sangat cepat? Karena image layer tidak disalin. Hanya upperdir kosong yang dibuat.

Inilah alasan volume dan bind mount menjadi sangat penting di Docker — ia memindahkan data dari upperdir ke filesystem host, sehingga data tetap ada walau container hancur.

Anti-pattern kritis: Jangan pernah menyimpan data penting di writable layer container. Database, file upload user, log aplikasi, dan konfigurasi runtime harus selalu berada di volume atau bind mount. Writable layer akan hilang saat container dihapus, di-restart dengan image baru, atau di-recreate oleh orchestrator. Ini adalah sumber data loss paling umum di Docker.

Image Bersifat Immutable #

Karena layer image bersifat read-only, image tidak bisa diubah setelah build. Setiap perubahan menghasilkan image baru. Ini mungkin terdengar sebagai keterbatasan, tapi sebenarnya adalah fitur kekuatan Docker.

Keuntungan immutability:

  • Build reproducible — image yang sama selalu menghasilkan container yang sama. Tidak ada “configuration drift” misterius.
  • Rollback mudah — jika image baru bermasalah, cukup kembali ke tag lama. Tidak perlu uninstall atau reconfigure.
  • Konsisten antar environment — image yang sama berjalan identik di laptop developer, CI, staging, dan production.
  • Audit-friendly — konten image bisa di-inspect (mis. dengan docker history) dan di-hash untuk verifikasi integritas.
  • Cache friendly — layer image yang sama dipakai bersama, sehingga deployment tidak perlu download image dari nol.

Konsep ini adalah pondasi dari beberapa workflow penting di industri:

  • CI/CD — image Docker menjadi build artifact yang sama dari pipeline sampai production.
  • GitOps — image tag adalah reference yang bisa di-version di Git (mis. :v1.2.3).
  • Immutable infrastructure — server (atau container) yang berjalan tidak di-patch di tempat, tapi di-replace dengan instance baru dari image baru.
# Lihat history layer sebuah image
docker history nginx:1.25

# Output:
# IMAGE          CREATED       CREATED BY                                      SIZE
# a4d8d7c4b1f0   3 weeks ago   CMD ["nginx" "-g" "daemon off;"]              0B
# e9b1f5c0a2c3   3 weeks ago   EXPOSE 80                                       0B
# ...

Layer Sharing dan Efisiensi Storage #

Docker menyimpan layer berdasarkan hash konten (SHA256). Jika dua image memiliki layer dengan konten identik, layer itu hanya disimpan satu kali di disk dan dipakai bersama.

Contoh dampak:

Skenario Tanpa Sharing Dengan Layer Sharing
10 image berbasis alpine:3.19 10 × 7 MB = 70 MB 7 MB (1 layer dipakai bersama)
5 image dengan apt install curl identik 5 × 1 MB = 5 MB 1 MB (1 layer dipakai bersama)
50 microservice dengan base image sama 50 × base size 1 × base size

Inilah alasan Docker hemat storage di skala besar. Bayangkan kamu punya 50 microservice di registry, semua berbasis node:20-alpine. Tanpa sharing, base layer di-download dan disimpan 50 kali. Dengan sharing, hanya 1 kali.

flowchart LR
    subgraph REG["Docker Host Disk"]
        B[alpine-base.tar<br/>7 MB]
        C[curl-install.tar<br/>1 MB]
    end
    
    IMG1[Image: app1] --> B
    IMG1 --> C
    IMG2[Image: app2] --> B
    IMG2 --> C
    IMG3[Image: app3] --> B
    IMG3 --> C
    
    B -.satu salinan.-> REG
    C -.satu salinan.-> REG

Implikasi praktis:

  • Pull image lebih cepat — Docker hanya men-download layer yang belum ada di host.
  • Push image ke registry lebih cepat — layer yang sudah ada di registry tidak perlu di-upload ulang.
  • Storage host lebih efisien — layer bersama tidak diduplikasi.
Trik optimasi: Saat menulis Dockerfile, sengaja buat layer yang bisa di-share antar image. Misalnya, pisahkan instalasi system package (jarang berubah) dari COPY source code (sering berubah). Ini membuat layer system package di-cache lama dan hanya layer COPY yang invalidate saat build.

Dampak Layer terhadap Build Performance #

Docker build cache bekerja berdasarkan konten layer. Cache key untuk setiap layer adalah hash dari:

  1. Isi instruksi Dockerfile.
  2. Hash dari parent layer.
  3. Untuk COPY/ADD: hash konten file yang di-copy.

Jika semua itu cocok dengan build sebelumnya, layer dipakai dari cache. Jika salah satu berubah, layer di-build ulang, dan semua layer di bawahnya juga ikut di-rebuild.

Anti-Pattern: Copy Source Code Terlalu Dini #

# ANTI-PATTERN: source code di-copy sebelum dependency
FROM node:20-alpine
WORKDIR /app
COPY . .                  # ← perubahan 1 baris kode invalidate semua cache
RUN npm install           # ← npm install dijalankan ulang setiap build
CMD ["node", "index.js"]

Masalah: setiap kali kamu mengubah satu baris kode di source, Docker membatalkan cache dari baris COPY . . ke bawah. Ini termasuk npm install, yang biasanya butuh waktu lama.

Solusi: Pisahkan Dependency dan Source Code #

# BENAR: dependency di-install dulu, source code belakangan
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./     # ← hanya invalidate saat package.json berubah
RUN npm install           # ← cached selama package.json tidak berubah
COPY . .                  # ← invalidate setiap source code berubah
CMD ["node", "index.js"]

Hasil: perubahan source code tidak menjalankan npm install ulang. Build inkremental biasanya hanya butuh 1–2 detik.

flowchart LR
    subgraph BAD["Anti-Pattern"]
        B1[COPY . .] --> B2[RUN npm install]
        B2 --> B3[perubahan kode<br/>→ npm install ulang]
    end
    
    subgraph GOOD["Best Practice"]
        G1[COPY package.json] --> G2[RUN npm install]
        G2 --> G3[COPY . .]
        G3 --> G4[perubahan kode<br/>→ npm install cached]
    end

Tips Tambahan untuk Build Cache #

Gunakan BuildKit (default di Docker modern) untuk fitur cache lanjutan:

  • Cache mount — mount cache direktori ke build (--mount=type=cache). Cache bertahan antar build.
  • Build cache ke registry — push/pull build cache dari Docker Hub atau ECR untuk CI yang berjalan di mesin fresh.
  • Multi-stage build — pisahkan build artifact dari runtime image. Runtime image tidak membawa toolchain yang berat.

Aktifkan BuildKit:

# Di environment variable
export DOCKER_BUILDKIT=1

# Atau di Dockerfile (modern syntax)
# syntax=docker/dockerfile:1

Mount yang Perlu Kamu Ketahui #

Docker juga menyediakan tiga jenis mount yang bisa kamu tambahkan saat container berjalan. Ini relevan karena filesystem layer adalah pondasi, tapi volume dan bind mount adalah lapisan di atasnya untuk data persisten.

flowchart TB
    subgraph TYPES["Jenis Mount di Docker"]
        V[Volume<br/>dikelola Docker]
        B[Bind Mount<br/>path host manual]
        T[tmpfs<br/>disimpan di RAM]
    end
    
    V --> PERSIST[Data persisten<br/>untuk production]
    B --> DEV[Live reload<br/>untuk development]
    T --> SECRET[Sensitive data<br/>non-persistent]

Tiga jenis mount ini akan dibahas mendalam di artikel-artikel selanjutnya dalam section ini. Untuk sekarang, cukup pahami bahwa ketiganya beroperasi di atas layered filesystem yang sudah kita bahas — mereka tidak menggantikan image layer, tapi menambah data persistence di luarnya.

Jenis Mount Lokasi Fisik Persisten? Use Case Utama
Volume /var/lib/docker/volumes/... Ya (dikelola Docker) Database, upload, production data
Bind Mount Path host sesuai yang kamu tentukan Ya (tergantung host) Source code untuk live reload, config
tmpfs RAM Tidak Secret, session, cache sensitif

Best Practice Filesystem dan Layer #

Prinsip-prinsip ini merangkum pelajaran dari seluruh artikel.

1. Minimalkan Jumlah Layer #

Gabungkan perintah yang terkait dalam satu RUN:

# BENAR: satu layer untuk install + cleanup
RUN apt-get update && \
    apt-get install -y curl nginx && \
    rm -rf /var/lib/apt/lists/*
# ANTI-PATTERN: banyak layer kecil
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y nginx
RUN rm -rf /var/lib/apt/lists/*

Versi pertama membuat 1 layer, versi kedua membuat 4 layer. Versi pertama juga menghapus cache apt di layer yang sama (penting untuk ukuran image), sedangkan versi kedua meninggalkannya di layer sebelumnya.

2. Urutkan Instruksi dengan Benar #

Letakkan yang paling jarang berubah di atas, yang paling sering berubah di bawah:

  1. Base image (paling jarang berubah).
  2. System package install (jarang berubah).
  3. Dependency install dari package manager (berubah saat dependency update).
  4. COPY source code (paling sering berubah).
  5. CMD/ENTRYPOINT (metadata, tidak menambah layer).

3. Gunakan Multi-Stage Build #

Untuk bahasa yang butuh toolchain saat build (Go, Rust, Java, TypeScript), pisahkan build environment dari runtime:

# Stage 1: build
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp

# Stage 2: runtime
FROM alpine:3.19
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]

Hasil: image runtime hanya 10–20 MB, bukan 800 MB seperti image build.

4. Pilih Base Image Sekecil Mungkin #

Base Image Ukuran Use Case
scratch 0 MB Binary statis (Go, Rust)
alpine 5–7 MB Aplikasi ringan, butuh package manager
distroless 10–20 MB Production Java/Node/Go, tanpa shell
debian-slim 30–50 MB Butuh libc tapi ingin lebih kecil dari full
ubuntu/debian 70–120 MB Default, tapi lebih besar dari perlu

Untuk production, alpine atau distroless adalah pilihan terbaik. Untuk development, ubuntu atau debian lebih familiar.

5. Pahami Cache Layer Sebelum Optimasi #

Jangan asal menggabungkan layer. Setiap keputusan trade-off — antara cache hit dan ukuran image, antara jumlah layer dan kebersihan Dockerfile. Pahami implikasinya:

  • Terlalu banyak layer → image besar.
  • Terlalu sedikit layer → cache sering invalidate.
  • Sweet spot → pisahkan yang jarang berubah (cached lama) dari yang sering berubah (cached pendek).

6. Bersihkan Artefak di Layer yang Sama #

Hapus cache package manager dan file temporary di RUN yang sama dengan instalasi:

# BENAR: hapus di layer yang sama
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

# JANGAN: hapus di layer terpisah (file masih ada di layer sebelumnya)
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*   # ← ini tidak mengurangi ukuran image!
Kesalahan umum: Menghapus file di RUN terpisah tidak mengurangi ukuran image. Docker layer immutable — file yang ditambahkan di layer sebelumnya tetap ada. Untuk benar-benar menghapus, lakukan di RUN yang sama dengan pembuatan file.

Ringkasan #

  • Docker image = kumpulan layer read-only yang digabung via union filesystem. Container menambahkan satu layer writable di atas saat runtime. Ini menjelaskan kenapa image kecil, container cepat start, dan data di container hilang saat dihapus.
  • Storage driver default adalah overlay2 untuk Linux modern. Hindari driver legacy seperti aufs dan devicemapper kecuali kamu punya alasan spesifik.
  • Copy-on-write (CoW) adalah mekanisme kunci: file hanya disalin ke writable layer saat ada perubahan. Read langsung dari image layer, write memicu copy-up.
  • Image immutable karena layer read-only. Setiap perubahan menghasilkan image baru. Ini fitur, bukan keterbatasan — mendukung reproducible build, rollback, dan konsistensi environment.
  • Layer sharing berdasarkan content hash. Image dengan layer identik berbagi storage di disk. Inilah kenapa Docker hemat ruang saat punya banyak image dari base yang sama.
  • Build cache bekerja per-layer. Urutan Dockerfile sangat berpengaruh — letakkan yang jarang berubah di atas, yang sering berubah di bawah. Pisahkan COPY package.json dari COPY . . untuk cache npm install yang efektif.
  • Multi-stage build memisahkan build environment dari runtime image, menghasilkan image production yang kecil tanpa mengorbankan toolchain development.
  • Jangan simpan data penting di writable layer container. Writable layer hilang saat container dihapus. Gunakan volume atau bind mount — topik artikel selanjutnya dalam section ini.

← Sebelumnya: Docker Use Case   Berikutnya: Ephemeral Container →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact