Fastify #

Fastify dikenal sebagai framework Node.js yang ringan, cepat, dan fokus pada performance. Namun dalam praktik tim, kecepatan runtime saja tidak cukup. Konsistensi environment local development sering menjadi sumber masalah: versi Node berbeda, dependency native bermasalah, hingga konflik port.

Docker hadir sebagai solusi untuk menyeragamkan environment development, dan Docker Compose membantu mengorkestrasi service pendukung seperti database, cache, atau message broker.

Artikel ini membahas secara mendetail dan rinci bagaimana menyusun Dockerfile dan Docker Compose untuk aplikasi Fastify dalam konteks local development, lengkap dengan reasoning arsitektural, best practice, dan anti-pattern yang sering terjadi.

Tujuan Setup Docker untuk Fastify #

Sebelum menulis Dockerfile, kita perlu sepakat dengan tujuannya:

  • Mendukung hot reload (via nodemon atau tsx)
  • Perubahan kode lokal langsung tercermin di container
  • Startup cepat, image ringan
  • Mudah diintegrasikan dengan database lokal
  • Tidak mencampur concern production ke environment development

Docker untuk local dev bukan tentang image sekecil mungkin, tapi tentang developer experience yang stabil dan predictable.


Struktur Project Fastify #

fastify-app/
├── src/
│   ├── app.ts
│   ├── server.ts
│   └── routes/
├── package.json
├── package-lock.json
├── tsconfig.json
├── Dockerfile
├── docker-compose.yml
└── .dockerignore

Struktur ini memisahkan:

  • entrypoint server
  • konfigurasi TypeScript
  • file Docker sebagai first-class citizen

.dockerignore: Fondasi yang Sering Dilupakan #

node_modules
npm-debug.log
.git
.gitignore
Dockerfile
.dockerignore

Tanpa .dockerignore, Docker build akan:

  • Lambat
  • Boros disk
  • Tidak deterministic

Ini langkah kecil dengan dampak besar.


Dockerfile untuk Fastify #

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:

  • Lebih ringan dibanding Debian-based image
  • Sudah cukup untuk local dev
  • Konsisten dengan LTS Node modern

2. WORKDIR #

Menetapkan /app sebagai root aplikasi di dalam container. Semua perintah berikutnya relatif ke direktori ini.

3. Copy package.json terlebih dahulu #

Ini Docker layer caching optimization:

  • Dependency tidak di-install ulang jika kode berubah
  • Build lebih cepat saat iterasi

4. npm install (bukan npm ci) #

Untuk local development:

  • Lebih fleksibel
  • Lebih toleran terhadap perubahan dependency

npm ci lebih cocok untuk CI/CD atau production image.

5. COPY source code #

Source code dicopy setelah dependency untuk menjaga cache.

6. CMD dev mode #

Biasanya menjalankan:

  • nodemon src/server.ts
  • atau tsx watch src/server.ts

Script npm yang Direkomendasikan #

"scripts": {
  "dev": "nodemon src/server.ts",
  "build": "tsc",
  "start": "node dist/server.js"
}

dev digunakan di Docker Compose untuk hot reload.


Docker Compose #

version: '3.9'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: fastify-dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    command: npm run dev
    environment:
      NODE_ENV: development
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: fastify-db
    environment:
      POSTGRES_USER: fastify
      POSTGRES_PASSWORD: fastify
      POSTGRES_DB: fastify_dev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Penjelasan Docker Compose #

Service api #

  • build: membangun image dari Dockerfile lokal

  • ports: expose Fastify ke host

  • volumes:

    • .:/app → sinkronisasi source code
    • /app/node_modules → mencegah override node_modules
  • command: override CMD untuk dev mode

  • depends_on: memastikan database start lebih dulu

Service db #

  • Menggunakan PostgreSQL versi Alpine
  • Volume named untuk persist data
  • Port dibuka agar bisa diakses tool lokal (DBeaver, TablePlus)

Workflow Developer #

  1. Jalankan:

    docker compose up --build
    
  2. Edit file di src/

  3. Fastify auto-reload via nodemon

  4. Tidak perlu install Node.js di host

  5. Semua developer punya environment identik


Kapan Docker Masuk Akal? #

Docker sangat masuk akal jika:

  • Tim > 1 orang
  • Banyak dependency native
  • Ada database / service pendukung

Docker overkill jika:

  • Prototype 1 file
  • Spike eksperimen singkat

Engineering adalah soal trade-off, bukan dogma.


Anti-Pattern #

  • ❌ Menggunakan image production untuk local dev
  • ❌ Tidak menggunakan volume → harus rebuild setiap edit
  • ❌ Menyimpan node_modules di host + container sekaligus
  • ❌ Menjalankan Fastify sebagai root di production (boleh di dev)
  • ❌ Dockerfile terlalu kompleks untuk kebutuhan lokal

Best Practice #

  • ✅ Gunakan volume bind mount untuk source code
  • ✅ Gunakan nodemon / tsx watch
  • ✅ Pisahkan Dockerfile dev & prod
  • ✅ Gunakan .env (dan .env.example)
  • ✅ Gunakan Alpine image untuk dev yang ringan

Penutup #

Dockerfile dan Docker Compose untuk Fastify di local development bukan tentang gaya-gayaan, tapi tentang:

  • Konsistensi
  • Produktivitas tim
  • Mengurangi “works on my machine”

Dengan setup yang tepat, Fastify tetap terasa cepat, ringan, dan menyenangkan, bahkan saat dijalankan di dalam container.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact