เขียนไฟล์ docker-compose.yml อธิบายทุก Option ที่ใช้บ่อย

ไฟล์ docker-compose.yml คือหัวใจของ Docker Compose บทความนี้จะอธิบายทุก Option ที่ใช้บ่อยในการเขียนไฟล์ Compose พร้อมตัวอย่างจริงสำหรับใช้งาน

โครงสร้างไฟล์สมบูรณ์

services:
  service-name:
    image: image-name:tag       # ใช้ Image สำเร็จรูป
    build: ./path               # หรือ Build จาก Dockerfile
    container_name: my-app      # ชื่อ Container (optional)
    ports:
      - "host:container"        # Port Mapping
    environment:
      - KEY=VALUE               # Environment Variable
    volumes:
      - volume-name:/path       # Mount Volume
      - ./local:/container      # Bind Mount
    networks:
      - my-network              # Network ที่ใช้
    depends_on:
      - other-service           # Service ที่ต้องเริ่มก่อน
    restart: unless-stopped     # Restart Policy
    healthcheck:                # ตรวจสอบสุขภาพ
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  volume-name:                  # นิยาม Named Volume

networks:
  my-network:                   # นิยาม Network

Option สำคัญที่ควรรู้

image vs build

services:
  app:
    # ใช้ Image สำเร็จรูปจาก Registry
    image: nginx:1.25

  my-api:
    # Build Image จาก Dockerfile ใน Folder ปัจจุบัน
    build: .

  frontend:
    # Build พร้อมระบุ Build Args
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
      args:
        NODE_ENV: production

ports

services:
  web:
    ports:
      - "80:80"        # HOST:CONTAINER
      - "443:443"
      - "3000"         # Docker เลือก Port บน Host เอง

environment

services:
  app:
    environment:
      # แบบ List
      - DB_HOST=mysql
      - DB_PORT=3306
    # หรือแบบ Map
    environment:
      DB_HOST: mysql
      DB_PORT: 3306
    # หรือโหลดจากไฟล์ .env
    env_file:
      - .env

volumes

services:
  db:
    volumes:
      - db-data:/var/lib/mysql        # Named Volume
      - ./config:/etc/mysql/conf.d    # Bind Mount
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro  # Read-only

volumes:
  db-data:  # ต้องประกาศไว้ที่นี่ด้วย

depends_on

services:
  app:
    depends_on:
      db:
        condition: service_healthy  # รอจน DB Healthy ก่อน
      redis:
        condition: service_started  # รอแค่เริ่มได้

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

restart

services:
  app:
    restart: no               # ไม่ รีสตาร์ตเลย (default)
    # restart: always        # รีสตาร์ตทุกครั้งที่หยุด
    # restart: unless-stopped  # รีสตาร์ต ยกเว้นถึงหยุดเอง
    # restart: on-failure    # รีสตาร์ตเมื่อ Error เท่านั้น

ตัวอย่างไฟล์ครบจบ: Node.js + MySQL + Redis

services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=mysql
      - DB_PASSWORD=secret
      - REDIS_HOST=redis
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      retries: 5
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    restart: unless-stopped

volumes:
  mysql-data:

สรุป

Option สำคัญที่ควรรู้ในเกือบทุก Compose File ได้แก่ image/build, ports, environment, volumes, depends_on และ restart ครู่นี้คุณก็เขียนไฟล์ Compose สำหรับงานจริงได้แล้วครับ