ai

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

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

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

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

อ่านเพิ่ม: Container Orchestration นอกจาก Kubernetes มีอะไรอีก? Docker · อ่านเพิ่ม: Ansible คืออะไร? สอน Configuration Management และ IT Automat · อ่านเพิ่ม: Kubernetes Networking คืออะไร? สอน Service, Ingress, DNS และ

Docker Compose คืออะไร?

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

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

เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง Class Html คืออะไร — ข้อมูลครบถ้วน 2026

api สามารถเชื่อมต่อ Database ได้ด้วย:

DATABASE_URL=postgresql://user:pass@db:5432/myapp

^^ ← ชื่อ Service

Redis

REDIS_URL=redis://redis:6379

แนะนำเพิ่มเติม — ดูสัญญาณเทรดที่ XM Signal

^^^^^ ← ชื่อ 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 หยุด เหมาะสำหรับข้อมูลชั่วคราวที่ต้องการความเร็วสูง

เนื้อหาเกี่ยวข้อง — อ่านต่อ: XDR Platform Machine Learning Pipeline — คู่มือฉบับสมบูรณ์ 2026

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

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

เมื่อ 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 ปัญหาได้

แนะนำเพิ่มเติม — คู่มือเทรดจาก SiamCafeBook

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 ได้

เนื้อหาเกี่ยวข้อง — Distributed Tracing Machine Learning Pipeline —

ใช้ 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

เนื้อหาเกี่ยวข้อง — ทำความเข้าใจ LlamaIndex RAG Post-mortem Analysis — คู่มือฉบับสมบูรณ์ 2026

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

  • ใช้ Named Volumes สำหรับ Data: อย่าใช้ Bind Mount สำหรับ Database Data ใน Production เพราะ Performance แย่กว่า
  • ตั้ง Health Checks เสมอ: โดยเฉพาะ Database และ Service ที่ใช้เวลา Start นาน เพื่อให้ depends_on ทำงานถูกต้อง
  • แยกไฟล์ Config ตาม Environment: ใช้ compose.yml + compose.override.yml สำหรับ Dev และ compose.prod.yml สำหรับ Production
  • อย่าเปิด Port ที่ไม่จำเป็น: Database ไม่ควรเปิด Port ใน Production ให้เข้าถึงผ่าน Internal Network เท่านั้น
  • จำกัด Resources: ตั้ง Memory Limit และ CPU Limit เพื่อป้องกัน Container กิน Resource ทั้งเครื่อง
  • ใช้ .env สำหรับ Secrets: ไม่ Hard-code Password ใน compose.yml และอย่า Commit .env เข้า Git
  • ตั้ง Logging Limits: ไม่งั้น Log จะกิน Disk จนเต็ม
  • ใช้ restart: always ใน Production: เพื่อให้ Container กลับมาทำงานอัตโนมัติเมื่อ Crash
  • Pin Image Versions: ใช้ postgres:16-alpine ไม่ใช่ postgres:latest เพื่อความแน่นอนของ Build

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

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง