Masdika Loading..
Masdika.ID

DevOps Engineer

Cloud Engineer

System Administrator

  • Home
  • Portfolio
  • Services
  • Resume
  • Skills
  • Blog
  • Contact
Masdika.ID

DevOps Engineer

Cloud Engineer

System Administrator

Download CV

Recent Posts

  • Panduan Lengkap Install K3s di Ubuntu dan Konfigurasi Remote Kubectl dari Windows PC/Laptop
  • Deploy Next.js di Kubernetes dengan Ingress + SSL Let’s Encrypt
  • Tutorial Lengkap: Membuat Cloudflare API Token & Menggunakannya di Kubernetes dengan cert-manager
  • Panduan Lengkap Deploy WordPress + Redis + MySQL di Kubernetes dengan SSL Cloudflare
  • Panduan Lengkap Install & Konfigurasi Ceph 3 Node dengan RGW (S3 Compatible)

Recent Comments

  1. Masdika.ID on Tutorial Lengkap: Membuat Cloudflare API Token & Menggunakannya di Kubernetes dengan cert-manager
  2. Sahrull on Tutorial Lengkap: Membuat Cloudflare API Token & Menggunakannya di Kubernetes dengan cert-manager
  3. Masdika.ID on Tutorial Lengkap: Membuat Cloudflare API Token & Menggunakannya di Kubernetes dengan cert-manager
  4. Sahrull on Tutorial Lengkap: Membuat Cloudflare API Token & Menggunakannya di Kubernetes dengan cert-manager
  5. Riyan on Cara Kirim Notifikasi Otomatis SSL Expired via Email (Lengkap + Bash Script)

Categories

  • Tutorial

Masddika.BIZ.ID

  • About
  • Terms & Conditions
  • Privacy Policy
BLOG POST

Single-Stage vs Multi-Stage Docker Builds: Panduan Lengkap untuk Meningkatkan Efisiensi Docker Anda

August 10, 2025 Tutorial by Masdika.ID
Single-Stage vs Multi-Stage Docker Builds: Panduan Lengkap untuk Meningkatkan Efisiensi Docker Anda

Apa itu Docker Build?

Docker adalah alat yang memungkinkan pengembang untuk mengemas aplikasi dan semua dependensinya ke dalam container yang dapat dijalankan di mana saja. Proses pembuatan container ini dimulai dengan menggunakan Dockerfile, yang berisi instruksi untuk membangun image Docker.

Namun, tidak semua Dockerfile sama. Ada dua jenis utama dalam Docker build: Single-Stage Build dan Multi-Stage Build. Masing-masing memiliki keuntungan dan kelemahan, tergantung pada kebutuhan proyek Anda.

Dalam artikel ini, kita akan membahas perbedaan utama antara Single-Stage Docker Builds dan Multi-Stage Docker Builds, serta bagaimana memilih yang terbaik untuk aplikasi Anda.

Apa Itu Single-Stage Docker Build? 🟦

Definisi:

Single-Stage Build adalah pendekatan sederhana untuk membangun image Docker. Semua instruksi—mulai dari menginstal dependencies hingga menyalin aplikasi—dilakukan dalam satu tahap. Proses ini tidak memisahkan antara tahap build dan runtime.

Keuntungan:

  • Simplicity: Mudah untuk memahami dan diterapkan, cocok untuk aplikasi kecil atau proyek prototipe.
  • Kecepatan: Lebih cepat dalam membangun image, karena hanya ada satu tahap.

Contoh Dockerfile Single-Stage:

# Menggunakan image dasar
FROM node:14

# Install dependencies dan copy aplikasi
RUN npm install
COPY . /app

# Tentukan direktori kerja
WORKDIR /app

# Expose port untuk akses
EXPOSE 80

# Jalankan aplikasi
CMD ["npm", "start"]

Catatan: pada single‑stage, tool build & cache ikut terbawa ke image final, sehingga ukuran image cenderung lebih besar.

Pada contoh di atas, kita:

  1. Menggunakan image dasar Node.js.
  2. Menginstal dependencies menggunakan npm install.
  3. Menyalin aplikasi ke container dan menjalankan server.

Namun, masalah utama dengan pendekatan ini adalah ukuran image. Image yang dihasilkan akan mencakup semua tool dan dependensi yang digunakan dalam build, bahkan yang tidak dibutuhkan saat aplikasi dijalankan.

Apa Itu Multi-Stage Docker Build? 🐳

Definisi:

Multi-Stage Build adalah pendekatan yang lebih kompleks dan efisien. Pada pendekatan ini, proses build dibagi menjadi beberapa tahap. Biasanya, tahap pertama digunakan untuk membangun aplikasi, sedangkan tahap terakhir hanya berisi file yang diperlukan untuk menjalankan aplikasi.

Keuntungan:

  • Ukuran Image yang Lebih Kecil: Dengan hanya menyalin file yang diperlukan untuk runtime, Anda menghindari membawa build dependencies ke dalam image final.
  • Keamanan: Tools dan dependensi build yang tidak diperlukan tidak ada dalam image final, yang membuat image lebih aman.
  • Optimalisasi: Menghasilkan image yang lebih efisien untuk produksi, karena hanya mengandung file yang benar-benar dibutuhkan.

Contoh Dockerfile Multi-Stage:

# Stage 1: Build Stage
FROM node:14 AS builder

# Install dependencies
RUN npm install
COPY . /app
WORKDIR /app

# Build aplikasi
RUN npm run build

# Stage 2: Final Image
FROM node:14

# Salin hasil build dari Stage 1
COPY --from=builder /app/build /app

# Expose port
EXPOSE 80

# Jalankan aplikasi
CMD ["npm", "start"]

Pada contoh ini:

  1. Stage 1 menginstal dependencies dan membangun aplikasi.
  2. Stage 2 hanya menyalin hasil build dan menjalankan aplikasi, menghasilkan image yang lebih kecil.

Dengan menggunakan multi-stage builds, kita mengurangi ukuran final image dan menghindari membawa dependensi build yang tidak diperlukan.

Perbandingan: Single-Stage vs. Multi-Stage Docker Build 🧐

FiturSingle-Stage BuildMulti-Stage Build
KompleksitasSederhana dan mudah dipahamiLebih kompleks, memerlukan beberapa tahap
Ukuran ImageLebih besar karena membawa tools buildLebih kecil, hanya membawa file runtime
KeamananTools build ada di image akhirTools build tidak ada di image akhir
KecepatanLebih cepat dalam buildLebih lambat karena beberapa tahap build
PenggunaanCocok untuk aplikasi kecil dan prototipeIdeal untuk aplikasi besar dan produksi

Kapan Menggunakan Single-Stage Build? ⚡

  • Prototipe: Jika Anda sedang membuat prototipe atau aplikasi kecil yang tidak akan digunakan di lingkungan produksi.
  • Aplikasi Sederhana: Jika Anda tidak memerlukan optimasi image atau memiliki kebutuhan khusus untuk keamanan dan ukuran image.

Kapan Menggunakan Multi-Stage Build? 🚀

  • Lingkungan Produksi: Jika Anda perlu mengoptimalkan ukuran image untuk kecepatan pengiriman dan penyimpanan di cloud.
  • Aplikasi Besar: Jika aplikasi Anda kompleks, memerlukan banyak dependensi, dan Anda ingin memastikan image akhir tetap bersih dan aman.

Mengapa Multi-Stage Builds Lebih Disarankan? 🔥

Dengan multi-stage builds, Anda bisa memastikan bahwa image akhir Anda hanya berisi file yang benar-benar dibutuhkan untuk menjalankan aplikasi. Ini membuatnya lebih kecil, lebih cepat, dan lebih aman. Di dunia DevOps yang semakin mengutamakan efisiensi dan kecepatan, menggunakan pendekatan ini adalah langkah cerdas, terutama untuk aplikasi berat dan produksi.

Optimalkan Docker Builds Anda untuk Produksi 🏁

Jika Anda masih menggunakan single-stage build untuk aplikasi besar atau aplikasi yang membutuhkan optimasi, sangat disarankan untuk beralih ke multi-stage build. Dengan begitu, Anda akan:

  1. Mempercepat proses build.
  2. Mengurangi ukuran dan biaya penyimpanan image.
  3. Meningkatkan keamanan dengan menghindari pembawaan dependencies yang tidak diperlukan.

Di bawah ini adalah Dockerfile multi‑stage final yang dipakai masdika sudah termasuk tuning PHP penuh (4096M, JIT 512M, file cache), ImageMagick/convert, serta runtime libs agar ekstensi gd/imagick/zip selalu terbaca. Ini membuat image rapi, build cepat, dan optimasi gambar WebP aman. 👇

# =========================
# Stage 1: BUILD (compile PHP extensions, pecl, tuning)
# =========================
FROM dunglas/frankenphp:latest AS builder

# Build deps + ImageMagick dev untuk compile imagick
RUN apt-get update && apt-get install -y --no-install-recommends \
    libjpeg-dev libpng-dev libwebp-dev libxpm-dev libfreetype6-dev libzip-dev \
    libicu-dev libmagickwand-dev imagemagick curl git unzip \
 && pecl install redis imagick \
 && docker-php-ext-enable redis imagick \
 && docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm \
 && docker-php-ext-install -j"$(nproc)" gd mysqli opcache zip intl exif \
 && docker-php-ext-enable gd mysqli opcache zip intl exif \
 && apt-get clean && rm -rf /var/lib/apt/lists/*

# >>> TUNING PHP.INI
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \
    mkdir -p /app/opcache && chown www-data:www-data /app/opcache && \
    echo "memory_limit = 4096M" >> "$PHP_INI_DIR/php.ini" && \
    echo "upload_max_filesize = 1024M" >> "$PHP_INI_DIR/php.ini" && \
    echo "post_max_size = 1024M" >> "$PHP_INI_DIR/php.ini" && \
    echo "max_execution_time = 300" >> "$PHP_INI_DIR/php.ini" && \
    echo "max_input_time = 300" >> "$PHP_INI_DIR/php.ini" && \
    echo "realpath_cache_size = 4096k" >> "$PHP_INI_DIR/php.ini" && \
    echo "realpath_cache_ttl = 600" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.enable=1" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.enable_cli=1" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.memory_consumption=1024" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.interned_strings_buffer=128" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.max_accelerated_files=60000" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.revalidate_freq=0" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.validate_timestamps=0" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.jit=tracing" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.jit_buffer_size=512M" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.file_cache=/app/opcache" >> "$PHP_INI_DIR/php.ini" && \
    echo "opcache.file_cache_only=0" >> "$PHP_INI_DIR/php.ini"

# =========================
# Stage 2: FINAL (runtime only + ImageMagick)
# =========================
FROM dunglas/frankenphp:latest

ENV SERVER_NAME="masdika.biz.id www.masdika.id" \
    FRANKENPHP_MAX_CONCURRENCY=10000 \
    FRANKENPHP_WORKER_TIMEOUT=120 \
    FRANKENPHP_MAX_REQUESTS=50000

# Runtime libs + ImageMagick (convert)
RUN apt-get update && apt-get install -y --no-install-recommends \
    imagemagick \
    libpng16-16 libjpeg62-turbo libwebp7 libxpm4 libfreetype6 \
    libzip4 libicu72 libmagickwand-6.q16-6 \
 && rm -rf /var/lib/apt/lists/*

# Copy extensions, core PHP, dan config dari builder
COPY --from=builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=builder /usr/local/lib/php/ /usr/local/lib/php/
COPY --from=builder /usr/local/etc/php/ /usr/local/etc/php/

# App & Caddy
COPY --chown=www-data:www-data ./wordpress /app/public
COPY ./Caddyfile /etc/caddy/Caddyfile

# Healthcheck
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
  CMD curl -fsS http://localhost/wp-login.php || exit 1

RUN chown -R 33:33 /app
USER www-data

Bagaimana Dockerfile Ini Bekerja (2 Tahap) 🔧

Stage 1 — Builder

  • Memasang paket dev (termasuk komponen pengembangan untuk ImageMagick) agar bisa mengompilasi ekstensi.
  • Mengompilasi & mengaktifkan ekstensi PHP yang dibutuhkan WordPress: gd (dengan freetype, jpeg, webp), mysqli, opcache, zip, intl, exif, redis (PECL), dan imagick (PECL).
  • Menerapkan tuning php.ini penuh:
memory_limit=4096M, upload_max_filesize=1024M, post_max_size=1024M

max_execution_time=300, max_input_time=300, realpath cache (realpath_cache_size=4096k, realpath_cache_ttl=600)

OPcache: enable=1, enable_cli=1, memory_consumption=1024, interned_strings_buffer=128, max_accelerated_files=60000, revalidate_freq=0, validate_timestamps=0

JIT: opcache.jit=tracing, opcache.jit_buffer_size=512M

File cache: opcache.file_cache=/app/opcache, opcache.file_cache_only=0 (folder /app/opcache dimiliki www-data).

Stage 2 — Final/Runtime

  • Memakai image FrankenPHP yang bersih lalu menambahkan runtime libraries (tanpa header dev) + ImageMagick sehingga CLI convert tersedia.
  • Shared libraries yang memastikan ekstensi gd/imagick/zip bisa diload: libpng16, libjpeg-turbo, libwebp, libfreetype6, libzip4, libicu72, libMagickWand-6.q16-6.
  • Menyalin ekstensi & konfigurasi PHP hasil build dari Stage 1; menjalankan aplikasi sebagai user non‑root (www-data).
  • Menambahkan healthcheck ke http://localhost/wp-login.php agar orkestrator tahu status aplikasi.

Dampaknya

  • Optimasi & konversi WebP berjalan mulus—misalnya melalui plugin WP‑Optimize dengan converter Imagick (ImageMagick)—serta pembuatan thumbnail/responsive image WordPress tanpa error.
  • Image final lebih kecil & rapi (alat build tidak ikut terbawa ke produksi).
  • Menghilangkan error umum seperti: convert: not found, libpng16.so.16 not found, libzip.so.4 not found, atau libMagickWand-6.Q16.so.6 not found.

Kenapa setup ini dipilih?

  • ✅ Lebih ramping dari single‑stage: dev headers hanya ada di builder; final cuma bawa runtime.
  • ✅ Stabil untuk WordPress: gd, imagick, zip selalu kebaca karena runtime libs tersedia di stage final.
  • ✅ Gambar/WebP lancar: convert (ImageMagick) tersedia, sehingga plugin optimasi gambar misalnya WP‑Optimize dengan converter Imagick (ImageMagick) dapat melakukan konversi WebP serta thumbnail/responsive image tanpa error.

Tip: Mengaktifkan Imagick di WP‑Optimize

  1. Buka WP‑Optimize → Images → WebP.
  2. Pada Converter, pilih Imagick (ImageMagick). Opsi Generate WebP on upload bisa diaktifkan bila perlu.
  3. Klik Save settings, lalu Run conversion untuk memproses gambar yang sudah ada.

Kesimpulan 🏆

Pilihlah multi-stage build jika Anda ingin:

  • Ukuran image yang lebih kecil.
  • Memisahkan tahap build dan runtime.
  • Mengurangi potensi masalah keamanan dengan tidak menyertakan tools build dalam image produksi.

Single-stage build tetap berguna untuk aplikasi kecil dan saat Anda membutuhkan solusi cepat tanpa terlalu mengkhawatirkan ukuran atau efisiensi.

Jika Anda ingin membuat image Docker yang lebih efisien dan optimal, multi-stage builds adalah pilihan terbaik untuk aplikasi produksi Anda. Dengan mengikuti panduan ini, Anda akan dapat menulis Dockerfile yang lebih bersih dan lebih efisien.

Dengan penjelasan di atas, Anda bisa mengoptimalkan Docker build untuk aplikasi apa pun, baik itu untuk proyek kecil atau aplikasi produksi besar.

Share:
Tags: dockerdockerfilemulti-stagesingle-stage
Related Posts
Deploy Next.js di Kubernetes dengan Ingress + SSL Let’s Encrypt

Buat kamu yang lagi Deploy aplikasi dengan Next.js dan pengen jalan di Kubernetes dengan domain custom + SSL otomatis, artikel…

Deploy Next.js di Docker (Frontend Only) dengan pnpm

🌟 Apa itu Next.js ? Next.js adalah framework React yang populer untuk membangun aplikasi web modern. Dengan fitur SSR (Server…

Post navigation

Prev
Next
2 Comments
  • Krisna 9:23 am August 10, 2025 Reply

    Sangat bermanfaat

    • Masdika.ID 3:40 pm August 25, 2025 Reply

      Oke

Write a comment Cancel Reply


© 2025 www.masdika.id — Semua hak cipta dilindungi