# Docker Compose ปี 2026: แอปพลิเคชัน Multi-Container, Networking และคำถามสัมภาษณ์ DevOps > บทเรียน Docker Compose สำหรับแอปพลิเคชัน multi-container พร้อม networking, volumes และการ deploy production รวมถึงคำถามสัมภาษณ์ DevOps - Published: 2026-08-03 - Updated: 2026-08-03 - Author: SharpSkill - Reading time: 5 min --- 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](https://docs.docker.com/compose/compose-file/) กำหนดแนวคิดหลักสามประการ: - **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](/blog/devops/kubernetes-deploying-first-application) ในภายหลัง ```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](/blog/devops/essential-devops-interview-questions) ```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) ## 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](/blog/devops/kubernetes-helm-charts-2026-packaging-deployment-interview-questions) ให้การ 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) ที่เลิกใช้แล้วด้วยประสิทธิภาพและฟีเจอร์ที่ดีกว่า --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/devops/docker-compose-2026-multi-container-networking-devops-interview