BuildKit: Mesin Build Default Docker
BuildKit menggantikan mesin build lama sepenuhnya. Ia membangun graf dependensi dari Dockerfile Anda, menjalankan tahapan yang tidak saling bergantung secara paralel, dan hanya mengirim berkas yang benar-benar dibutuhkan ke daemon.
Tambahkan baris ini di paling atas Dockerfile untuk membuka semua fitur BuildKit terbaru, terlepas dari versi Docker yang terpasang:
# syntax=docker/dockerfile:1
1. Cache Mount โ Berhenti Mengunduh Dependensi Berulang Kali
Masalah klasik: setiap kali package.json berubah sedikit saja, seluruh npm install dijalankan dari nol dan mengunduh ulang semuanya.
# syntax=docker/dockerfile:1
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
# Cache npm BERTAHAN antar build, bahkan ketika layer ini di-rebuild
RUN --mount=type=cache,target=/root/.npm \
npm ci
COPY . .
RUN npm run build
Pola yang sama untuk ekosistem lain:
# Go
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /app/server ./cmd/server
# Python (pip)
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# APT โ perlu menonaktifkan pembersihan otomatis Docker
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean && \
apt-get update && apt-get install -y --no-install-recommends ffmpeg
Layer cache menjadi tidak sah begitu ada berkas yang berubah. Cache mount adalah direktori terpisah yang bertahan di luar layer โ jadi meski layer harus dibangun ulang, isi cache-nya masih ada. Untuk proyek besar, ini sering memangkas waktu build dari beberapa menit menjadi beberapa detik.
2. Secret Mount โ Rahasia yang Tidak Bocor ke Image
ARG NPM_TOKEN
RUN npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN
# Token ini TERSIMPAN PERMANEN di riwayat layer image.
# Siapa pun yang menarik image Anda bisa membacanya dengan
# "docker history" atau sekadar mengekstrak layer-nya.
# Cara yang benar โ rahasia hanya ada selama perintah berjalan
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci
docker build --secret id=npm_token,env=NPM_TOKEN -t app:1.0 .
docker build --secret id=npm_token,src=./token.txt -t app:1.0 .
# Untuk git clone repositori privat, pakai SSH agent forwarding
RUN --mount=type=ssh git clone [email protected]:org/privat.git
# docker build --ssh default -t app:1.0 .
3. Image Multi-Arsitektur
Laptop Apple Silicon memakai arm64, sementara sebagian besar server memakai amd64. Image yang dibangun di laptop tidak akan berjalan di server bila arsitekturnya tidak cocok.
# Buat builder yang mendukung multi-platform
docker buildx create --name multi --driver docker-container --use
docker buildx inspect --bootstrap
# Bangun & dorong untuk dua arsitektur sekaligus
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.contoh.com/app:2.4.0 \
--push .
Membangun arm64 di mesin amd64 memakai emulasi QEMU yang bisa 10โ20 kali lebih lambat. Untuk pipeline produksi, jauh lebih baik memakai runner asli untuk tiap arsitektur lalu menggabungkan hasilnya menjadi satu manifest, ketimbang mengemulasi semuanya di satu mesin.
4. Cache Terdistribusi untuk CI
Runner CI selalu dimulai dari nol, sehingga cache lokal tidak pernah terpakai. Solusinya adalah menyimpan cache di registry.
docker buildx build \
--cache-from type=registry,ref=registry.contoh.com/app:buildcache \
--cache-to type=registry,ref=registry.contoh.com/app:buildcache,mode=max \
-t registry.contoh.com/app:2.4.0 --push .
mode=max menyimpan cache untuk semua tahap termasuk tahap builder, bukan hanya layer akhir. Ukurannya lebih besar, tetapi tingkat cache hit-nya jauh lebih tinggi.
5. Heredoc โ Dockerfile yang Lebih Terbaca
# syntax=docker/dockerfile:1
RUN <<EOF
set -eux
apt-get update
apt-get install -y --no-install-recommends curl ca-certificates
rm -rf /var/lib/apt/lists/*
EOF
COPY <<EOF /app/config.json
{
"lingkungan": "produksi",
"log_level": "info"
}
EOF
6. Memeriksa Hasil Build
# Melihat riwayat build beserta waktu tiap langkah
docker buildx history
# Membongkar isi image tanpa menjalankannya
docker buildx imagetools inspect registry.contoh.com/app:2.4.0
# Melihat berapa besar tiap layer
docker history app:2.4.0 --no-trunc
# Membandingkan ukuran
docker images app --format "{{.Tag}}\t{{.Size}}"