Docker Compose Multi-Container Apps 2026

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

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 ที่อธิบายทุกอย่างในที่เดียว

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

สำหรับ 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 การเทรดให้คุณ

รับ สัญญาณเทรด Forex ฟรีจาก XMSignal