NextJS #
Next.js adalah framework React yang opinionated dan production-ready, menggabungkan frontend, backend (API Routes), dan rendering strategy (CSR, SSR, SSG, ISR) dalam satu platform. Namun justru karena kelengkapan ini, setup local development sering menjadi sumber masalah:
- Perbedaan versi Node.js
- Konflik dependency native
- Environment variable tidak konsisten
- Perbedaan perilaku antara mesin developer
Docker hadir untuk menyelesaikan masalah tersebut dengan menyediakan environment local development yang konsisten dan dapat direproduksi. Artikel ini membahas secara mendetail dan rinci bagaimana menyusun Dockerfile dan Docker Compose untuk aplikasi Next.js dalam konteks local development, lengkap dengan reasoning teknis, best practice, dan anti-pattern yang sering terjadi.
Prinsip Docker Next.js #
Sebelum masuk ke teknis, penting memahami prinsip dasarnya:
- Fokus pada developer experience, bukan image sekecil mungkin
- Mendukung hot reload / Fast Refresh
- Source code di-edit di host, dijalankan di container
- Tidak mencampur concern production ke local dev
Docker untuk local dev adalah alat kolaborasi, bukan alat optimasi runtime.
Struktur Project Next.js #
nextjs-app/
├── app/ # atau pages/
├── public/
├── package.json
├── package-lock.json
├── next.config.js
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
└── .env.local
Struktur ini menjaga Docker sebagai bagian eksplisit dari workflow, bukan tempelan belakangan.
.dockerignore: Fondasi Wajib #
node_modules
.next
.git
.gitignore
Dockerfile
.dockerignore
npm-debug.log
Tanpa .dockerignore, build akan:
- Lambat
- Boros disk
- Sulit di-debug
Ini kesalahan kecil yang dampaknya besar.
Dockerfile Next.js #
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
Penjelasan per Bagian #
1. Base Image #
node:20-alpine dipilih karena:
- Node.js LTS modern
- Image ringan
- Sudah lebih dari cukup untuk local dev
Untuk development, Alpine tidak masalah, meskipun di production kadang perlu Debian-based image.
2. WORKDIR #
Menetapkan /app sebagai root aplikasi di dalam container.
Ini menyederhanakan path dan perintah selanjutnya.
3. Copy package.json #
Ini adalah optimasi Docker layer caching:
- Dependency tidak di-install ulang setiap kali kode berubah
- Iterasi development jauh lebih cepat
4. npm install (bukan npm ci) #
Untuk local development:
- Lebih fleksibel
- Lebih toleran terhadap perubahan dependency
npm ci lebih cocok untuk CI/CD atau image production.
5. COPY source code #
Source code dicopy setelah dependency agar cache tetap optimal.
6. CMD dev mode #
Menjalankan Next.js dev server dengan Fast Refresh.
Script npm #
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
Script dev akan digunakan oleh Docker Compose.
Docker Compose #
version: '3.9'
services:
web:
build:
context: .
dockerfile: Dockerfile
container_name: nextjs-dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
NODE_ENV: development
command: npm run dev
depends_on:
- api
api:
image: postgres:16-alpine
container_name: nextjs-db
environment:
POSTGRES_USER: nextjs
POSTGRES_PASSWORD: nextjs
POSTGRES_DB: nextjs_dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Penjelasan Docker Compose #
Service web
#
build: membangun image dari Dockerfile lokalports: expose Next.js dev server ke hostvolumes:.:/app→ sinkronisasi source code/app/node_modules→ mencegah konflik dependency
environment: memastikan Next.js berjalan di mode developmentcommand: override CMD untuk dev mode
Service Database #
Next.js sering digunakan bersama:
- Prisma
- Drizzle
- API Routes
Database dimasukkan ke Compose untuk mensimulasikan environment nyata.
Environment Variable #
Gunakan:
.env.localuntuk Next.js.env.exampleuntuk dokumentasi
Hindari hardcode environment di Dockerfile.
Workflow Developer #
Jalankan:
docker compose up --buildAkses aplikasi di
http://localhost:3000Edit file di
app/ataupages/Fast Refresh otomatis berjalan
Tidak perlu install Node.js di host
Kapan Docker Masuk Akal? #
Docker sangat masuk akal jika:
- Tim > 1 orang
- Ada backend / database
- Ingin environment konsisten
Docker kurang masuk akal jika:
- Solo developer
- Prototype cepat
Engineering adalah soal konteks.
Anti-Pattern #
- ❌ Menggunakan image production untuk local dev
- ❌ Menyimpan
.nextdi volume host - ❌ Tidak memisahkan node_modules
- ❌ Terlalu banyak logic di Dockerfile
- ❌ Menganggap Docker selalu wajib
Best Practice #
- ✅ Gunakan volume bind mount untuk source code
- ✅ Pisahkan Dockerfile dev dan prod
- ✅ Gunakan
.env.local - ✅ Jangan build Next.js di local dev
- ✅ Jaga Dockerfile tetap sederhana
Penutup #
Dockerfile dan Docker Compose untuk Next.js local development bukan tentang kompleksitas, tapi tentang keteraturan dan konsistensi.
Dengan setup yang tepat:
- Fast Refresh tetap cepat
- Onboarding developer lebih singkat
- Masalah environment berkurang drastis