Home > Blog > tech

Docker Compose คืออะไร? สอนสร้าง Multi-Container App สำหรับ Development และ Production 2026

docker compose multi container guide
Docker Compose Multi-Container Guide 2026
2026-04-08 | tech | 3600 words

ในการพัฒนา Application สมัยใหม่ แทบจะเป็นไปไม่ได้ที่จะรันแค่ Container เดียว Application จริงๆ ประกอบด้วยหลาย Service เช่น Web Server, API, Database, Cache, Message Queue และอีกมากมาย การจัดการ Container หลายตัวด้วยคำสั่ง docker run ทีละตัวนั้นยุ่งยากและผิดพลาดง่าย Docker Compose จึงเป็นเครื่องมือที่ขาดไม่ได้สำหรับนักพัฒนาทุกคน

บทความนี้จะสอน Docker Compose ตั้งแต่พื้นฐานจนถึงเทคนิคขั้นสูง ครอบคลุมทุกหัวข้อที่คุณต้องรู้เพื่อจัดการ Multi-Container Application ทั้งใน Development และ Production ในปี 2026

Docker Compose คืออะไร?

Docker Compose คือเครื่องมือสำหรับกำหนดและรัน Multi-Container Docker Application ด้วยไฟล์ YAML เพียงไฟล์เดียว คุณเขียนทุก Service, Network, Volume ที่ต้องการในไฟล์ compose.yml แล้วใช้คำสั่งเดียว docker compose up ก็สามารถรันทุกอย่างได้พร้อมกัน

Docker Compose ถูกสร้างขึ้นเพื่อแก้ปัญหาหลักสามข้อ ข้อแรกคือการจัดการหลาย Container พร้อมกันโดยไม่ต้องรันคำสั่งทีละตัว ข้อสองคือการตั้งค่า Networking ระหว่าง Container ให้คุยกันได้อัตโนมัติ และข้อสามคือการจัดการ Data Persistence ผ่าน Volumes ที่กำหนดไว้ในที่เดียว

Docker Compose vs Dockerfile vs Kubernetes

เครื่องมือหน้าที่ใช้เมื่อ
Dockerfileสร้าง Image สำหรับ 1 Containerต้องการ Custom Image
Docker Composeจัดการหลาย Container บน 1 เครื่องDevelopment, Small Production
Kubernetesจัดการ Container ข้ามหลายเครื่องLarge Scale Production

Docker Compose ไม่ได้มาแทน Dockerfile แต่ใช้ร่วมกัน Dockerfile สร้าง Image ส่วน Compose จัดการว่า Image เหล่านั้นจะรันอย่างไร เชื่อมต่อกันอย่างไร และตั้งค่าอะไรบ้าง

compose.yml Syntax พื้นฐาน

ไฟล์ compose.yml (หรือ docker-compose.yml) เป็นหัวใจของ Docker Compose ประกอบด้วย Top-Level Keys หลักคือ services, networks, volumes, configs และ secrets

# compose.yml — ตัวอย่าง Full-Stack Application
services:
  # Web Application (React/Next.js)
  web:
    build: ./frontend
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://api:8000
    depends_on:
      - api
    networks:
      - frontend

  # API Server (Python FastAPI)
  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - frontend
      - backend
    volumes:
      - ./backend:/app

  # PostgreSQL Database
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis Cache
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

volumes:
  postgres_data:
  redis_data:
ชื่อไฟล์: Docker Compose รู้จักทั้ง compose.yml และ docker-compose.yml แต่ในปี 2026 แนะนำให้ใช้ compose.yml ซึ่งเป็นชื่อมาตรฐานใหม่

คำสั่ง Docker Compose ที่ใช้บ่อย

# รัน Services ทั้งหมด (foreground)
docker compose up

# รัน Services ทั้งหมด (background)
docker compose up -d

# Build images ใหม่ก่อนรัน
docker compose up -d --build

# หยุด Services ทั้งหมด
docker compose down

# หยุดและลบ Volumes ด้วย (ระวัง! ข้อมูลหาย)
docker compose down -v

# ดูสถานะ Services
docker compose ps

# ดู Logs
docker compose logs           # ทุก Service
docker compose logs api       # เฉพาะ api
docker compose logs -f api    # Follow logs (real-time)

# รัน Command ใน Container
docker compose exec api bash
docker compose exec db psql -U user -d myapp

# รัน One-off Command
docker compose run --rm api python manage.py migrate

# Restart Service เดียว
docker compose restart api

# Scale Service (สร้างหลาย Instance)
docker compose up -d --scale api=3

# ดู Resource Usage
docker compose top
docker compose stats

Building Custom Images ใน Compose

คุณสามารถ Build Custom Image จาก Dockerfile ได้โดยตรงในไฟล์ Compose โดยระบุ build context แทนการใช้ image

# compose.yml
services:
  api:
    # วิธีที่ 1: ระบุ Path ที่มี Dockerfile
    build: ./backend

    # วิธีที่ 2: ระบุ Context + Dockerfile ชื่ออื่น
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
      args:
        - NODE_ENV=production
        - BUILD_DATE=${BUILD_DATE}
      target: production    # สำหรับ Multi-stage build

    # ตั้งชื่อ Image ที่ Build
    image: myapp-api:latest

    # Cache จาก Registry
    build:
      context: .
      cache_from:
        - myregistry/myapp:cache

ตัวอย่าง Multi-Stage Dockerfile

# backend/Dockerfile
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
USER appuser
EXPOSE 8000
CMD ["node", "dist/server.js"]

# Stage 3: Development
FROM node:20-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8000
CMD ["npm", "run", "dev"]

Environment Variables และ .env Files

Docker Compose รองรับหลายวิธีในการจัดการ Environment Variables ทำให้คุณแยก Configuration จาก Code ได้ตามหลัก 12-Factor App

# วิธีที่ 1: กำหนดตรงใน compose.yml
services:
  api:
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
      - NODE_ENV=production
      - LOG_LEVEL=info

# วิธีที่ 2: ใช้ .env file
services:
  api:
    env_file:
      - .env
      - .env.local    # override ค่าใน .env

# วิธีที่ 3: ใช้ Variable Substitution จาก Shell
services:
  api:
    image: myapp:${APP_VERSION:-latest}
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - SECRET_KEY=${SECRET_KEY:?SECRET_KEY is required}
# .env file (อยู่ที่เดียวกับ compose.yml)
POSTGRES_USER=myuser
POSTGRES_PASSWORD=supersecret123
POSTGRES_DB=myapp
APP_VERSION=2.1.0
REDIS_MAXMEMORY=512mb

# .env.local (สำหรับ override ในเครื่อง dev)
POSTGRES_PASSWORD=devpassword
LOG_LEVEL=debug
ข้อควรระวัง: อย่า Commit ไฟล์ .env ที่มี Password จริงเข้า Git ให้ใส่ .env ใน .gitignore และสร้าง .env.example เป็นตัวอย่างแทน

Networking ใน Docker Compose

Default Bridge Network

เมื่อคุณรัน docker compose up Docker จะสร้าง Network เริ่มต้นให้อัตโนมัติ โดยทุก Service จะอยู่ใน Network เดียวกันและสามารถเรียกหากันด้วยชื่อ Service ได้เลย

# ทุก Service คุยกันด้วย Service Name เป็น hostname
# api สามารถเชื่อมต่อ Database ได้ด้วย:
DATABASE_URL=postgresql://user:pass@db:5432/myapp
#                                    ^^  ← ชื่อ Service

# Redis
REDIS_URL=redis://redis:6379
#               ^^^^^ ← ชื่อ Service

Custom Networks

การแยก Network ช่วยเรื่อง Security เพราะ Service ที่ไม่จำเป็นต้องคุยกันจะแยก Network กัน เช่น Frontend ไม่ควรเข้าถึง Database โดยตรง

services:
  # Nginx อยู่ใน frontend network เท่านั้น
  nginx:
    image: nginx:alpine
    networks:
      - frontend
    ports:
      - "80:80"

  # API อยู่ทั้ง frontend และ backend
  api:
    build: ./api
    networks:
      - frontend     # รับ request จาก nginx
      - backend      # เชื่อมต่อ database

  # Database อยู่ใน backend เท่านั้น
  db:
    image: postgres:16
    networks:
      - backend      # nginx เข้าถึงไม่ได้

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true   # ไม่เปิดให้เข้าจากภายนอก

Service Discovery

Docker Compose มี Built-in DNS ที่ทำให้ Service ค้นหากันได้ด้วยชื่อ ถ้า Scale Service เป็นหลาย Instance Docker จะทำ Round-Robin DNS ให้อัตโนมัติ

# Scale api เป็น 3 instances
docker compose up -d --scale api=3

# nginx สามารถใช้ชื่อ "api" ได้
# Docker จะ round-robin ระหว่าง 3 instances
upstream api {
    server api:8000;  # จะ resolve เป็น 3 IP อัตโนมัติ
}

Volumes — จัดการ Data Persistence

Named Volumes

Named Volumes ถูกจัดการโดย Docker เอง เหมาะสำหรับ Data ที่ต้องการ Persist เช่น Database Files

services:
  db:
    image: postgres:16
    volumes:
      - postgres_data:/var/lib/postgresql/data    # Named Volume

  redis:
    image: redis:7
    volumes:
      - redis_data:/data                          # Named Volume

volumes:
  postgres_data:
    driver: local
  redis_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /path/on/host

Bind Mounts

Bind Mounts Map โฟลเดอร์จาก Host เข้าไปใน Container เหมาะสำหรับ Development ที่ต้องการเห็น Code Change ทันที

services:
  api:
    build: ./backend
    volumes:
      # Bind Mount — sync code จาก host
      - ./backend:/app

      # Bind Mount แบบ Read-Only
      - ./config/nginx.conf:/etc/nginx/nginx.conf:ro

      # Anonymous Volume — ป้องกัน node_modules ถูก override
      - /app/node_modules

tmpfs Mounts

tmpfs Mount เก็บข้อมูลใน Memory เท่านั้น หายเมื่อ Container หยุด เหมาะสำหรับข้อมูลชั่วคราวที่ต้องการความเร็วสูง

services:
  api:
    tmpfs:
      - /tmp
      - /run:size=64M    # จำกัดขนาด 64MB

Health Checks

Health Checks ช่วยให้ Docker รู้ว่า Service พร้อมใช้งานจริงหรือยัง ไม่ใช่แค่ Process รันอยู่ ซึ่งสำคัญมากสำหรับ depends_on และ Orchestration

services:
  api:
    build: ./backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s       # ตรวจทุก 30 วินาที
      timeout: 10s        # Timeout ต่อครั้ง
      retries: 3          # ลองกี่ครั้งก่อนถือว่า unhealthy
      start_period: 40s   # รอกี่วินาทีก่อนเริ่มตรวจ

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

  redis:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

  mysql:
    image: mysql:8
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

depends_on และ Startup Ordering

เมื่อ Service ต้องรอ Service อื่นพร้อมก่อน คุณใช้ depends_on กับ condition เพื่อควบคุมลำดับการ Start

services:
  api:
    build: ./backend
    depends_on:
      db:
        condition: service_healthy     # รอ DB healthy ก่อน
        restart: true                  # restart ถ้า DB restart
      redis:
        condition: service_started     # รอแค่ Redis start
      migrations:
        condition: service_completed_successfully  # รอ migration เสร็จ

  migrations:
    build: ./backend
    command: python manage.py migrate
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 5s
      timeout: 3s
      retries: 10
ข้อควรรู้: depends_on แบบเก่า (ไม่มี condition) แค่ควบคุมลำดับการ Start ไม่รอให้ Service พร้อมจริง ควรใช้ condition: service_healthy เสมอเมื่อทำได้

Profiles — Environment-Specific Services

Profiles ช่วยให้คุณกำหนดว่า Service ไหนจะรันใน Environment ไหน เช่น บาง Service รันเฉพาะตอน Development หรือเฉพาะตอน Testing

services:
  # Service หลัก — รันเสมอ
  api:
    build: ./backend
    ports:
      - "8000:8000"

  db:
    image: postgres:16

  # Debug Tools — รันเฉพาะ dev
  pgadmin:
    image: dpage/pgadmin4
    ports:
      - "5050:80"
    profiles:
      - dev
      - debug

  # Mailhog — รันเฉพาะ dev
  mailhog:
    image: mailhog/mailhog
    ports:
      - "8025:8025"
    profiles:
      - dev

  # Test Runner — รันเฉพาะตอน test
  test:
    build: ./backend
    command: pytest
    profiles:
      - test

  # Monitoring — รันเฉพาะ production
  prometheus:
    image: prom/prometheus
    profiles:
      - monitoring
      - production
# รัน Services หลัก (ไม่มี profile)
docker compose up -d

# รัน Services หลัก + dev tools
docker compose --profile dev up -d

# รัน Tests
docker compose --profile test run --rm test

# รัน production + monitoring
docker compose --profile production --profile monitoring up -d

# ตั้ง Profile ผ่าน Environment Variable
COMPOSE_PROFILES=dev docker compose up -d

Extending และ Overriding Configs

Docker Compose รองรับการแยกไฟล์ Config ตาม Environment ทำให้คุณมี Base Config แล้ว Override เฉพาะส่วนที่ต่างกัน

# compose.yml — Base config
services:
  api:
    build: ./backend
    environment:
      - NODE_ENV=production
    networks:
      - app-network

  db:
    image: postgres:16
    volumes:
      - postgres_data:/var/lib/postgresql/data

# compose.override.yml — Auto-loaded ใน Development
services:
  api:
    build:
      target: development
    volumes:
      - ./backend:/app      # Bind mount สำหรับ hot-reload
    ports:
      - "8000:8000"         # เปิด port สำหรับ debug
    environment:
      - NODE_ENV=development
      - DEBUG=true

  db:
    ports:
      - "5432:5432"         # เปิด port สำหรับ local access
# compose.prod.yml — Production overrides
services:
  api:
    build:
      target: production
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
    restart: always

  db:
    restart: always
    # ไม่เปิด port — เข้าถึงจาก internal network เท่านั้น
# Development (auto-loads compose.override.yml)
docker compose up -d

# Production (ระบุไฟล์เอง)
docker compose -f compose.yml -f compose.prod.yml up -d

# หรือใช้ COMPOSE_FILE environment variable
COMPOSE_FILE=compose.yml:compose.prod.yml docker compose up -d

Compose Watch — File Sync สำหรับ Dev

Docker Compose Watch เป็นฟีเจอร์ใหม่ที่ช่วยให้ Development Workflow ดีขึ้นมาก โดยจะ Watch ไฟล์และ Sync เข้า Container หรือ Rebuild อัตโนมัติเมื่อไฟล์เปลี่ยน

services:
  api:
    build: ./backend
    develop:
      watch:
        # Sync ไฟล์เข้า Container (เร็ว, ไม่ rebuild)
        - action: sync
          path: ./backend/src
          target: /app/src
          ignore:
            - node_modules/
            - "*.test.js"

        # Rebuild เมื่อ Dependencies เปลี่ยน
        - action: rebuild
          path: ./backend/package.json

        # Sync + Restart Container
        - action: sync+restart
          path: ./backend/config
          target: /app/config

  frontend:
    build: ./frontend
    develop:
      watch:
        - action: sync
          path: ./frontend/src
          target: /app/src
        - action: rebuild
          path: ./frontend/package.json
# เริ่ม Watch Mode
docker compose watch

# หรือรวมกับ up
docker compose up --watch

Production Deployment Patterns

Pattern 1: Single Server with Compose

# compose.prod.yml
services:
  api:
    image: myregistry/myapp-api:${APP_VERSION}
    restart: always
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  db:
    image: postgres:16-alpine
    restart: always
    volumes:
      - postgres_data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          memory: 2G

  nginx:
    image: nginx:alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./certbot/conf:/etc/letsencrypt:ro
    depends_on:
      - api

Pattern 2: Compose กับ Traefik Reverse Proxy

Traefik เป็น Reverse Proxy ที่ออกแบบมาสำหรับ Container โดยเฉพาะ มันอ่าน Docker Labels แล้วตั้งค่า Routing อัตโนมัติ รองรับ HTTPS ด้วย Let's Encrypt ในตัว

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entryPoints.web.address=:80"
      - "--entryPoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt

  api:
    build: ./backend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=8000"

  web:
    build: ./frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.web.rule=Host(`example.com`)"
      - "traefik.http.routers.web.tls.certresolver=letsencrypt"

volumes:
  letsencrypt:

Logging Configuration

การตั้งค่า Logging ที่ดีสำคัญมากใน Production เพื่อไม่ให้ Log Files กิน Disk จนเต็ม และเพื่อให้สามารถ Debug ปัญหาได้

services:
  api:
    # จำกัดขนาด Log
    logging:
      driver: "json-file"
      options:
        max-size: "10m"    # สูงสุด 10MB ต่อไฟล์
        max-file: "5"      # เก็บสูงสุด 5 ไฟล์ (50MB total)
        compress: "true"   # บีบอัดไฟล์เก่า

  # ส่ง Log ไปยัง External Service
  worker:
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://logserver:514"
        tag: "myapp-worker"

  # ปิด Log (ไม่แนะนำ)
  noisy-service:
    logging:
      driver: "none"

Resource Limits

การจำกัด Resource ป้องกันไม่ให้ Container ตัวหนึ่งกิน Resource จนหมด ทำให้ Container อื่นทำงานไม่ได้

services:
  api:
    deploy:
      resources:
        # กำหนดค่าสูงสุด
        limits:
          cpus: '1.0'        # สูงสุด 1 CPU core
          memory: 512M       # สูงสุด 512MB RAM
          pids: 100           # จำนวน Process สูงสุด
        # กำหนดค่าขั้นต่ำ (reserved)
        reservations:
          cpus: '0.25'       # สงวน 0.25 CPU
          memory: 128M       # สงวน 128MB RAM

  db:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

    # Shared Memory สำหรับ PostgreSQL
    shm_size: 256mb

Configs และ Secrets

Docker Compose รองรับ Configs สำหรับ Configuration Files และ Secrets สำหรับข้อมูลลับ เช่น Password, API Keys, Certificates

services:
  api:
    image: myapp-api
    configs:
      - source: api_config
        target: /app/config.json
    secrets:
      - db_password
      - api_key

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

configs:
  api_config:
    file: ./config/api.json

secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    environment: "API_KEY"  # อ่านจาก Environment Variable

Docker Compose กับ Multi-Stage Builds

การใช้ Multi-Stage Build ร่วมกับ Compose ช่วยให้คุณ Build Image สำหรับ Dev และ Production จาก Dockerfile เดียวกัน

# Dockerfile
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./

FROM base AS development
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

FROM base AS production
RUN npm ci --only=production
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]

# compose.yml (development)
services:
  api:
    build:
      context: ./backend
      target: development     # ใช้ Stage "development"
    volumes:
      - ./backend:/app
      - /app/node_modules

# compose.prod.yml (production)
services:
  api:
    build:
      context: ./backend
      target: production      # ใช้ Stage "production"

Real-World ตัวอย่าง: WordPress + MySQL + phpMyAdmin

# compose.yml — WordPress Stack
services:
  wordpress:
    image: wordpress:6-apache
    restart: always
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: wp_secret
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_data:/var/www/html
    depends_on:
      mysql:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_secret
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_secret
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  phpmyadmin:
    image: phpmyadmin:latest
    restart: always
    ports:
      - "8081:80"
    environment:
      PMA_HOST: mysql
      PMA_USER: root
      PMA_PASSWORD: root_secret
    profiles:
      - dev
    depends_on:
      - mysql

volumes:
  wp_data:
  mysql_data:

Real-World ตัวอย่าง: Node.js + MongoDB + Mongo Express

# compose.yml — MERN Stack
services:
  api:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      MONGODB_URI: mongodb://root:secret@mongo:27017/myapp?authSource=admin
      JWT_SECRET: ${JWT_SECRET}
      NODE_ENV: development
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      mongo:
        condition: service_healthy
    develop:
      watch:
        - action: sync
          path: ./backend/src
          target: /app/src
        - action: rebuild
          path: ./backend/package.json

  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      REACT_APP_API_URL: http://localhost:5000

  mongo:
    image: mongo:7
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: secret
    volumes:
      - mongo_data:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

  mongo-express:
    image: mongo-express:latest
    ports:
      - "8081:8081"
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: secret
      ME_CONFIG_MONGODB_URL: mongodb://root:secret@mongo:27017/
    profiles:
      - dev
    depends_on:
      - mongo

volumes:
  mongo_data:

Docker Compose vs Docker Swarm

เกณฑ์Docker ComposeDocker Swarm
จำนวนเครื่อง1 เครื่องหลายเครื่อง (Cluster)
Use CaseDevelopment, Small ProductionMedium Production
Scalingจำกัดใน 1 เครื่องข้ามเครื่องได้
High Availabilityไม่มีมี (Manager nodes)
Learning Curveง่ายปานกลาง
Config Filecompose.ymlcompose.yml (เดียวกัน!)
สถานะในปี 2026ยังนิยมมากลดความนิยมลง

Migration จาก Compose ไป Kubernetes

เมื่อ Application เติบโตจนต้องการ High Availability, Auto-scaling หรือ Multi-node Deployment คุณอาจต้องย้ายจาก Docker Compose ไป Kubernetes คุณสามารถใช้เครื่องมือช่วย Convert ได้

# ใช้ Kompose เพื่อ Convert compose.yml → K8s manifests
# ติดตั้ง Kompose
curl -L https://github.com/kubernetes/kompose/releases/latest/download/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv kompose /usr/local/bin/

# Convert
kompose convert -f compose.yml
# จะได้ไฟล์:
# api-deployment.yaml
# api-service.yaml
# db-deployment.yaml
# db-service.yaml
# postgres-data-persistentvolumeclaim.yaml

# Deploy ไป K8s
kubectl apply -f .

# หรือ Convert เป็น Helm Chart
kompose convert -c -f compose.yml
คำแนะนำ: อย่ารีบย้ายไป Kubernetes ถ้า Docker Compose ยังตอบโจทย์อยู่ Kubernetes มี Overhead สูงมาก ทั้งในแง่ Infrastructure และ Learning Curve สำหรับทีมเล็ก Docker Compose + Single Server มักเพียงพอสำหรับ Traffic ระดับปานกลาง

Best Practices สำหรับ Docker Compose

Troubleshooting ปัญหาที่พบบ่อย

# ปัญหา: Container เริ่มไม่ได้
docker compose logs service_name
docker compose events

# ปัญหา: Port ชน
docker compose ps    # ดู port ที่ใช้อยู่
lsof -i :8000       # ดู process ที่ใช้ port นั้น

# ปัญหา: Volume Permission
# เพิ่มใน Dockerfile:
RUN chown -R appuser:appgroup /app
USER appuser

# ปัญหา: Network ไม่เชื่อมกัน
docker compose exec api ping db    # ทดสอบ connectivity
docker network ls                   # ดู networks
docker network inspect project_default  # ดูรายละเอียด

# ปัญหา: Build Cache เก่า
docker compose build --no-cache
docker compose up -d --force-recreate

# ปัญหา: Disk เต็ม
docker system df           # ดูการใช้ disk
docker system prune -a     # ลบทุกอย่างที่ไม่ได้ใช้
docker volume prune        # ลบ volumes ที่ไม่ได้ใช้

สรุป

Docker Compose เป็นเครื่องมือที่ขาดไม่ได้สำหรับการพัฒนา Application ที่มีหลาย Service ด้วยไฟล์ compose.yml เพียงไฟล์เดียว คุณสามารถกำหนดทุกอย่างตั้งแต่ Services, Networks, Volumes จนถึง Health Checks และ Resource Limits

ในปี 2026 Docker Compose มาพร้อมฟีเจอร์ใหม่ที่ทรงพลัง เช่น Compose Watch สำหรับ Development, Profiles สำหรับแยก Environment, Configs และ Secrets สำหรับ Security และ Production Deployment Patterns ที่ใช้งานได้จริง

เริ่มต้นวันนี้ สร้างไฟล์ compose.yml ในโปรเจกต์ของคุณ กำหนด Services ที่ต้องการ รัน docker compose up แล้วคุณจะเข้าใจว่าทำไม Docker Compose ถึงเป็นเครื่องมือมาตรฐานของนักพัฒนาทั่วโลก ไม่ว่าจะเป็นการพัฒนาบนเครื่องตัวเองหรือ Deploy ขึ้น Production Server


Back to Blog | iCafe Forex | SiamLanCard | Siam2R