Ultimate Local Developer Environments with Docker & Docker Compose
A practical guide to configure fast, predictable local developer environments with Node.js, hot-reloading, and dedicated PostgreSQL caches using Docker.
Developing applications "on the bare metal" often leads to the infamous "it works on my machine" syndrome. By containerizing your local development workflow, you ensure identical runs in dev, staging, and production.
The Dockerfile Blueprint for Local Node Dev
We need a multi-stage Dockerfile setup that keeps building speeds lightning-fast by caching dependency layers properly:
# Development target
FROM node:20-alpine AS development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "run", "start:dev"]
Wiring it Up with Docker Compose
Docker Compose lets you boot up your API service, database container, and Redis cache altogether with a single command.
Here is a highly optimized configuration that includes persistent PostgreSQL volume mappings and fast hot-reloading:
version: '3.8'
services:
api:
build:
context: .
target: development
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
- '3000:3000'
environment:
- DATABASE_URL=postgresql://pratik:secret@db:5432/portfolio?schema=public
depends_on:
- db
db:
image: postgres:15-alpine
restart: always
environment:
- POSTGRES_USER=pratik
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=portfolio
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- '5432:5432'
volumes:
pgdata:
Key Optimization Tips:
pgdata, your mock PostgreSQL data persists even when containers are restarted or destroyed.- /usr/src/app/node_modules inside the volumes list prevents your host system's node_modules from overwriting the container's specialized Linux-binary node_modules.node:20-alpine) to shrink your container footprints from ~1.2GB down to < 200MB.Now you can spin up the entire ecosystem with just docker compose up --build and code with active hot-reloading!