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
nodemonatautsx) - 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 cilebih 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 lokalports: expose Fastify ke hostvolumes:.:/app→ sinkronisasi source code/app/node_modules→ mencegah override node_modules
command: override CMD untuk dev modedepends_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 #
Jalankan:
docker compose up --buildEdit file di
src/Fastify auto-reload via nodemon
Tidak perlu install Node.js di host
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_modulesdi 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.