Hana — VyuApp Support
Online
20/20 pesan tersisa
🌸 Selamat datang di VyuApp! Saya Hana, ada yang bisa saya bantu hari ini?
Semua artikel

Engineering

Optimasi Build Docker untuk Next.js Produksi: Panduan Lengkap 2026

Panduan lengkap optimasi build Docker untuk Next.js produksi 2026. Multi-stage build, standalone output, caching, dan strategi pengurangan ukuran image hingga 83%.

28 Juni 2026 13 min read#docker#nextjs#devops#optimasi
Optimasi Build Docker untuk Next.js Produksi: Panduan Lengkap 2026

Optimasi build Docker untuk Next.js produksi adalah langkah krusial yang membedakan deployment yang lambat dan mahal dari sistem yang efisien. Banyak developer menghadapi masalah: image yang terlalu besar, build yang berlarut, dan biaya infrastruktur yang membengkak. Panduan lengkap 2026 ini membahas secara mendalam cara mengoptimalkan Docker build untuk Next.js agar siap produksi dengan performa terbaik. Bagi Anda yang sedang membangun produk digital, penting untuk diingat bahwa CI/CD pipeline yang efisien menjadi fondasi deployment yang andal dan cepat.

Kami akan membahas berbagai teknik yang terbukti efektif, mulai dari multi-stage builds, standalone output mode, strategi caching, hingga best practices yang bisa langsung Anda terapkan. Berdasarkan riset terbaru, optimasi yang tepat bisa mengurangi ukuran Docker image hingga 80% dan mempercepat build time secara signifikan.

Docker containers di production server

Mengapa Optimasi Build Docker untuk Next.js Produksi Penting?

Docker menjadi standar industri untuk deployment aplikasi modern, termasuk Next.js. Namun, tanpa optimasi yang tepat, Docker image untuk aplikasi Next.js bisa mencapai ukuran yang sangat besar — kadang lebih dari 1GB. Ukuran image yang besar berdampak langsung pada kecepatan deployment, biaya penyimpanan di container registry, dan waktu pull image saat scaling.

Menurut data dari berbagai sumber, termasuk studi kasus yang dipublikasikan di LinkedIn, optimasi Docker image Next.js bisa mengurangi ukuran dari 3.39GB menjadi hanya 619MB — pengurangan sebesar 82%. Pengurangan ini bukan sekadar angka, tapi berdampak nyata pada performa infrastruktur Anda. Image yang lebih kecil berarti deploy yang lebih cepat, bandwidth yang lebih hemat, dan waktu recovery yang lebih singkat saat terjadi incident.

Selain ukuran image, build time juga menjadi faktor kritis. Dalam siklus CI/CD yang aktif, setiap commit akan memicu build baru. Jika build memakan waktu 15-20 menit, itu berarti developer harus menunggu lama sebelum bisa melihat hasil perubahan mereka. Dengan optimasi yang tepat, build time bisa dikurangi dari belasan menit menjadi hanya beberapa menit saja.

Developer sedang mengoptimalkan konfigurasi Docker

Memahami Arsitektur Build Next.js dalam Docker

Sebelum masuk ke teknik optimasi, penting untuk memahami bagaimana Next.js bekerja di dalam Docker. Next.js memiliki beberapa mode output: default (node server), standalone, dan export. Setiap mode menghasilkan artefak build yang berbeda, dan ini mempengaruhi ukuran serta kompleksitas Docker image yang dihasilkan.

Pada mode default, Next.js membutuhkan seluruh direktori node_modules untuk menjalankan aplikasi di production. Ini berarti image harus menyertakan semua dependency, termasuk devDependencies yang sebenarnya tidak diperlukan di production. Akibatnya, ukuran image membengkak karena ribuan file dependency yang tidak semua diperlukan.

Mode standalone, yang diperkenalkan oleh Vercel, mengubah game ini secara drastis. Dengan mengaktifkan output: 'standalone' di next.config.js, Next.js akan menghasilkan build yang mandiri — hanya berisi dependency yang benar-benar digunakan oleh aplikasi Anda. Berdasarkan laporan di Reddit, ukuran build bisa turun dari ratusan MB menjadi hanya 37MB saat menggunakan standalone mode. Perbedaan ini sangat signifikan dan menjadi alasan utama mengapa standalone mode menjadi rekomendasi untuk deployment Docker.

Multi-Stage Build: Fondasi Optimasi Docker untuk Next.js

Multi-stage build adalah fitur Docker yang memungkinkan Anda menggunakan beberapa FROM dalam satu Dockerfile. Setiap FROM membuat stage baru, dan Anda bisa menyalin artefak dari satu stage ke stage lainnya. Konsep ini sangat powerful untuk aplikasi Next.js karena memisahkan proses build (yang membutuhkan banyak tools dan dependency) dari runtime production (yang hanya membutuhkan file yang sudah di-build).

Struktur multi-stage build untuk Next.js umumnya terdiri dari tiga stage. Stage pertama adalah dependency installer — stage ini hanya menyalin package.json dan package-lock.json, lalu menjalankan npm ci. Tujuannya adalah membuat layer caching yang efektif: selama dependency tidak berubah, Docker akan menggunakan cache dan tidak perlu mengunduh ulang semua package.

Stage kedua adalah builder — stage ini menyalin source code dan menjalankan npm run build. Stage ini membutuhkan devDependencies seperti TypeScript, PostCSS, dan Tailwind CSS yang diperlukan saat build. Stage ketiga adalah production runtime — stage ini hanya menyalin hasil build dari stage builder, menjalankan npm ci --production untuk dependency production saja, dan mengeksekusi aplikasi. Hasilnya adalah image production yang jauh lebih kecil karena tidak menyertakan devDependencies, source code, atau artefak build yang tidak diperlukan.

FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

Contoh di atas menunjukkan Dockerfile multi-stage yang mengikuti best practices dari dokumentasi resmi Next.js. Perhatikan bagaimana stage runner hanya berisi file yang benar-benar diperlukan untuk menjalankan aplikasi — tidak ada source code, tidak ada node_modules lengkap, hanya artefak standalone dan static files.

Terminal menampilkan proses build Docker

// Advertisement

Standalone Output Mode: Kunci Ukuran Image Minimal

Standalone output mode adalah fitur yang wajib digunakan saat mendeploy Next.js ke Docker. Fitur ini tersedia sejak Next.js 12 dan semakin matang di versi-versi terbaru. Cara mengaktifkannya sangat sederhana — cukup tambahkan output: 'standalone' di file next.config.js.

Saat standalone mode diaktifkan, Next.js akan menganalisis penggunaan dependency di seluruh aplikasi Anda dan hanya menyertakan modul yang benar-benar digunakan. Hasilnya ada di direktori .next/standalone yang berisi server.js (entry point) beserta hanya dependency yang diperlukan. Ini berbeda drastis dengan mode default yang membutuhkan seluruh node_modules.

Data dari berbagai sumber mengonfirmasi efektivitas standalone mode. Seorang developer di Reddit melaporkan bahwa ukuran build turun dari ratusan MB menjadi hanya 37MB setelah mengaktifkan standalone. Sumber lain dari JavaScript Plain English melaporkan pengurangan ukuran hingga 80% dengan Next.js 15 standalone mode. Angka-angka ini menunjukkan bahwa standalone mode bukan sekadar optimasi minor, tapi perubahan fundamental dalam cara Next.js menghasilkan artefak production.

Penting untuk dicatat bahwa standalone mode memerlukan penyesuaian pada Dockerfile. Anda perlu menyalin direktori .next/standalone dan .next/static ke stage production, serta memastikan public folder juga tersedia. Jika menggunakan custom server, pastikan entry point sudah benar. Dokumentasi resmi Next.js di nextjs.org/docs/app/getting-started/deploying memberikan panduan lengkap untuk konfigurasi ini.

Strategi Caching untuk Build yang Lebih Cepat

Caching adalah senjata paling ampuh untuk mempercepat Docker build. Tanpa caching yang baik, setiap build akan mengulang proses dari awal — mengunduh semua dependency, mengcompile semua source code, dan menghasilkan semua artefak. Dengan caching yang tepat, hanya bagian yang berubah yang perlu diproses ulang.

Prinsip dasar caching Docker adalah: Docker menyimpan hasil setiap perintah dalam layer. Jika perintah dan inputnya tidak berubah, Docker akan menggunakan layer yang sudah ada di cache. Kuncinya adalah menempatkan perintah yang jarang berubah di bagian atas Dockerfile, dan perintah yang sering berubah di bagian bawah. Untuk aplikasi Next.js, package.json dan package-lock.json jarang berubah dibandingkan source code, sehingga npm ci seharusnya menjadi perintah pertama yang di-cache.

Selain layer caching Docker, Next.js juga memiliki sistem caching internal di direktori .next/cache. Direktori ini menyimpan hasil build sebelumnya dan bisa digunakan untuk mempercepat build berikutnya. Di lingkungan CI/CD, pastikan .next/cache di-persist antar builds. Docker BuildKit (yang sudah default di Docker versi terbaru) mendukung cache mounting yang memungkinkan Anda mempertahankan cache ini di antara builds tanpa perlu menyalinnya ke dalam image.

# Menggunakan BuildKit cache mount untuk .next/cache
RUN --mount=type=cache,target=/app/.next/cache \
    npm run build

Dengan menggunakan --mount=type=cache, cache Next.js akan dipertahankan bahkan setelah container baru dibuat. Teknik ini bisa mengurangi build time dari belasan menit menjadi hanya 2-3 menit untuk build incremental, terutama pada proyek besar dengan banyak halaman dan komponen.

Memilih Base Image yang Tepat

Pilihan base image memiliki dampak besar pada ukuran akhir Docker image. Node.js tersedia dalam beberapa varian: node:20 (Debian-based, ~900MB), node:20-slim (Debian minimal, ~200MB), dan node:20-alpine (Alpine Linux, ~50MB). Untuk produksi, node:20-alpine adalah pilihan terbaik karena ukurannya yang sangat kecil.

Alpine Linux adalah distribusi Linux yang dirancang untuk keamanan dan ukuran minimal. Meskipun ukurannya kecil, Alpine menyediakan semua tools yang dibutuhkan untuk menjalankan aplikasi Node.js. Namun, ada beberapa hal yang perlu diperhatikan saat menggunakan Alpine: beberapa native modules mungkin perlu di-build ulang karena Alpine menggunakan musl libc alih-alih glibc. Pastikan untuk menguji aplikasi Anda di Alpine sebelum deploy ke produksi.

Penggunaan base image yang tepat bisa mengurangi ukuran image sekitar 700-850MB hanya dari perubahan ini saja. Gabungkan dengan multi-stage build dan standalone output, total pengurangan ukuran bisa mencapai 80-90% dibandingkan image tanpa optimasi. Dalam konteks di mana setiap MB berarti biaya penyimpanan dan bandwidth, pengurangan ini sangat berharga.

Arsitektur microservices dengan container

Optimasi Production Runtime: Lebih dari Sekadar Build

Build yang optimal baru setengah dari cerita. Production runtime juga perlu dioptimasi untuk performa terbaik. Beberapa aspek penting yang sering terlewatkan meliputi user configuration, health check, dan resource management.

Pertama, selalu gunakan non-root user di container production. Membuat user khusus seperti nextjs dengan group nodejs adalah best practice yang direkomendasikan oleh dokumentasi resmi Next.js dan Docker. Ini bukan hanya soal keamanan — beberapa container runtime seperti Kubernetes dan Docker Swarm juga membutuhkan non-root user untuk security policies.

Kedua, implementasikan health check endpoint di aplikasi Anda. Next.js sudah menyediakan built-in health check melalui route /_next/data, tapi Anda bisa membuat custom endpoint yang lebih informatif. Health check memungkinkan orchestrator untuk mengetahui kapan container siap menerima traffic, kapan perlu di-restart, dan kapan perlu di-scale. Tanpa health check yang proper, container bisa saja menerima traffic sebelum aplikasi benar-benar siap.

Ketiga, pertimbangkan untuk menggunakan environment variables di runtime alih-alih build time, sebisa mungkin. Next.js 15 memungkinkan lebih banyak environment variable diakses di runtime berkat Server Components dan Server Actions. Ini berarti Anda bisa build sekali dan deploy ke berbagai environment (development, staging, production) tanpa perlu rebuild. Pendekatan ini sangat efisien dalam CI/CD pipeline di mana setiap environment bisa menggunakan image yang sama dengan konfigurasi yang berbeda.

// Advertisement

Studi Kasus: Optimasi dari 3.39GB ke 619MB

Sebuah studi kasus menarik dipublikasikan di LinkedIn pada Juni 2026 oleh seorang DevOps engineer. Tim mereka berhasil mengoptimalkan Docker image Next.js dari ukuran awal 3.39GB menjadi hanya 619MB — pengurangan sebesar 82%. Berikut adalah langkah-langkah yang mereka ambil.

Langkah pertama adalah mengaktifkan standalone output mode. Sebelum optimasi, mereka menggunakan mode default yang membutuhkan seluruh node_modules. Setelah mengaktifkan standalone, ukuran build artifacts turun drastis. Langkah kedua adalah menerapkan multi-stage build yang proper — memisahkan dependency installation, build, dan production runtime ke stage-stage terpisah. Ini memastikan devDependencies tidak masuk ke production image.

Langkah ketiga adalah beralih ke base image Alpine. Dari node:20 (Debian-based, sekitar 900MB) ke node:20-alpine (sekitar 50MB). Penghematan ini saja sudah luar biasa signifikan. Langkah keempat adalah membersihkan file-file yang tidak diperlukan — .git, .env, README, test files, dan file-file lain yang ikut ter-copy ke image. Mereka menggunakan .dockerignore yang ketat untuk memastikan hanya file yang benar-benar diperlukan yang masuk ke build context.

Hasil akhirnya adalah image production yang hanya 619MB — sekitar 82% lebih kecil dari image awal. Dampaknya terasa langsung: deployment time turun dari 8 menit menjadi kurang dari 2 menit, biaya penyimpanan di container registry berkurang signifikan, dan rolling updates menjadi lebih cepat dan reliable. Studi kasus ini menunjukkan bahwa optimasi Docker bukan sekadar teori, tapi praktik yang memberikan dampak nyata pada operasional tim engineering. Dalam konteks bisnis digital, memahami intelijen pasar dan mengoptimalkan infrastruktur teknis harus berjalan beriringan untuk mencapai hasil yang maksimal.

Kesalahan Umum yang Harus Dihindari

Ada beberapa kesalahan umum yang sering dilakukan developer saat mengoptimalkan Docker build untuk Next.js. Memahami kesalahan-kesalahan ini bisa membantu Anda menghindari jebakan yang sama dan mempercepat proses optimasi.

Pertama, menggunakan COPY . . di awal Dockerfile. Ini adalah kesalahan paling umum karena akan invalidate seluruh cache setiap kali ada perubahan file, termasuk file yang tidak berhubungan dengan dependency. Solusinya adalah menyalin package files terlebih dahulu, menjalankan install, baru menyalin source code. Dengan urutan ini, Docker hanya perlu mengulang install saat package files berubah.

Kedua, tidak menggunakan .dockerignore. Tanpa .dockerignore, Docker akan mengirim seluruh direktori project (termasuk node_modules, .git, test files, dan dokumentasi) ke Docker daemon sebagai build context. Ini memperlambat proses build karena Docker perlu memproses file-file yang tidak diperlukan. Buat .dockerignore yang mencakup: node_modules, .next, .git, .env*, README.md, docker-compose*.yml, dan Dockerfile itu sendiri.

Ketiga, menjalankan npm install alih-alih npm ci di Dockerfile. npm install mencoba menyelesaikan dependency tree dan bisa menghasilkan package-lock.json yang berbeda dari local development. npm ci lebih cocok untuk CI/CD karena akan menghapus node_modules yang ada dan menginstal persis sesuai package-lock.json. Ini memastikan reproducibility — build yang sama akan selalu menghasilkan output yang sama.

Keempat, mengabaikan optimasi node_modules production. Bahkan dengan npm ci --production, node_modules masih bisa berisi file-file yang tidak diperlukan seperti README, CHANGELOG, TypeScript definitions, dan test files dari dependency. Tools seperti depcheck bisa membantu mengidentifikasi dependency yang tidak digunakan, dan npm prune --production bisa membersihkan devDependencies yang tertinggal.

Checklist Optimasi: Mulai dari Mana?

Jika Anda baru mulai mengoptimalkan Docker build untuk Next.js, berikut adalah checklist yang bisa Anda ikuti secara berurutan. Mulai dari optimasi yang memberikan dampak terbesar terlebih dahulu.

Yang pertama dan paling berdampak: aktifkan standalone output mode. Tambahkan output: 'standalone' di next.config.js dan sesuaikan Dockerfile untuk menggunakan artefak standalone. Optimasi ini saja bisa mengurangi ukuran image hingga 80%. Yang kedua: implementasikan multi-stage build. Pisahkan dependency installation, build, dan production runtime ke stage-stage terpisah. Ini memastikan devDependencies dan source code tidak masuk ke production image.

Yang ketiga: gunakan base image Alpine. Beralih dari node:20 ke node:20-alpine menghemat ratusan MB. Yang keempat: buat .dockerignore yang ketat. Pastikan hanya file yang benar-benar diperlukan yang masuk ke build context. Yang kelima: optimalkan layer caching. Urutkan perintah di Dockerfile agar perintah yang jarang berubah ada di atas, dan manfaatkan BuildKit cache mounts untuk .next/cache.

Yang keenam: gunakan npm ci alih-alih npm install. Ini memastikan reproducibility dan menghindari masalah dependency resolution. Yang ketujuh: bersihkan file yang tidak diperlukan di production stage — README, LICENSE, test files, dan file-file lain yang tidak dibutuhkan untuk menjalankan aplikasi. Dengan mengikuti checklist ini secara berurutan, Anda bisa mencapai hasil yang signifikan dalam waktu singkat. Ingatlah bahwa estetika dan desain juga merupakan strategi — bahkan performa teknis yang optimal sekalipun perlu dikemas dalam produk yang menarik dan mudah digunakan oleh pengguna akhir.

Sumber dan Referensi

Artikel ini ditulis berdasarkan riset dari berbagai sumber terpercaya berikut:

Pertanyaan yang Sering Diajukan

Apa perbedaan standalone output mode dengan mode default Next.js di Docker?

Mode default Next.js membutuhkan seluruh direktori node_modules untuk menjalankan aplikasi di production, sehingga Docker image harus menyertakan semua dependency. Standalone output mode hanya menyertakan dependency yang benar-benar digunakan oleh aplikasi Anda, menghasilkan build yang jauh lebih kecil — kadang hanya 37MB dibandingkan ratusan MB. Standalone mode menghasilkan file .next/standalone/server.js yang bisa dijalankan secara mandiri tanpa perlu full node_modules.

Seberapa besar pengurangan ukuran image yang bisa dicapai dengan optimasi Docker untuk Next.js?

Berdasarkan data dari berbagai studi kasus, pengurangan ukuran bisa mencapai 70-82% dengan menerapkan optimasi secara lengkap. Studi kasus di LinkedIn menunjukkan pengurangan dari 3.39GB ke 619MB (82%), sementara sumber lain melaporkan pengurangan hingga 80% dengan Next.js 15 standalone mode. Faktor-faktor yang paling berdampak adalah standalone output mode (pengurangan terbesar), base image Alpine (menghemat ~850MB), dan multi-stage build (menghilangkan devDependencies).

Apakah saya perlu rebuild Docker image setiap kali ada perubahan kode?

Ya, setiap perubahan source code memang memerlukan rebuild image baru. Namun, dengan strategi caching yang tepat, rebuild hanya akan memproses bagian yang berubah. Layer caching Docker memastikan bahwa dependency installation (yang paling lambat) tidak perlu diulang selama package.json tidak berubah. Selain itu, .next/cache bisa di-cache menggunakan BuildKit cache mounts untuk mempercepat build incremental. Dalam praktiknya, build incremental setelah optimasi bisa selesai dalam 2-3 menit, jauh lebih cepat dari build pertama kali yang mungkin memakan 10-15 menit.

// Advertisement

V

VyuApp Studio

Bespoke web engineering — Garut, ID