The goal
docker compose up should give any developer — regardless of what they have installed locally — a running Postgres, Redis, and your Node.js app with hot reload. No more "it works on my machine" setup issues.
The complete compose file
version: '3.9'
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://dev:dev@db:5432/appdb
REDIS_URL: redis://redis:6379
NODE_ENV: development
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
command: npm run dev
db:
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
POSTGRES_DB: appdb
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/seed.sql:/docker-entrypoint-initdb.d/seed.sql
healthcheck:
test: pg_isready -U dev -d appdb
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:Development-stage Dockerfile target
FROM node:20-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm install # include devDependencies for dev
COPY . .
CMD ["npm", "run", "dev"]Hot reload inside Docker
The key is the volume mount: - .:/app. This mounts your local source code into the container, so changes you make locally are immediately visible inside the container. Your dev server (nodemon, ts-node-dev, or Vite) picks up the file changes and reloads.
The - /app/node_modules line is an anonymous volume that prevents the local node_modules from overwriting the container's node_modules (they can differ between platforms).
Seed data
Place a scripts/seed.sql file with initial data. Postgres automatically runs any .sql files in /docker-entrypoint-initdb.d/ on first start. For Prisma-based seeding:
# In your package.json:
"db:seed": "npx prisma db seed"
# In compose app command:
command: sh -c "npx prisma migrate deploy && npx prisma db seed && npm run dev"Useful compose commands
# Start everything
docker compose up
# Start in background
docker compose up -d
# View logs
docker compose logs -f app
# Reset database
docker compose down -v && docker compose up
# Run a one-off command
docker compose exec app npx prisma studio