Struktur Dockerfile #

Dockerfile adalah blueprint utama dalam proses membangun Docker Image. Setiap instruksi di dalam Dockerfile dieksekusi secara berurutan dan membentuk layer yang menentukan ukuran, performa, keamanan, serta maintainability image yang dihasilkan.

Bagi backend engineer, DevOps, maupun platform engineer, memahami struktur Dockerfile bukan hanya soal bisa build image, tetapi:

  • memahami bagaimana layer bekerja
  • menghindari image yang terlalu besar
  • menjaga keamanan kredensial
  • mempercepat build dan deployment

Bagan Struktur Dockerfile (Konseptual) #

┌──────────────────────────┐
│ FROM                     │  ← Base Image
├──────────────────────────┤
│ ARG                      │  ← Build-time Variable
├──────────────────────────┤
│ ENV                      │  ← Runtime Environment Variable
├──────────────────────────┤
│ WORKDIR                  │  ← Working Directory
├──────────────────────────┤
│ COPY / ADD               │  ← Copy Source Code / Asset
├──────────────────────────┤
│ RUN                      │  ← Install Dependencies / Build
├──────────────────────────┤
│ EXPOSE                   │  ← Port Documentation
├──────────────────────────┤
│ USER                     │  ← Runtime User
├──────────────────────────┤
│ ENTRYPOINT / CMD         │  ← Container Startup Command
└──────────────────────────┘

Bagan di atas menunjukkan urutan logis Dockerfile dari atas ke bawah, meskipun dalam praktik beberapa instruksi bisa diulang atau dikombinasikan.

Konsep Dasar Dockerfile #

  • Dockerfile adalah file deklaratif
  • Setiap instruksi menghasilkan immutable layer
  • Perubahan pada satu layer akan meng-invalidate cache layer setelahnya

Implikasinya:

  • Urutan instruksi sangat penting
  • Kesalahan kecil bisa berdampak ke ukuran dan waktu build

FROM #

Fungsi #

Menentukan base image yang akan digunakan.

Aturan Penting #

  • Instruksi pertama wajib FROM (kecuali ARG sebelum FROM)
  • Bisa digunakan lebih dari satu kali (multi-stage build)

Contoh #

FROM golang:1.22-alpine

Multi-stage Build #

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

FROM gcr.io/distroless/base-debian12
WORKDIR /app
COPY --from=builder /app/app .
CMD ["/app/app"]

ARG #

Fungsi #

Mendefinisikan variable yang hanya tersedia saat build.

Karakteristik #

  • Tidak tersedia saat container runtime
  • Bisa di-override dengan --build-arg

Contoh #

ARG APP_ENV=production
ARG GO_VERSION=1.22
FROM golang:${GO_VERSION}-alpine

ENV #

Fungsi #

Mendefinisikan environment variable saat runtime.

Contoh #

ENV APP_ENV=production
ENV APP_PORT=8080

Perbedaan ARG vs ENV #

AspekARGENV
Waktu hidupBuild timeRuntime
Bisa diakses container
Aman untuk secret

WORKDIR #

Fungsi #

Menentukan direktori kerja di dalam container.

Best Practice #

  • Gunakan WORKDIR dibanding cd di RUN

Contoh #

WORKDIR /app

COPY #

Fungsi #

Menyalin file dari host ke image.

Contoh #

COPY . .
COPY go.mod go.sum ./

Best Practice #

  • Copy file dependency dulu agar cache efektif

ADD #

Fungsi Tambahan dibanding COPY #

  • Bisa extract tar otomatis
  • Bisa download URL (tidak direkomendasikan)

Contoh #

ADD archive.tar.gz /app

Rekomendasi #

Gunakan COPY, kecuali butuh fitur khusus ADD.


RUN #

Fungsi #

Menjalankan perintah saat build image.

Contoh #

RUN apk add --no-cache ca-certificates

Menggabungkan Command #

RUN apk add --no-cache \
    git \
    curl \
 && rm -rf /var/cache/apk/*

EXPOSE #

Fungsi #

Dokumentasi port yang digunakan aplikasi.

Contoh #

EXPOSE 8080

EXPOSE tidak membuka port, hanya dokumentasi.


USER #

Fungsi #

Menentukan user yang digunakan container.

Contoh #

RUN adduser -D appuser
USER appuser

Alasan Penting #

  • Menghindari running sebagai root
  • Meningkatkan keamanan

VOLUME #

Fungsi #

Mendeklarasikan mount point untuk data persisten.

Contoh #

VOLUME ["/data"]

HEALTHCHECK #

Fungsi #

Menentukan mekanisme health monitoring container.

Contoh #

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1

SHELL #

Fungsi #

Mengubah shell default untuk RUN.

Contoh #

SHELL ["/bin/bash", "-c"]

ONBUILD #

Fungsi #

Menentukan trigger untuk image turunan.

Contoh #

ONBUILD COPY . /app

Catatan #

Jarang digunakan, rawan membingungkan.


STOPSIGNAL #

Fungsi #

Menentukan signal untuk menghentikan container.

Contoh #

STOPSIGNAL SIGTERM

CMD #

Fungsi #

Menentukan perintah default saat container dijalankan.

Contoh #

CMD ["./app"]

Karakteristik #

  • Bisa dioverride docker run

ENTRYPOINT #

Fungsi #

Menentukan executable utama container.

Contoh #

ENTRYPOINT ["./app"]

ENTRYPOINT + CMD #

ENTRYPOINT ["./app"]
CMD ["--help"]

Perbedaan CMD vs ENTRYPOINT #

AspekCMDENTRYPOINT
Bisa dioverrideYaSulit
Cocok untukDefault commandBinary utama

Best Practice #

1. Gunakan Base Image Sekecil Mungkin #

  • alpine
  • distroless

2. Manfaatkan Multi-stage Build #

  • Pisahkan build dan runtime
  • Image lebih kecil & aman

3. Optimalkan Cache #

  • COPY dependency sebelum source code

4. Jangan Simpan Secret #

❌ Jangan:

ENV DB_PASSWORD=secret

Gunakan:

  • Docker secrets
  • Environment runtime

5. Jangan Jalankan Sebagai Root #

Gunakan USER non-root.

6. Minimalkan Layer #

  • Gabungkan RUN
  • Hapus cache package manager

7. Tambahkan HEALTHCHECK #

Agar orchestration lebih cerdas.


Penutup #

Dockerfile bukan sekadar file konfigurasi, tetapi fondasi kualitas Docker Image. Dengan memahami setiap instruksi, implikasi layer, dan best practice, kita bisa menghasilkan image yang:

  • kecil
  • cepat
  • aman
  • siap produksi

Pemahaman Dockerfile yang baik adalah skill fundamental bagi engineer modern—terutama di era cloud-native dan container orchestration.

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