it

Docker Compose v2 Team Productivity

Docker Compose v2 Team Productivity
สรุปคำตอบ: Docker Compose V2 คือ plugin รุ่นใหม่ที่ทำงานเป็น docker compose (ไม่มี hyphen) ฝังในตัว Docker CLI ตรง เพิ่ม Profiles, Depends-on healthcheck, Secrets, Extensions และรองรับ BuildKit เต็มรูปแบบ เหมาะมากสำหรับ team productivity เพราะ config เดียวทำงานได้ตั้งแต่ local dev ไปถึง CI/CD ช่วยลดปัญหา "works on my machine"

โดย อ.บอม กิตติทัศน์ | 15/03/2026 | SiamCafe.net Since 1997

Docker Compose V2: ความแตกต่างจาก V1

Docker Compose V1 เป็น Python standalone binary (docker-compose) ที่ต้องติดตั้งแยก V2 เป็น Go plugin ที่ integrate เข้า Docker CLI โดยตรง เรียกใช้ด้วย docker compose (ไม่มี hyphen) รวดเร็วกว่าและ maintain ง่ายกว่า Docker Desktop บน Mac/Windows มี Compose V2 ให้ใช้ทันทีโดยไม่ต้องติดตั้งเพิ่ม

ข้อดีหลักของ V2 ต่อ V1 ได้แก่: startup เร็วกว่าเพราะเขียนด้วย Go, รองรับ --profile flag สำหรับ environment ต่างๆ, depends_on รองรับ condition: service_healthy และ service_completed_successfully, docker compose watch สำหรับ live reload, รองรับ Compose Spec เต็มรูปแบบ

เนื้อหาเกี่ยวข้อง — Debian Linux Server 2026 Setup Guide

โครงสร้าง docker-compose.yml สำหรับ Team

# docker-compose.yml - production-ready team config
version: "3.9"

services:
  # Web application
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    image: myapp:${APP_VERSION:-latest}
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
      - SECRET_KEY=${SECRET_KEY}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    secrets:
      - db_password
    networks:
      - backend
      - frontend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # Development override ใช้กับ docker-compose.dev.yml
  app-dev:
    extends:
      service: app
    build:
      target: development
    volumes:
      - .:/app
    profiles:
      - dev

  # Database
  db:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Cache
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --requirepass ${REDIS_PASS:-}
    volumes:
      - redis_data:/data
    networks:
      - backend

  # Worker (background jobs)
  worker:
    build:
      context: .
      target: production
    command: celery -A myapp worker --loglevel=info -c 4
    depends_on:
      - db
      - redis
    environment:
      - DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
    networks:
      - backend
    restart: unless-stopped
    profiles:
      - production
      - worker

  # Nginx reverse proxy
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - static_files:/var/www/static:ro
    depends_on:
      - app
    networks:
      - frontend
    profiles:
      - production

  # Monitoring (optional profile)
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    networks:
      - backend
    profiles:
      - monitoring

volumes:
  postgres_data:
  redis_data:
  static_files:

networks:
  backend:
    internal: true
  frontend:

secrets:
  db_password:
    file: ./secrets/db_password.txt

Multi-file Compose Override Pattern สำหรับ Team

Pattern ที่ดีมากสำหรับ team คือการใช้ multiple Compose files แยก environment:

# docker-compose.dev.yml - override สำหรับ local dev
services:
  app:
    build:
      target: development
    volumes:
      - .:/app          # live code reload
      - /app/node_modules
    environment:
      - DEBUG=true
      - LOG_LEVEL=debug
    ports:
      - "8000:8000"
      - "5678:5678"   # debugger port

  db:
    ports:
      - "5432:5432"   # expose ให้ DB client เชื่อมได้

  # MailHog สำหรับ test email ใน dev
  mailhog:
    image: mailhog/mailhog
    ports:
      - "8025:8025"
      - "1025:1025"
    profiles:
      - dev
# docker-compose.ci.yml - override สำหรับ CI/CD
services:
  app:
    environment:
      - CI=true
      - TESTING=true

  db:
    # ใช้ tmpfs สำหรับ CI เพื่อความเร็ว
    tmpfs:
      - /var/lib/postgresql/data
# วิธีใช้งาน
# Local dev:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --profile dev

# CI/CD:
docker compose -f docker-compose.yml -f docker-compose.ci.yml up --abort-on-container-exit

# Production:
docker compose --profile production up -d

docker compose watch: Live Reload สำหรับ Developer

Docker Compose V2.22+ มี watch mode ที่ sync file changes แบบ real-time โดยไม่ต้อง mount volume:

# docker-compose.yml พร้อม watch config
services:
  app:
    build: .
    develop:
      watch:
        # sync source code เข้า container
        - action: sync
          path: ./src
          target: /app/src
          ignore:
            - __pycache__/

        # rebuild เมื่อ dependencies เปลี่ยน
        - action: rebuild
          path: requirements.txt

        # restart เมื่อ config เปลี่ยน
        - action: sync+restart
          path: ./config
          target: /app/config
# รัน watch mode
docker compose watch

# หรือ
docker compose up --watch

เนื้อหาเกี่ยวข้อง — Skaffold Dev 12-Factor App

Secrets Management ใน Docker Compose

Secrets ใน Compose V2 ช่วยให้ไม่ต้อง hardcode password ใน environment variables:

# secrets จาก file
secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt

# secrets จาก environment (สำหรับ CI)
secrets:
  db_password:
    environment: DB_PASSWORD  # อ่านจาก env var

# ใน service
services:
  app:
    secrets:
      - db_password
    # ถูก mount ที่ /run/secrets/db_password
# อ่าน secret ใน Python app
import os

def read_secret(name):
    secret_path = f"/run/secrets/{name}"
    if os.path.exists(secret_path):
        with open(secret_path) as f:
            return f.read().strip()
    # fallback สำหรับ local dev
    return os.environ.get(name.upper(), "")

DB_PASSWORD = read_secret("db_password")

Healthcheck และ Dependency Management

ปัญหาที่พบบ่อยใน team คือ service เริ่ม connect database ก่อนที่ db จะพร้อม V2 แก้ได้ด้วย healthcheck:

services:
  app:
    depends_on:
      db:
        condition: service_healthy    # รอให้ db healthy
      migration:
        condition: service_completed_successfully  # รอให้ migration จบ
      redis:
        condition: service_started    # แค่รอให้ start

  # Run database migrations ก่อน start app
  migration:
    build: .
    command: python manage.py migrate --no-input
    depends_on:
      db:
        condition: service_healthy
    restart: on-failure

  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 10s

Docker Compose สำหรับ CI/CD Pipeline

การใช้ Docker Compose ใน GitHub Actions / GitLab CI ทำให้ test environment consistent กับ local dev:

# .github/workflows/test.yml
name: Test
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Start services
        run: |
          docker compose -f docker-compose.yml \
                         -f docker-compose.ci.yml \
                         up -d db redis

      - name: Wait for services
        run: |
          docker compose exec -T db \
            sh -c 'until pg_isready -U user; do sleep 1; done'

      - name: Run migrations
        run: docker compose run --rm migration

      - name: Run tests
        run: |
          docker compose run --rm \
            -e CI=true \
            app pytest --cov=. --cov-report=xml -v

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml

      - name: Cleanup
        if: always()
        run: docker compose down -v

เนื้อหาเกี่ยวข้อง — Ubuntu Server 2026

Performance Tuning สำหรับ Team Workflow

Technique วิธีใช้ ผลที่ได้
BuildKit cache DOCKER_BUILDKIT=1 build เร็วขึ้น 2-5x
Multi-stage build แยก dev/prod Dockerfile stages image เล็ก prod ไม่มี dev tools
Registry cache cache_from: type=registry CI build เร็วขึ้น
Profiles --profile dev/prod start เฉพาะ service ที่ต้องการ
tmpfs tmpfs: /tmp test เร็วขึ้นบน CI
watch mode docker compose watch hot reload ไม่ต้อง restart

Team Workflow Best Practices

Commit docker-compose.yml ลงใน repo เสมอ ทุกคนในทีมควร clone แล้วรัน docker compose up ได้ทันทีโดยไม่ต้องตั้งค่าอะไรเพิ่ม

ใช้ .env.example file commit ไฟล์ .env.example ที่มีค่าเริ่มต้นปลอดภัยสำหรับ local dev แล้ว gitignore .env จริง ทำให้ developer ใหม่รู้ว่าต้องตั้งค่าอะไร

ตั้ง resource limits ใน production environment ควรตั้ง CPU/memory limits เพื่อป้องกัน container ตัวใดตัวหนึ่ง consume resource หมดระบบ

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 128M

Logging configuration ควร configure log driver อย่างชัดเจน ป้องกัน logs เต็ม disk:

services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Troubleshooting Docker Compose ปัญหาที่พบบ่อยใน Team

Port already in use มักเกิดจากมี service ค้างอยู่ แก้โดยรัน docker compose down หรือ lsof -i :PORT แล้ว kill process นั้น

Container cannot connect to service ตรวจสอบว่า service อยู่ใน network เดียวกัน และใช้ service name (ไม่ใช่ localhost) เป็น hostname

Volume permissions issue บน Linux user ID ภายใน container อาจไม่ตรงกับ host ใช้ user: "${UID}:${GID}" ใน compose file หรือ fix permission ใน Dockerfile

Build cache stale รัน docker compose build --no-cache เพื่อ force rebuild ทั้งหมด หรือ docker system prune เพื่อ clean ทุกอย่าง

FAQ Docker Compose V2

Q: docker-compose กับ docker compose ต่างกันอย่างไร?

A: docker-compose (hyphen) คือ V1 standalone binary เขียนด้วย Python docker compose (space) คือ V2 plugin เขียนด้วย Go integrate เข้า Docker CLI ตรง V1 deprecated แล้ว แนะนำใช้ V2

Q: ทำไม service ไม่รอให้ database พร้อมก่อน?

A: depends_on ธรรมดา รอแค่ container start ไม่ได้รอให้ service พร้อมรับ connection ต้องเพิ่ม condition: service_healthy พร้อม healthcheck ที่ database service

Q: จะแชร์ config ระหว่าง services ได้อย่างไร?

A: ใช้ extends เพื่อ inherit config จาก service อื่น หรือใช้ YAML anchors (&anchor / *anchor) สำหรับ inline reuse

Q: Profiles คืออะไร ใช้ทำอะไร?

A: Profiles ช่วยให้กำหนดว่า service ไหนจะ start เมื่อใช้ --profile flag เช่น --profile dev start mailhog, --profile monitoring start prometheus/grafana โดยไม่ต้องมี services เหล่านี้ทุกครั้ง

Docker Compose Networking ในเชิงลึก

Docker Compose สร้าง network ให้ services ใน stack เดียวกันสื่อสารกันได้โดยอัตโนมัติ โดย default ทุก service จะอยู่ใน network เดียวกัน ชื่อ projectname_default แต่ใน production ควรแยก network ตาม security zone

การออกแบบ network ที่ดีควรมี frontend network สำหรับ nginx กับ app, backend network สำหรับ app กับ db/redis, และตั้ง internal: true สำหรับ backend network เพื่อไม่ให้ external access ได้โดยตรง

Service resolution ใน Docker network ทำงานผ่าน embedded DNS server ของ Docker แต่ละ container สามารถ resolve ชื่อ service อื่นได้โดยตรง เช่น db, redis, worker ไม่จำเป็นต้องรู้ IP address

Volume Management: Best Practices

Volume ใน Docker Compose มีสองประเภทหลัก: named volumes และ bind mounts ต่างประเภทเหมาะกับ use case ต่างกัน

Named volumes เหมาะสำหรับข้อมูลที่ต้องการ persist เช่น database data, uploaded files Docker จัดการ lifecycle ให้ และทำงานได้ดีบนทุก OS รวมถึง Windows ที่มีปัญหา permission น้อยกว่า bind mount

Bind mounts เหมาะสำหรับ development workflow ที่ต้องการ sync code แบบ real-time ระหว่าง host กับ container ควรหลีกเลี่ยง bind mount ใน production เพราะ performance ต่ำกว่าและ permission issues บน Linux

# Volume patterns ที่แนะนำ
services:
  app:
    volumes:
      # Named volume สำหรับ persistent data
      - uploads:/app/media/uploads
      # Bind mount สำหรับ dev source code
      - ./src:/app/src:delegated     # :delegated เร็วกว่าบน Mac
      # tmpfs สำหรับ cache ที่ไม่ต้อง persist
      - type: tmpfs
        target: /tmp

  db:
    volumes:
      # Named volume เสมอสำหรับ database
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/myapp/postgres  # สำหรับ production เก็บข้อมูลที่ path ที่ backup ได้
  uploads:

Environment Variable Management ระดับ Team

การจัดการ environment variables อย่างเป็นระบบสำคัญมากสำหรับ team โดยเฉพาะเมื่อมี developer หลายคนและหลาย environment ต้องใช้ค่าต่างกัน แนวทางที่ดีที่สุดคือใช้ combination ของ .env files กับ Docker secrets

# .env.example ที่ commit ลง repo (ค่า default ปลอดภัย)
# Application
APP_ENV=development
APP_DEBUG=true
APP_PORT=8000
SECRET_KEY=dev-insecure-key-change-in-production

# Database (ค่า local dev)
DB_HOST=db
DB_PORT=5432
DB_NAME=myapp_dev
DB_USER=developer
DB_PASS=localdevpassword

# Redis
REDIS_HOST=redis
REDIS_PORT=6379

# API Keys (จำเป็นต้องตั้งค่าเอง)
STRIPE_KEY=              # ขอจาก team lead
SENDGRID_KEY=            # ขอจาก team lead

ทุกคนใน team ทำสำเนา .env.example เป็น .env แล้วใส่ค่า secret ที่จำเป็น ค่าที่ไม่ sensitive ให้มี default ใน .env.example เพื่อให้ใช้งานได้ทันที ส่วน production secrets ควรใช้ Docker secrets หรือ environment variable injection ผ่าน CI/CD system

Docker Compose สำหรับ Monorepo

หาก project ใช้ monorepo ที่มีหลาย service Docker Compose จัดการได้ดีมากโดยใช้ build.context ชี้ไปยัง directory ของแต่ละ service:

# monorepo structure
# /
# ├── services/
# │   ├── api/
# │   │   └── Dockerfile
# │   ├── worker/
# │   │   └── Dockerfile
# │   └── frontend/
# │       └── Dockerfile
# └── docker-compose.yml

services:
  api:
    build:
      context: ./services/api
      dockerfile: Dockerfile
    ports:
      - "8000:8000"

  worker:
    build:
      context: ./services/worker
    command: celery -A app worker

  frontend:
    build:
      context: ./services/frontend
      args:
        - API_URL=http://api:8000
    ports:
      - "3000:3000"

Debugging Docker Compose Issues

เครื่องมือสำคัญสำหรับ debug Docker Compose:

# ดู logs ทุก service
docker compose logs -f

# ดู log เฉพาะ service
docker compose logs -f app

# exec เข้า container
docker compose exec app bash
docker compose exec db psql -U myuser mydb

# ดู resource usage
docker compose stats

# config validation
docker compose config

# ดู service status
docker compose ps

# ดูว่า network ไหน container อยู่
docker network ls
docker inspect myapp_app_1 | grep -i network

เนื้อหาเกี่ยวข้อง — BGP Routing Advanced Production Guide

Docker Compose Extensions (x-) สำหรับ DRY Config

Compose V2 รองรับ YAML anchors และ Extensions (ขึ้นต้นด้วย x-) เพื่อลดการซ้ำซ้อนใน config:

# ใช้ YAML anchors เพื่อ reuse config
x-common-env: &common-env
  environment:
    - DATABASE_URL=postgresql://user:${DB_PASS}@db:5432/mydb
    - REDIS_URL=redis://redis:6379/0
    - SECRET_KEY=${SECRET_KEY}

x-healthcheck: &default-healthcheck
  healthcheck:
    interval: 30s
    timeout: 10s
    retries: 3

services:
  app:
    <<: *common-env
    <<: *default-healthcheck
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]

  worker:
    <<: *common-env
    command: celery -A app worker

สรุป Docker Compose V2 สำหรับ Team

Docker Compose V2 เป็นเครื่องมือ essential สำหรับ development team ในปัจจุบัน ช่วยให้ environment ของทุกคนใน team เหมือนกัน ลดปัญหา "works on my machine" ได้อย่างมีประสิทธิภาพ การเลือกใช้ features ที่เหมาะสม ได้แก่ profiles สำหรับ conditional services, healthcheck สำหรับ dependency management, secrets สำหรับ credential management, watch mode สำหรับ live development, และ multi-file override pattern สำหรับ environment management จะทำให้ workflow ของทีมราบรื่นและ productive มากขึ้น

ดูข้อมูลเพิ่มเติมที่ SiamLanCard และ Siam2R | SiamCafe Book

บทความที่เกี่ยวข้อง

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง