Docker Compose v2 Team Productivity
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





