Bỏ qua đến nội dung chính
Docker ComposeDockerdev environmentDevOpslocal development

Docker Compose: Setup Dev Environment Hoàn Chỉnh

Docker Compose dev environment đầy đủ: Postgres, Redis, app, nginx. Volumes, networks, healthcheck, env. compose.yml chạy được ngay.

Xuất bản 7 phút đọc

Docker Compose là cách nhanh nhất để dev và team có cùng môi trường (Postgres, Redis, app) chỉ với 1 lệnh docker compose up. Bài này đi qua compose.yml production-grade từ A-Z.

Vì sao cần Compose?

Setup local thuần: cài Postgres, Redis, Node.js, config từng cái — mỗi dev mới mất 1 ngày, version khác nhau, "works on my machine". Compose: 1 file, 1 lệnh, ai pull về cũng chạy.

compose.yml cơ bản

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://postgres:secret@db:5432/alodev
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: alodev
    volumes:
      - pg-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pg-data:

Chạy:

docker compose up -d           # background
docker compose logs -f app     # tail log
docker compose down            # stop + remove
docker compose down -v         # cũng xoá volume (cẩn thận!)

Dev mode: hot reload qua bind mount

services:
  app:
    build:
      context: .
      target: dev          # multi-stage Dockerfile có stage 'dev'
    volumes:
      - .:/app             # bind mount source code
      - /app/node_modules  # anonymous volume — không overlap với host node_modules
    command: npm run dev
    environment:
      NODE_ENV: development

Sửa code trên host → file system event → nodemon reload. Anonymous volume trick: /app/node_modules không bị bind mount cover — container dùng deps đã npm ci trong build.

env_file để tách secret

services:
  app:
    env_file:
      - .env.local
    environment:
      NODE_ENV: development  # override env_file
# .env.local (gitignored)
DATABASE_URL=postgres://postgres:secret@db:5432/alodev
JWT_SECRET=dev-secret-thay-cho-production
SENDGRID_API_KEY=SG.test-key

Tách dev và prod: compose.override.yml

# compose.yml — base
services:
  app:
    image: alodev/api:latest
    environment:
      NODE_ENV: production

# compose.override.yml — auto-loaded khi docker compose up
services:
  app:
    build: .                    # build local thay vì pull image
    volumes:
      - .:/app
    command: npm run dev

Production không có override file → dùng image từ registry. Dev có override → build local, mount code.

Profile cho stack lớn

services:
  app:
    # ... luôn chạy
  db:
    # ... luôn chạy
  monitoring:
    image: prom/prometheus
    profiles: ["monitoring"]
  grafana:
    image: grafana/grafana
    profiles: ["monitoring"]
  mailhog:
    image: mailhog/mailhog
    profiles: ["test"]
docker compose up -d                            # chỉ app + db
docker compose --profile monitoring up -d       # + prometheus + grafana
docker compose --profile test up -d             # + mailhog

Network và service discovery

Mặc định Compose tạo 1 network, mọi service join. Service resolve nhau bằng tên: db:5432, cache:6379. Không cần IP.

Nếu cần tách network (ví dụ frontend không truy cập db trực tiếp):

services:
  api:    { networks: [frontend, backend] }
  web:    { networks: [frontend] }
  db:     { networks: [backend] }

networks:
  frontend: {}
  backend:  {}

Healthcheck đúng cho từng service

services:
  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d alodev"]
      interval: 5s
      timeout: 3s
      retries: 5

  cache:
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 2s

  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
      interval: 10s
      timeout: 5s
      start_period: 30s

start_period = grace period — không tính fail trong 30s đầu (app chưa start xong).

Compose trong CI

# .github/workflows/test.yml
- name: Start services
  run: docker compose up -d db cache
- name: Wait for db
  run: until docker compose exec -T db pg_isready; do sleep 1; done
- name: Run tests
  run: docker compose run --rm app npm test
- name: Cleanup
  if: always()
  run: docker compose down -v

Test integration với DB thực — không phải mock. Đọc thêm Integration testing.

Kết luận

Docker Compose là tool dev environment tốt nhất cho team Node.js/Python/Go. 1 lệnh docker compose up = full stack chạy. Khi production scale lớn hơn 1 server, anh sẽ migrate sang Kubernetes — nhưng giai đoạn đầu Compose là vừa đủ.

Zalo