All posts
DatabasesMay 12, 2026·6 min read

Docker Compose for Local Node.js Development

A docker-compose.yml that gives every developer on your team the same Postgres, Redis, and app stack with one command — including hot reload and seed data.

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

Ready to put this into practice?

Deploy your Node.js app to production in minutes — zero YAML, automatic CI/CD, and HTTPS included.