正在加载,请稍候…

Docker Compose for Development: Multi-Service Local Environment

Set up a complete local development environment with Docker Compose. Learn service dependencies, volumes, environment variables, health checks, and development workflows.

Docker Compose for Development: Multi-Service Setup

Complete Development Stack

# docker-compose.yml
version: '3.9'

services:
  # Main application
  api:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules  # Don't override container's node_modules
    environment:
      NODE_ENV: development
      DATABASE_URL: postgres://postgres:password@postgres:5432/mydb
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    command: npm run dev

  # Frontend
  web:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "5173:5173"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      VITE_API_URL: http://localhost:3000

  # PostgreSQL
  postgres:
    image: postgres:16-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./db/init:/docker-entrypoint-initdb.d  # Init scripts
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  # Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

  # MailHog for email testing
  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI

  # MinIO for S3-compatible storage
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123
    volumes:
      - minio_data:/data
    command: server /data --console-address ":9001"

volumes:
  postgres_data:
  redis_data:
  minio_data:

Development Dockerfile

# Dockerfile.dev
FROM node:20-alpine

WORKDIR /app

# Install dependencies first (better caching)
COPY package*.json ./
RUN npm ci

# Source code is mounted as volume, not copied
COPY . .

EXPOSE 3000
CMD ["npm", "run", "dev"]

Environment Configuration

# .env (development defaults, committed to git)
NODE_ENV=development
LOG_LEVEL=debug

# .env.local (secrets, not committed)
OPENAI_API_KEY=sk-...
STRIPE_SECRET_KEY=sk_test_...
# docker-compose.override.yml (local overrides, not committed)
services:
  api:
    environment:
      LOG_LEVEL: trace
    ports:
      - "9229:9229"  # Node.js debugger
    command: npm run dev:debug

Useful Commands

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f api

# Restart single service
docker-compose restart api

# Run commands in service
docker-compose exec api npm run db:migrate
docker-compose exec postgres psql -U postgres mydb

# Stop and clean up
docker-compose down
docker-compose down -v  # Also remove volumes

# Rebuild after Dockerfile changes
docker-compose build api
docker-compose up -d --build api

Profile-based Services

# Optional services with profiles
services:
  pgadmin:
    image: dpage/pgadmin4
    profiles: ["tools"]
    ports:
      - "5050:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@example.com
      PGADMIN_DEFAULT_PASSWORD: admin
# Start with optional tools
docker-compose --profile tools up -d

Docker Compose eliminates "works on my machine" by making the dev environment reproducible.