Menggunakan Multi-stage Build pada Dockerfile

Multi-stage builds adalah fitur Docker yang memungkinkan kita membuat image dengan beberapa tahap pembangunan. Setiap tahap memiliki Dockerfile sendiri dan dapat menghasilkan image sementara. Fitur ini sangat berguna untuk:

  • Membuat image yang lebih kecil: Dengan memisahkan tahap build dan tahap runtime, kita dapat menghapus file-file yang tidak diperlukan pada tahap runtime.

  • Meningkatkan keamanan: Dengan memisahkan tahap build dan tahap runtime, kita dapat mengurangi risiko serangan terhadap aplikasi.

Contoh Dockerfile dengan multi-stage builds:

# Stage 1: Build
FROM python:3.9-slim-buster as builder
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN python setup.py build_ext --inplace

# Stage 2: Runtime
FROM python:3.9-slim-buster
WORKDIR /app
COPY --from=builder /app .
EXPOSE 5000
CMD ["python", "app.py"]

Selanjutnya kita akan melihat contoh multi-stage builds yang lebih kompleks. Contoh ini akan menunjukkan bagaimana kita bisa memisahkan tahap pembangunan, pengujian, dan produksi dalam satu Dockerfile.

Contoh: Aplikasi Node.js dengan Testing dan Build

Penjelasan:

  1. Stage 1 (builder):

    • Menginstal dependensi dan membangun aplikasi.

    • Hasil build disimpan di direktori build.

  2. Stage 2 (tester):

    • Menyalin hasil build dari stage 1.

    • Menjalankan tes unit.

  3. Stage 3 (production):

    • Menggunakan base image yang lebih kecil (alpine) untuk runtime.

    • Hanya menyalin hasil build yang diperlukan.

    • Mendefinisikan port yang akan di-expose dan perintah untuk menjalankan aplikasi.

Contoh Lain: Aplikasi Python dengan Wheel

Penjelasan:

  • Stage 1 (builder):

    • Menginstal dependensi dan membuat wheel (distribusi Python).

  • Stage 2 (runtime):

    • Menyalin wheel dan distribusi yang telah dibuat.

    • Menginstal wheel untuk membuat lingkungan runtime yang bersih.

Keuntungan Multi-Stage Builds:

  • Image yang lebih kecil: Hanya komponen yang diperlukan untuk runtime yang disertakan dalam image final.

  • Peningkatan keamanan: Memisahkan tahap pembangunan dan runtime mengurangi permukaan serangan.

  • Fleksibelitas: Dapat digunakan untuk berbagai skenario, seperti membangun aplikasi yang kompleks dengan banyak dependensi.

Tips Tambahan:

  • Berikan nama yang jelas untuk setiap stage: Memudahkan untuk melacak tujuan setiap stage.

  • Manfaatkan caching: Gunakan --cache-from untuk memanfaatkan layer cache dari build sebelumnya.

  • Pertimbangkan menggunakan BuildKit: BuildKit adalah engine build Docker yang lebih cepat dan efisien.

Last updated