Docker Compose Multi-Container Apps ฉบับสมบูรณ์ 2026
Docker Compose เป็นเครื่องมือที่ขาดไม่ได้สำหรับ developer และ DevOps ทุกคน ช่วยจัดการ application ที่มีหลาย container ด้วยไฟล์ YAML ไฟล์เดียว แทนที่จะต้อง docker run ทีละ container พร้อม options ยาวเหยียด Docker Compose ใช้คำสั่ง docker compose up เดียว สร้างทุกอย่างให้พร้อมใช้งานทันที
บทความนี้ครอบคลุมทุกอย่างตั้งแต่พื้นฐานจนถึง advanced topics เช่น multi-stage builds custom networks named volumes healthcheck profiles environment variables secrets และ production deployment patterns ทุกตัวอย่างทดสอบจริงบน Docker 27 ใช้งานได้เลย สำหรับ reverse proxy ที่ integrate กับ Docker ได้ดีที่สุดดู Traefik Reverse Proxy ครับ
สารบัญ
- 1. ทำไมต้อง Docker Compose
- 2. ติดตั้ง Docker และ Compose
- 3. compose.yml พื้นฐาน
- 4. ตัวอย่าง: WordPress + MySQL + Redis
- 5. Networks — แยก Frontend/Backend
- 6. Volumes — Persistent Data
- 7. Environment Variables และ .env
- 8. Healthcheck และ Depends_on
- 9. Build จาก Dockerfile
- 10. Profiles — Dev/Test/Prod
- 11. Production Best Practices
- 12. คำสั่งที่ใช้บ่อย
- 13. Troubleshooting
- 14. FAQ
1. ทำไมต้อง Docker Compose
Application สมัยใหม่ไม่เคยรันด้วย container เดียว ตัวอย่างเช่น web app ทั่วไปต้องมี web server database cache queue worker และ reverse proxy ถ้าต้อง docker run ทุก container ด้วยมือ จะเจอปัญหาหลายอย่าง ต้องจำ options ของแต่ละ container ต้องสร้าง network เอง ต้อง manage volume เอง ต้อง start ตามลำดับที่ถูกต้อง Docker Compose แก้ปัญหาทั้งหมดนี้ด้วย declarative YAML file ที่อธิบายทุกอย่างในที่เดียว
- Reproducible — ทุกคนในทีมได้ environment เหมือนกัน 100%
- Version Controlled — compose.yml เก็บใน Git ได้ track ทุกการเปลี่ยนแปลง
- One Command — docker compose up สร้างทุกอย่าง docker compose down ลบทุกอย่าง
- Isolation — แต่ละ project มี network แยก ไม่ conflict กัน
2. ติดตั้ง Docker และ Compose
# ติดตั้ง Docker Engine (Ubuntu 24.04)
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# ตรวจสอบ
docker --version
# Docker version 27.x.x
docker compose version
# Docker Compose version v2.x.x
# เพิ่ม user ปัจจุบันเข้า docker group
sudo usermod -aG docker $USER
newgrp docker
3. compose.yml พื้นฐาน
# compose.yml (หรือ docker-compose.yml)
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
api:
image: node:20-alpine
working_dir: /app
volumes:
- ./api:/app
command: node server.js
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: appuser
POSTGRES_PASSWORD: secret123
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
# คำสั่งพื้นฐาน
docker compose up -d # สร้างและ start ทุก service
docker compose ps # ดู status
docker compose logs -f web # ดู log ของ web service
docker compose down # หยุดและลบทุก container
docker compose down -v # ลบ volumes ด้วย
4. ตัวอย่าง: WordPress + MySQL + Redis
# compose.yml — WordPress Production Stack
services:
wordpress:
image: wordpress:6-apache
restart: unless-stopped
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_content:/var/www/html/wp-content
depends_on:
mysql:
condition: service_healthy
networks:
- frontend
- backend
mysql:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- backend
volumes:
wp_content:
mysql_data:
redis_data:
networks:
frontend:
backend:
# สร้าง .env file
cat > .env << 'EOF'
DB_PASSWORD=SuperSecretP@ss2026
MYSQL_ROOT_PASSWORD=RootP@ss2026
EOF
# Start
docker compose up -d
# ตรวจสอบ
docker compose ps
# NAME SERVICE STATUS PORTS
# wp-mysql-1 mysql running 3306/tcp
# wp-redis-1 redis running 6379/tcp
# wp-wp-1 wordpress running 0.0.0.0:8080->80/tcp
5. Networks — แยก Frontend/Backend
การแยก network เป็น security best practice ที่สำคัญ web server อยู่ใน frontend network ที่เข้าถึงจากภายนอกได้ database อยู่ใน backend network ที่เข้าถึงได้เฉพาะจาก application เท่านั้น attacker ที่ hack web server ไม่สามารถเข้าถึง database โดยตรงได้
services:
nginx:
networks:
- frontend # เข้าถึงจากภายนอก
app:
networks:
- frontend # รับ request จาก nginx
- backend # เข้าถึง database
db:
networks:
- backend # เข้าถึงได้เฉพาะจาก app
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # ไม่มี internet access
6. Volumes — Persistent Data
# Named volumes — Docker จัดการ path ให้
volumes:
db_data:
driver: local
# Bind mounts — mount directory จาก host
services:
app:
volumes:
- ./src:/app/src # bind mount สำหรับ development
- node_modules:/app/node_modules # named volume สำหรับ dependencies
# Backup named volume
docker run --rm -v myapp_db_data:/data -v $(pwd):/backup \
alpine tar czf /backup/db_backup.tar.gz -C /data .
สำหรับ backup strategy โดยละเอียดอ่าน Rsync Backup Linux Guide ครับ
7. Environment Variables และ .env
# .env file (ไม่ commit เข้า Git!)
DB_PASSWORD=secret123
REDIS_URL=redis://redis:6379
APP_PORT=3000
# ใช้ใน compose.yml
services:
app:
ports:
- "${APP_PORT}:3000"
environment:
- DB_PASSWORD=${DB_PASSWORD}
- REDIS_URL=${REDIS_URL}
# Override สำหรับ environment ต่างๆ
# .env.production / .env.staging / .env.development
docker compose --env-file .env.production up -d
ห้าม commit .env ที่มี credentials เข้า Git เด็ดขาด เพิ่ม .env ใน .gitignore สร้าง .env.example ที่มีเฉพาะ key ไม่มี value เป็น template ให้ทีม
8. Healthcheck และ Depends_on
services:
app:
depends_on:
db:
condition: service_healthy # รอจน db healthy ก่อน start
redis:
condition: service_started # รอแค่ start ไม่ต้อง healthy
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s # รอ 30 วินาทีก่อนเริ่มตรวจ
redis:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
healthcheck สำคัญมากสำหรับ production ไม่ใช่แค่ตรวจว่า container รันอยู่ แต่ตรวจว่า service ข้างในพร้อมรับ connection จริง ป้องกันปัญหา application start แต่ database ยังไม่พร้อม
9. Build จาก Dockerfile
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
NODE_VERSION: "20"
target: production # multi-stage build
image: myapp:latest # tag image ที่ build
# Dockerfile (multi-stage)
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM base AS development
RUN npm ci
COPY . .
CMD ["npm", "run", "dev"]
FROM base AS production
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]
# Build และ start
docker compose up -d --build
# Build เฉพาะ service
docker compose build app
# Push ไป registry
docker compose push app
10. Profiles — Dev/Test/Prod
services:
app:
image: myapp:latest
# ไม่มี profiles = run เสมอ
db:
image: postgres:16
# ไม่มี profiles = run เสมอ
adminer:
image: adminer
ports:
- "8081:8080"
profiles:
- debug # run เฉพาะเมื่อเปิด debug profile
test-runner:
build: ./tests
profiles:
- test # run เฉพาะเมื่อ test
monitoring:
image: grafana/grafana
profiles:
- monitoring # run เฉพาะเมื่อต้องการ monitoring
# Start เฉพาะ services หลัก
docker compose up -d
# Start พร้อม debug tools
docker compose --profile debug up -d
# Run tests
docker compose --profile test run test-runner
11. Production Best Practices
services:
app:
image: myapp:v1.2.3 # ใช้ specific tag ไม่ใช่ latest
restart: unless-stopped # restart อัตโนมัติเมื่อ crash
deploy:
resources:
limits:
cpus: "2.0" # จำกัด CPU
memory: 512M # จำกัด Memory
reservations:
cpus: "0.5"
memory: 256M
logging:
driver: json-file
options:
max-size: "10m" # จำกัดขนาด log
max-file: "3" # เก็บ 3 ไฟล์
read_only: true # filesystem read-only
tmpfs:
- /tmp # เฉพาะ /tmp เขียนได้
security_opt:
- no-new-privileges:true # ป้องกัน privilege escalation
- ใช้ specific image tag — ไม่ใช้ latest เพื่อให้ reproducible
- ตั้ง resource limits — ป้องกัน container กิน resource ทั้ง host
- จำกัด log size — ป้องกัน disk เต็ม
- read_only filesystem — ป้องกัน attacker เขียนไฟล์
- restart policy — unless-stopped เหมาะกับ production
สำหรับ reverse proxy ที่ detect Docker services อัตโนมัติแนะนำ Traefik หรือ Nginx Reverse Proxy สำหรับ monitoring containers ใช้ Zabbix หรือ Prometheus ครับ
12. คำสั่งที่ใช้บ่อย
# Lifecycle
docker compose up -d # Start ทั้งหมด
docker compose down # Stop + ลบ containers
docker compose down -v # Stop + ลบ containers + volumes
docker compose restart # Restart ทั้งหมด
docker compose restart app # Restart เฉพาะ service
# Monitoring
docker compose ps # ดู status
docker compose logs -f # ดู log ทั้งหมด
docker compose logs -f app db # ดู log เฉพาะ services
docker compose top # ดู processes
# Maintenance
docker compose pull # ดึง images ใหม่
docker compose up -d --force-recreate # recreate ทุก container
docker compose exec app bash # เข้า shell ของ container
docker compose run --rm app npm test # รัน one-off command
# Scaling
docker compose up -d --scale app=3 # Scale app เป็น 3 instances
13. Troubleshooting
Container restart loop
# ดู log ว่า error อะไร
docker compose logs app --tail 50
# ดู exit code
docker compose ps -a
# app exited (1) = application error
# app exited (137) = killed by OOM (out of memory)
Service ไม่เชื่อมต่อกัน
# ตรวจว่าอยู่ network เดียวกัน
docker compose exec app ping db
# ใช้ service name เป็น hostname ไม่ใช่ localhost
# ถูก: DB_HOST=db
# ผิด: DB_HOST=localhost
Volume data หาย
# ตรวจว่าใช้ named volume ไม่ใช่ anonymous volume
docker volume ls | grep myproject
# ระวัง docker compose down -v จะลบ volumes!
Docker Compose กับ Development Workflow
จากประสบการณ์ที่ใช้ Docker Compose ในทีม development มาหลายปี ผมพบว่า pattern ที่ดีที่สุดคือมี compose.yml หลักสำหรับ services ที่ทุกคนต้องใช้ แล้วมี compose.override.yml สำหรับ development settings ที่แต่ละคนปรับได้ Docker Compose จะ merge ทั้งสอง file อัตโนมัติ ทำให้ developer แต่ละคน customize environment ของตัวเองได้โดยไม่กระทบคนอื่น
สำหรับ CI/CD pipeline ใช้ Docker Compose สร้าง test environment ที่เหมือน production ทุกประการ รัน integration test แล้วลบทิ้ง ไม่เหลือ artifacts ใน CI server สำหรับ CI/CD แบบละเอียดอ่าน Jenkins CI/CD หรือ GitLab CE ครับ สำหรับ Kubernetes ที่ซับซ้อนกว่าดู Kubernetes HA Cluster หรือ K3s Lightweight Kubernetes
เรื่อง security สำหรับ Docker host แนะนำ Fail2ban ป้องกัน brute force และ SSH Security Hardening สำหรับผู้ที่สนใจเรื่องการลงทุนและ automation ด้านการเงิน iCafeForex.com สอน Forex ครบวงจร รับสัญญาณเทรดฟรีจาก XMSignal.com/th ครับ รีวิวอุปกรณ์ IT ที่ SiamLancard.com และ Siam2R.com
14. FAQ
Docker Compose คืออะไร ต่างจาก Docker ธรรมดาอย่างไร
Docker Compose จัดการ multi-container applications ด้วย YAML ไฟล์เดียว ใช้ docker compose up สร้างทุก container network volume พร้อมกัน เหมาะกับ application ที่มีหลาย service
docker-compose กับ docker compose ต่างกันไหม
docker-compose (V1 Python) ถูก deprecate แล้ว docker compose (V2 Go) เป็น plugin ของ Docker CLI เร็วกว่า feature มากกว่า ใช้ V2 เสมอ
Docker Compose เหมาะกับ production ไหม
เหมาะสำหรับ single-host deployment ถ้าต้องการ auto-scaling หรือ multi-host orchestration ใช้ Kubernetes แทน สำหรับ small to medium production Docker Compose เพียงพอ
Docker Compose ใช้ .env file อย่างไร
สร้างไฟล์ .env ไว้ที่เดียวกับ compose.yml กำหนดตัวแปรเช่น DB_PASSWORD=secret แล้วอ้างอิงด้วย ${DB_PASSWORD} ใน compose file ห้าม commit .env เข้า Git
จะ update image ของ service อย่างไร
docker compose pull ดึง image ใหม่ แล้ว docker compose up -d เพื่อ recreate เฉพาะ container ที่เปลี่ยน container อื่นไม่ถูก restart
Docker Compose คือเครื่องมือที่ทำให้ทุกอย่างง่ายขึ้น reproducible และเชื่อถือได้ ลงทุนเวลาเรียนรู้วันเดียว ใช้ได้ตลอดอาชีพ DevOps ครับ
สรุป
สำหรับผู้ที่เพิ่งเริ่มต้นใช้ Docker Compose แนะนำให้เริ่มจาก project เล็กๆ ก่อน เช่น WordPress กับ MySQL สองตัว แล้วค่อยเพิ่มความซับซ้อนทีละอย่าง เพิ่ม Redis เพิ่ม Nginx เพิ่ม monitoring ทีละ service จนเข้าใจทุก concept แล้วค่อยนำไปใช้กับ project จริงครับ
Docker Compose เปลี่ยนวิธีที่ developer ทำงานกับ multi-container applications อย่างสิ้นเชิง จากการต้อง docker run ทีละ container พร้อม options ยาวเหยียดมาเป็นไฟล์ YAML ไฟล์เดียวที่อธิบายทุกอย่าง version controlled ได้ share กับทีมได้ ทุกคนได้ environment เหมือนกัน 100 เปอร์เซ็นต์ ไม่มี works on my machine อีกต่อไปครับ
Docker Compose เป็นเครื่องมือที่ทุก developer ต้องเชี่ยวชาญในปี 2026 ไม่ว่าจะใช้สำหรับ local development ที่ต้องการ environment เหมือน production หรือ production deployment จริงบน single host Docker Compose ทำให้ทุกอย่างง่ายขึ้น reproducible และ version controlled ลงทุนเวลาเรียนรู้สักวันเดียว แล้วคุณจะได้ทักษะที่ใช้ได้ตลอดอาชีพ DevOps ครับ
บทความแนะนำ
Compose ชีวิตการเงินของคุณ iCafeForex.com สอน Forex ครบวงจร พร้อม EA Trading อัตโนมัติ ที่ orchestrate การเทรดให้คุณ