Docker Compose ปี 2026: แอปพลิเคชัน Multi-Container, Networking และคำถามสัมภาษณ์ DevOps

บทเรียน Docker Compose สำหรับแอปพลิเคชัน multi-container พร้อม networking, volumes และการ deploy production รวมถึงคำถามสัมภาษณ์ DevOps

Docker Compose ปี 2026: แอปพลิเคชัน Multi-Container, Networking และคำถามสัมภาษณ์ DevOps

Docker Compose ยังคงเป็นเครื่องมือหลักสำหรับการกำหนดและรันแอปพลิเคชัน Docker แบบ multi-container ในปี 2026 ไม่ว่าจะเป็นการ orchestrate stack development ในเครื่องหรือเตรียมตัวสำหรับการสัมภาษณ์ DevOps การทำความเข้าใจเรื่อง Compose networking, service dependencies และ pattern ในระดับ production เป็นสิ่งที่แยก engineer ระดับ junior ออกจาก practitioner ระดับ senior

ประเด็นสำคัญ

Docker Compose ใช้รูปแบบ YAML แบบ declarative เพื่อกำหนด services, networks และ volumes ในไฟล์เดียว การรัน docker compose up จะเริ่มต้น application stack ทั้งหมดพร้อม networking ที่แยกออกมาและ storage ที่คงอยู่

ทำความเข้าใจสถาปัตยกรรม Docker Compose

Docker Compose ทำงานบนหลักการง่ายๆ: กำหนด services ของแอปพลิเคชันในไฟล์ compose.yaml (การตั้งชื่อแบบใหม่แทนที่ docker-compose.yml) และ Compose จะจัดการการสร้าง container, networking และการจัดการ lifecycle

Docker Compose specification กำหนดแนวคิดหลักสามประการ:

  • Services: การกำหนดค่า container รวมถึง image, build context, environment variables และ resource limits
  • Networks: ช่องทางการสื่อสารที่แยกออกมาระหว่าง services
  • Volumes: การจัดเก็บข้อมูลแบบ persistent ที่คงอยู่หลังจาก container restart
yaml
# compose.yaml
services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/app
    depends_on:
      db:
        condition: service_healthy
    networks:
      - backend

  db:
    image: postgres:16
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=app
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - backend

networks:
  backend:
    driver: bridge

volumes:
  postgres_data:

secrets:
  db_password:
    file: ./secrets/db_password.txt

การกำหนดค่านี้แสดงให้เห็น pattern ที่พร้อมสำหรับ production หลายประการ: health checks สำหรับการจัดลำดับ dependency, Docker secrets สำหรับข้อมูลที่ละเอียดอ่อน, named volumes สำหรับ persistence และการกำหนด network อย่างชัดเจน

เจาะลึก Docker Compose Networking

โดยค่าเริ่มต้น Compose จะสร้าง network หนึ่งเดียวสำหรับแอปพลิเคชัน services ทั้งหมดจะเข้าร่วม network นี้และสามารถเข้าถึงกันได้โดยใช้ชื่อ service เป็น hostname การทำความเข้าใจ networking model นี้เป็นพื้นฐานสำหรับการย้ายไป Kubernetes ในภายหลัง

yaml
# compose.yaml
services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    networks:
      - frontend-net
      - backend-net

  api:
    build: ./api
    networks:
      - backend-net

  cache:
    image: redis:7-alpine
    networks:
      - backend-net

  db:
    image: postgres:16
    networks:
      - backend-net

networks:
  frontend-net:
    driver: bridge
  backend-net:
    driver: bridge
    internal: true

flag internal: true ป้องกันไม่ให้ backend network เข้าถึง internet ภายนอก service frontend เชื่อมต่อทั้งสอง networks ทำหน้าที่เป็นจุดเข้าเพียงจุดเดียว การแบ่ง network นี้สะท้อนแนวปฏิบัติด้านความปลอดภัยใน production

DNS Resolution

DNS server ที่ฝังอยู่ใน Docker จะ resolve ชื่อ service โดยอัตโนมัติ service api สามารถเข้าถึง database ที่ db:5432 โดยไม่ต้องกำหนดค่า IP ด้วยตนเอง

Multi-Stage Builds กับ Compose

image สำหรับ production ควรมีขนาดเล็กที่สุด Multi-stage builds รวมกับ Compose profiles ช่วยให้กำหนดค่าที่แตกต่างกันสำหรับ development และ production ได้

dockerfile
# api/Dockerfile
# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:22-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]

# Stage 3: Development
FROM node:22-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
USER node
CMD ["npm", "run", "dev"]
yaml
# compose.yaml
services:
  api:
    build:
      context: ./api
      target: ${BUILD_TARGET:-production}
    volumes:
      - ${API_VOLUMES:-./api/dist:/app/dist:ro}
    profiles:
      - ${COMPOSE_PROFILES:-prod}

การรัน BUILD_TARGET=development COMPOSE_PROFILES=dev docker compose up จะเริ่มการกำหนดค่า development พร้อม hot reload

Service Dependencies และ Health Checks

directive depends_on ควบคุมลำดับการ startup แต่การที่ container เริ่มต้นไม่ได้หมายความว่า service พร้อมใช้งาน Health checks แก้ปัญหา timing นี้ เป็น pattern ที่มักถูกถามในการสัมภาษณ์ DevOps

yaml
# compose.yaml
services:
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
      migrations:
        condition: service_completed_successfully

  migrations:
    build: ./api
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

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

มีเงื่อนไข dependency สามแบบ:

  • service_started: ค่าเริ่มต้น container ได้เริ่มต้นแล้ว
  • service_healthy: health check ผ่าน
  • service_completed_successfully: container ออกด้วย code 0 (สำหรับ init containers)

พร้อมที่จะพิชิตการสัมภาษณ์ DevOps แล้วหรือยังครับ?

ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ

Docker Compose สำหรับ Development ในเครื่อง

สภาพแวดล้อม development ได้รับประโยชน์จาก bind mounts, environment overrides และ debugging tools ไฟล์ compose.override.yaml จะถูกรวมเข้ากับ compose.yaml โดยอัตโนมัติ

yaml
# compose.yaml (การกำหนดค่าพื้นฐาน)
services:
  api:
    build: ./api
    environment:
      - NODE_ENV=production

  db:
    image: postgres:16
yaml
# compose.override.yaml (override สำหรับ development)
services:
  api:
    build:
      target: development
    volumes:
      - ./api:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    ports:
      - "9229:9229"

  db:
    ports:
      - "5432:5432"

Anonymous volume /app/node_modules ป้องกันไม่ให้ node_modules ของ host เขียนทับ dependencies ที่ติดตั้งใน container

Pattern การ Deploy สำหรับ Production

Docker Compose เหมาะสำหรับการ deploy production แบบ single-host สำหรับการ orchestrate แบบ multi-host Kubernetes กับ Helm ให้การ scaling ที่ดีกว่า แต่ Compose ยังคงเป็นทางเลือกที่ดีสำหรับแอปพลิเคชันขนาดเล็ก

yaml
# compose.prod.yaml
services:
  api:
    image: registry.example.com/api:${VERSION:-latest}
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - api

key deploy กำหนดค่า resource limits, จำนวน replicas และ restart policies การรัน docker compose -f compose.prod.yaml up -d จะเริ่มต้น stack production ในโหมด detached

Environment Variables และการจัดการ Secrets

การกำหนดค่าที่ละเอียดอ่อนต้องการการจัดการที่เหมาะสม Docker Compose รองรับหลายวิธี ตั้งแต่ไฟล์ .env จนถึง Docker secrets

bash
# .env
POSTGRES_PASSWORD=dev_password_only
API_SECRET_KEY=local_dev_key
yaml
# compose.yaml
services:
  api:
    environment:
      - API_SECRET_KEY  # สืบทอดจาก shell หรือ .env
      - DATABASE_URL=postgres://user:${POSTGRES_PASSWORD}@db:5432/app
    env_file:
      - ./config/api.env

สำหรับ production Docker secrets ให้ความปลอดภัยที่ดีกว่าโดยการ mount ข้อมูลที่ละเอียดอ่อนเป็นไฟล์แทนที่จะเป็น environment variables:

yaml
# compose.prod.yaml
services:
  api:
    secrets:
      - api_key
      - db_password
    environment:
      - API_KEY_FILE=/run/secrets/api_key

secrets:
  api_key:
    external: true
  db_password:
    file: ./secrets/db_password.txt
ข้อควรระวังด้านความปลอดภัย

อย่า commit ไฟล์ .env ที่มี secrets ของ production ลงใน version control ใช้การจัดการ secret ภายนอกเช่น HashiCorp Vault หรือโซลูชันของ cloud provider สำหรับการ deploy production

คำถามสัมภาษณ์ DevOps ที่พบบ่อยเกี่ยวกับ Docker Compose

ผู้สัมภาษณ์จะทดสอบความเข้าใจเกี่ยวกับแนวคิด Compose ผ่านสถานการณ์จริง คำถามเหล่านี้มักปรากฏในการสัมภาษณ์ DevOps และ platform engineering

ถ: container ใน Compose network สื่อสารกันอย่างไร?

Docker สร้าง dedicated bridge network สำหรับแต่ละ Compose project services สื่อสารโดยใช้ชื่อ service เป็น hostname DNS server ที่ฝังอยู่จะ resolve ชื่อเหล่านี้เป็นที่อยู่ IP ของ container traffic จากภายนอกสามารถเข้าถึง services ได้เฉพาะผ่าน port ที่ publish ไว้อย่างชัดเจนเท่านั้น

ถ: เกิดอะไรขึ้นเมื่อรัน docker compose up กับ container ที่มีอยู่?

Compose เปรียบเทียบการกำหนดค่าปัจจุบันกับ container ที่กำลังทำงาน services ที่ไม่เปลี่ยนแปลงจะทำงานต่อไป services ที่ถูกแก้ไขจะถูกสร้างใหม่ด้วยการตั้งค่าใหม่ services ใหม่จะเริ่มต้นใหม่ services ที่ถูกลบจะถูกหยุดและลบทิ้ง

ถ: จะจัดการ database migrations ใน Compose ได้อย่างไร?

มีสอง pattern แรก ใช้ init container กับ dependency service_completed_successfully:

yaml
services:
  migrate:
    image: api:latest
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  api:
    depends_on:
      migrate:
        condition: service_completed_successfully

สอง รวม logic migration ไว้ใน startup script ของแอปพลิเคชัน ตรวจสอบและใช้ migrations ที่รอดำเนินการก่อนรับ traffic

ถ: volumes และ bind mounts แตกต่างกันอย่างไร?

Named volumes ถูกจัดการโดย Docker เก็บไว้ที่ /var/lib/docker/volumes และสามารถพกพาระหว่าง host ได้ Bind mounts map directory ของ host โดยตรงเข้าไปใน container มีประโยชน์สำหรับ development แต่ขึ้นอยู่กับสภาพแวดล้อม Volumes รองรับ drivers สำหรับ remote storage เช่น NFS หรือ cloud block storage

ถ: docker-compose และ docker compose แตกต่างกันอย่างไร?

docker-compose มีขีดกลางเป็น standalone tool V1 ที่ใช้ Python ปัจจุบันเลิกใช้แล้ว docker compose มีช่องว่างเป็น implementation V2 ที่ใช้ Go ซึ่งรวมอยู่ใน Docker CLI V2 เร็วกว่า รองรับ Compose Specification อย่างเต็มที่ และได้รับการพัฒนาอย่างต่อเนื่อง

การ Debug แอปพลิเคชัน Compose

การ troubleshoot แอปพลิเคชันที่ใช้ container ต้องการเทคนิคเฉพาะ คำสั่งเหล่านี้เผยให้เห็นสิ่งที่เกิดขึ้นภายใน stack Compose:

bash
# ดู logs จากทุก services
docker compose logs -f

# Logs จาก service เฉพาะพร้อม timestamps
docker compose logs -f --timestamps api

# รัน command ใน container ที่กำลังทำงาน
docker compose exec api sh

# รัน command ครั้งเดียว (เริ่ม container ใหม่)
docker compose run --rm api npm test

# ดูการใช้ resource
docker compose top
docker stats

# ตรวจสอบการกำหนดค่า network
docker network inspect project_backend

# ตรวจสอบความถูกต้องของ compose file
docker compose config

คำสั่ง docker compose config รวม compose files ทั้งหมดและแสดงการกำหนดค่าสุดท้าย มีประโยชน์มากสำหรับการ debug ปัญหา variable interpolation

สรุป

  • Docker Compose กำหนดแอปพลิเคชัน multi-container ในไฟล์ YAML เดียวพร้อม services, networks และ volumes
  • Services สื่อสารผ่าน DNS โดยใช้ชื่อ service เป็น hostname ภายใน default bridge network
  • Health checks ด้วยเงื่อนไข service_healthy ทำให้มั่นใจในลำดับการ startup ที่ถูกต้อง
  • ใช้ compose.override.yaml สำหรับการตั้งค่าเฉพาะ development เช่น bind mounts และ debug ports
  • การ deploy production ได้รับประโยชน์จาก resource limits, restart policies และ Docker secrets สำหรับข้อมูลที่ละเอียดอ่อน
  • CLI docker compose (V2) แทนที่ docker-compose (V1) ที่เลิกใช้แล้วด้วยประสิทธิภาพและฟีเจอร์ที่ดีกว่า

เริ่มฝึกซ้อมเลย!

ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ

แชร์

บทความที่เกี่ยวข้อง

Kubernetes Helm Charts 2026: คู่มือการ Packaging, Deployment และคำถามสัมภาษณ์งาน

Kubernetes Helm Charts 2026: คู่มือการ Packaging, Deployment และคำถามสัมภาษณ์งาน

เรียนรู้ Helm Charts ใน Kubernetes อย่างลึกซึ้งด้วยบทเรียนปฏิบัติเกี่ยวกับการสร้าง chart, templating, deployment และคำถามสัมภาษณ์ที่พบบ่อยที่สุด

Prometheus vs Grafana vs Datadog monitoring comparison for DevOps interviews

Prometheus vs Grafana vs Datadog ในปี 2026: เปรียบเทียบระบบ Monitoring และคำถามสัมภาษณ์ DevOps

เปรียบเทียบ Prometheus, Grafana และ Datadog สำหรับ monitoring ในปี 2026 ครอบคลุมสถาปัตยกรรม, ภาษา query, alerting, ราคา TCO, Kubernetes monitoring และคำถามสัมภาษณ์งาน DevOps ด้าน observability

แผนภาพแสดงการทำงานของ ArgoCD และ GitOps บน Kubernetes

ArgoCD และ GitOps สำหรับ Kubernetes: คู่มือฉบับสมบูรณ์และคำถามสัมภาษณ์งาน 2026

เรียนรู้การใช้งาน ArgoCD สำหรับ GitOps บน Kubernetes ครอบคลุมตั้งแต่พื้นฐานไปจนถึงเทคนิคขั้นสูง พร้อมคำถามสัมภาษณ์งานที่พบบ่อยในปี 2026