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 lokal

  • ports: expose Next.js dev server ke host

  • volumes:

    • .:/app → sinkronisasi source code
    • /app/node_modules → mencegah konflik dependency
  • environment: memastikan Next.js berjalan di mode development

  • command: 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.local untuk Next.js
  • .env.example untuk dokumentasi

Hindari hardcode environment di Dockerfile.


Workflow Developer #

  1. Jalankan:

    docker compose up --build
    
  2. Akses aplikasi di http://localhost:3000

  3. Edit file di app/ atau pages/

  4. Fast Refresh otomatis berjalan

  5. 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 .next di 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
About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact