Docker image yang besar bukan cuma soal storage — ini mempengaruhi kecepatan build, waktu deploy, dan biaya. Image 1GB butuh waktu lebih lama untuk di-push, di-pull, dan di-deploy dibanding image 100MB.
Berikut tips praktis untuk membuat Docker image lebih kecil dan build lebih cepat.
1. Gunakan Multi-Stage Build
Multi-stage build memisahkan tahap build dari tahap run. Hasilnya? Image production yang jauh lebih kecil.
# ❌ Tanpa multi-stage — image besar
FROM node:20
WORKDIR /app
COPY . .
RUN npm ci && npm run build
CMD ["node", "dist/index.js"]
# Image: ~1.2GB (termasuk devDependencies, source code, build tools)
# ✅ Dengan multi-stage — image kecil
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
# Image: ~200MB (hanya runtime + compiled output)
Selisihnya dramatic: 1.2GB vs 200MB.
2. Pilih Base Image yang Tepat
Base image menentukan ukuran akhir Docker image kamu.
| Base Image | Ukuran | Use Case |
|---|---|---|
node:20 |
~1.1GB | Development, butuh banyak tools |
node:20-slim |
~200MB | Production, butuh beberapa system packages |
node:20-alpine |
~130MB | Production, minimal dependencies |
python:3.12 |
~1GB | Development |
python:3.12-slim |
~150MB | Production |
python:3.12-alpine |
~50MB | Production minimal |
Gunakan Alpine untuk production kalau bisa. Kalau butuh system packages yang tidak ada di Alpine, pakai Slim.
3. Urutkan Layer dengan Benar
Docker menggunakan layer caching. Setiap layer yang berubah akan membuat layer setelahnya rebuild.
# ❌ SALAH — source code di-copy duluan
COPY . .
RUN npm ci # Selalu rebuild (cache miss)
# ✅ BENAR — dependency files di-copy dulu
COPY package.json package-lock.json ./
RUN npm ci # Di-cache selama package.json tidak berubah
COPY . . # Layer ini rebuild, tapi npm ci sudah cached
Prinsipnya: taruh instruksi yang paling jarang berubah di atas, yang sering berubah di bawah.
4. Gunakan .dockerignore
Sama seperti .gitignore, .dockerignore mencegah file tidak perlu masuk ke dalam build context:
node_modules
.git
.env
*.log
coverage
dist
build
.github
.vscode
docker-compose.yml
Dockerfile
README.md
Tanpa .dockerignore: Docker mengirim semua file ke daemon, termasuk node_modules (yang bisa ratusan MB). Build lebih lambat, image lebih besar.
5. Kombinasikan RUN Commands
Setiap RUN menciptakan layer baru. Kurangi jumlah layer dengan mengkombinasikan commands:
# ❌ Banyak layer
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN apt-get clean
# ✅ Satu layer
RUN apt-get update && \
apt-get install -y --no-install-recommends curl git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
6. Hapus Cache setelah Install
Package manager menyimpan cache yang tidak perlu di image akhir:
# Node.js
RUN npm ci --production && npm cache clean --force
# Python
RUN pip install --no-cache-dir -r requirements.txt
# PHP
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
# Alpine
RUN apk add --no-cache package-name
# Debian/Ubuntu
RUN apt-get update && apt-get install -y package && \
apt-get clean && rm -rf /var/lib/apt/lists/*
7. Copy yang Dibutuhkan Saja
Jangan copy seluruh repository. Copy hanya file yang dibutuhkan:
# ❌ Copy semua
COPY . .
# ✅ Copy hanya yang dibutuhkan
COPY package.json package-lock.json ./
COPY src/ ./src/
COPY tsconfig.json ./
8. Gunakan .dockerignore untuk Secrets
Pastikan file sensitif tidak masuk ke image:
.env
.env.local
.env.production
*.pem
*.key
credentials.json
service-account.json
Ini penting: secrets yang masuk ke Docker image bisa di-extract oleh siapa saja yang punya akses ke image.
9. Pin Versi Base Image
Jangan gunakan latest — ini tidak reproducible dan bisa berubah sewaktu-waktu:
# ❌ Tidak reproducible
FROM node:latest
# ✅ Specific version
FROM node:20.11.1-alpine
# ✅ Atau minimal major version
FROM node:20-alpine
10. Review Image dengan dive
dive adalah tool untuk menganalisis Docker image dan menemukan waste:
# Install dive
brew install dive
# Analisis image
dive my-image:latest
Dive menunjukkan:
- Size setiap layer
- File apa yang menambah ukuran
- Waste yang bisa dihapus
Contoh: Node.js App yang Dioptimasi
Sebelum Optimasi
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]
Ukuran: ~1.5GB
Sesudah Optimasi
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Run
FROM node:20-alpine
WORKDIR /app
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -s /bin/sh -D appuser
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
Ukuran: ~180MB — 88% lebih kecil.
Yang berubah:
- Multi-stage build → build tools tidak masuk image akhir
- Alpine base → base image lebih kecil
- Layer ordering → dependency di-cache
- Non-root user → lebih aman
Contoh: Python App yang Dioptimasi
Sebelum
FROM python:3.12
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "main.py"]
Ukuran: ~1.2GB
Sesudah
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
CMD ["python", "main.py"]
Ukuran: ~200MB
Ringkasan Checklist
- Gunakan multi-stage build
- Pilih base image yang tepat (Alpine > Slim > Full)
- Urutkan layer dari yang paling jarang berubah
- Buat
.dockerignoreyang lengkap - Kombinasikan RUN commands
- Hapus cache setelah install dependencies
- Copy hanya file yang dibutuhkan
- Pin versi base image
- Jangan masukkan secrets ke image
- Review dengan
dive
Hubungannya dengan Helipod
Docker image yang lebih kecil = build lebih cepat di Helipod. Dengan multi-stage build, kamu bisa mengurangi waktu deployment dari ~5 menit menjadi ~1-2 menit.
Helipod juga auto-detect Dockerfile kamu dan menggunakan optimasi yang sudah kamu buat. Kalau kamu tidak pakai Dockerfile sendiri, Helipack akan generate Dockerfile yang sudah dioptimasi secara otomatis.
Baca lebih lanjut: Dockerfile di Helipod
Kesimpulan
Optimasi Docker image bukan hanya soal ukuran — ini tentang kecepatan build, waktu deploy, dan biaya. Dengan tips di atas, kamu bisa membuat image yang lebih kecil, build yang lebih cepat, dan deployment yang lebih efisien.
Mulai deploy di helipod.io — tidak perlu kartu kredit.
Punya pertanyaan? Hubungi kami di support@helipod.id atau bergabung ke komunitas di hangar.helipod.io.