Traffine I/O

Bahasa Indonesia

2022-06-03

Multi-Stage Builds di Docker

Apa itu Multi-Stage Build

Multi-stage build adalah fitur pada Docker yang membantu menyederhanakan proses pembuatan, mengurangi ukuran image, dan meningkatkan keamanan untuk aplikasi yang dikemas dalam container. Dengan memungkinkan beberapa pernyataan FROM dalam satu Dockerfile, multi-stage build memfasilitasi pembuatan intermediate image sementara yang hanya ada selama proses pembuatan.

Setiap stage dalam multi-stage build dapat diwarisi dari base image yang berbeda, yang memungkinkan penggunaan berbagai alat, pustaka, dan lingkungan yang disesuaikan untuk tugas tertentu. Sebagai hasilnya, pengembang dapat mengoptimalkan setiap stage untuk tujuannya masing-masing, seperti kompilasi atau pengujian, tanpa mempengaruhi image akhir. Hanya stage terakhir dalam proses pembuatan yang menghasilkan output image yang akan didistribusikan, memastikan bahwa hanya file dan dependensi yang diperlukan yang disertakan.

Menggunakan multi-stage build tidak hanya membantu menciptakan image Docker yang lebih bersih dan ramping, tetapi juga membuatnya lebih mudah mengelola proses pembuatan yang kompleks. Dengan memisahkan proses pembuatan ke dalam stage yang berbeda, pengembang dapat fokus pada tugas individu, meningkatkan kejelasan kode, dan menyederhanakan pemecahan masalah saat masalah muncul. Selain itu, multi-stage build menawarkan fleksibilitas dalam penggunaan kembali beberapa stage di seluruh proyek yang berbeda, mempromosikan modularitas dan reuse.

Manfaat dari Multi-Stage Build

Mengurangi Ukuran Image

Salah satu manfaat utama dari multi-stage build adalah kemampuan untuk meminimalkan ukuran akhir image Docker hanya dengan menyertakan file dan dependensi yang diperlukan untuk menjalankan aplikasi. Stage pembangunan yang intermediate dapat mengandung alat pembangunan, kompiler, dan dependensi lain yang diperlukan selama proses pembangunan tetapi tidak diperlukan dalam image akhir. Dengan menyalin hanya artefak yang relevan dari stage intermediate ke stage akhir, pengembang dapat menciptakan image yang ramping dan efisien yang lebih cepat didistribusikan dan mengkonsumsi resource yang lebih sedikit.

Meningkatkan Keamanan

Multi-stage build dapat membantu meningkatkan keamanan aplikasi yang dikemas dalam container dengan meminimalkan jumlah komponen dalam image Docker akhir. Mengurangi bidang serangan untuk potensi kerentanan keamanan sangat penting untuk menjaga integritas dan keselamatan aplikasi. Dengan menciptakan image yang terfokus dengan komponen yang lebih sedikit, pengembang dapat lebih mudah mengelola dan memelihara keamanan, serta memastikan kepatuhan dengan kebijakan organisasi dan standar industri.

Selain itu, multi-stage build memungkinkan pengembang menggunakan lingkungan yang terpisah untuk membangun dan menjalankan aplikasi, yang dapat lebih meningkatkan keamanan. Misalnya, sebuah stage pembangunan dapat menggunakan image dengan berbagai alat pengembangan dan pustaka, sementara stage akhir mungkin menggunakan base image yang minimal danhanya termasuk lingkungan runtime.

Menyederhanakan Proses Pembuatan

Dengan memecah proses pembuatan ke dalam beberapa stage, multi-stage build menyederhanakan proses pembuatan yang kompleks, membuatnya lebih mudah dibaca dan dipelihara. Setiap stage dapat fokus pada tugas tertentu, seperti mengkompilasi kode sumber, menjalankan pengujian, atau menghasilkan aset, membuatnya lebih mudah untuk memahami seluruh proses dan menyelesaikan masalah ketika terjadi.

Selain itu, multi-stage build mempromosikan modularitas dan reuse dengan memungkinkan pengembang menggunakan kembali stage pembuatan tertentu di seluruh proyek yang berbeda. Misalnya, jika beberapa proyek menggunakan toolchain atau lingkungan pembangunan yang sama, stage intermediate yang umum dapat dibuat dan dibagi di antara mereka, mengurangi duplikasi kode dan upaya pemeliharaan.

Mengimplementasikan Multi-Stage Build

Untuk mengimplementasikan multi-stage build, ikuti langkah-langkah berikut:

  1. Tentukan base image untuk setiap stage
    Gunakan beberapa pernyataan FROM di Dockerfile untuk menentukan base image untuk setiap stage. Beri setiap stage alias unik menggunakan kata kunci AS, yang akan digunakan untuk merujuk ke stage tersebut nanti.
Dockerfile
# Build stage
FROM node:14 AS build
  1. Tentukan direktori kerja
    Atur direktori kerja untuk setiap stage menggunakan instruksi WORKDIR.
Dockerfile
WORKDIR /app
  1. Salin file yang diperlukan dan instal dependensi
    Salin file yang diperlukan dan instal dependensi untuk setiap stage menggunakan instruksi COPY dan RUN.
Dockerfile
# Copy package files and install dependencies
COPY package*.json ./
RUN npm install
  1. Kompilasi atau membangun aplikasi
    Lakukan kompilasi atau langkah pembangunan yang diperlukan khusus untuk aplikasi.
Dockerfile
# Copy source files and build the application
COPY . .
RUN npm run build
  1. Tentukan stage akhir
    Tentukan base image stage akhir dan atur direktori kerja.
Dockerfile
# Final stage
FROM node:14-alpine AS final
WORKDIR /app
  1. Salin artefak dari stage sebelumnya
    Gunakan instruksi COPY dengan opsi --from untuk menyalin artefak atau file dari stage sebelumnya ke stage akhir.
Dockerfile
# Copy build artifacts from build stage
COPY --from=build /app/dist /app/dist
  1. Konfigurasi lingkungan runtime
    Atur variabel lingkungan, port yang diexpose, atau entry point yang diperlukan untuk aplikasi.
Dockerfile
# Set environment variables
ENV NODE_ENV=production

# Expose the application port
EXPOSE 3000

# Define the entry point
CMD ["npm", "start"]

Membang Stage Pembangunan dan Produksi Menggunakan Opsi --target

Pada bab ini, saya akan membahas cara membangun stage pembangunan dan produksi dari satu Dockerfile menggunakan opsi --target. Ini memungkinkan pengembang untuk membangun image Docker yang disesuaikan dengan lingkungan tertentu tanpa mempertahankan Dockerfile terpisah.

Membangun Stage Pembangunan

Untuk membangun stage pembangunan dari Dockerfile multi-stage, gunakan opsi --target dengan perintah docker build dan tentukan alias stage pengembangan.

Misalnya, dengan Dockerfile berikut:

Dockerfile
# Develop stage
FROM node:14 AS develop
WORKDIR /app
COPY package*.json ./
RUN npm install
ENV NODE_ENV=development
CMD ["npm", "run", "dev"]

# Production stage
FROM node:14-alpine AS production
WORKDIR /app
COPY --from=develop /app/node_modules /app/node_modules
COPY . .
RUN npm run build
ENV NODE_ENV=production
CMD ["npm", "start"]

Untuk membangun stage pembangunan, jalankan:

bash
$ docker build -t my-app:develop --target develop .

Ini akan membuat image Docker dengan tag my-app:develop yang berisi lingkungan pengembangan.

Membangun Stage Produksi

Untuk membangun stage produksi, cukup abaikan opsi --target atau tentukan alias stage produksi.

Misalnya, dengan Dockerfile yang sama seperti di atas:

Untuk membangun stage produksi, jalankan:

bash
$ docker build -t my-app:production --target production .

Ini akan membuat image Docker dengan tag my-app:production yang dioptimalkan untuk dideploy di lingkungan produksi.

Contoh Nyata

Pada bab ini, saya akan mengeksplorasi contoh nyata multi-stage build untuk bahasa dan framework pemrograman yang berbeda.

Membangun Aplikasi Node.js

Pada contoh ini, kita akan membuat multi-stage build untuk aplikasi Node.js menggunakan base image node:14 untuk stage pembangunan dan gambar node:14-alpine untuk stage akhir.

Dockerfile
# Build stage
FROM node:14 AS build
WORKDIR /app

# Copy package files and install dependencies
COPY package*.json ./
RUN npm install

# Copy source files and build the application
COPY . .
RUN npm run build

# Final stage
FROM node:14-alpine AS final
WORKDIR /app

# Copy build artifacts from build stage
COPY --from=build /app/dist /app/dist

# Set environment variables
ENV NODE_ENV=production

# Expose the application port
EXPOSE 3000

# Define the entry point
CMD ["npm", "start"]

Mengompilasi Binary Golang

Pada contoh ini, kita akan membuat multi-stage build untuk aplikasi Golang, menggunakan gambar golang:1.17 untuk stage pembangunan dan gambar scratch untuk stage akhir.

# Build stage
FROM golang:1.17 AS build
WORKDIR /src

# Copy source files and compile the application
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app

# Final stage
FROM scratch AS final
WORKDIR /app

# Copy the compiled binary from the build stage
COPY --from=build /src/app .

# Expose the application port
EXPOSE 8080

# Define the entry point
CMD ["./app"]

Membuat Aplikasi Web Python

Pada contoh ini, kita akan membuat multi-stage build untuk aplikasi web Python menggunakan Flask, dengan base image python:3.9 untuk stage pembangunan dan gambar python:3.9-slim untuk stage akhir.

# Build stage
FROM python:3.9 AS build
WORKDIR /app

# Copy requirements file and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy source files
COPY . .

# Final stage
FROM python:3.9-slim AS final
WORKDIR /app

# Copy installed dependencies and source files from the build stage
COPY --from=build /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages
COPY --from=build /app .

# Expose the application port
EXPOSE 5000

# Define the entry point
CMD ["python", "app.py"]

Referensi

https://docs.docker.com/build/building/multi-stage/
https://earthly.dev/blog/docker-multistage/
https://dev.to/pavanbelagatti/what-are-multi-stage-docker-builds-1mi9

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!