🖥️ VPS · 31 ตุลาคม 2026 · อ่าน 12 นาที

ใช้งาน Docker Compose บน VPS Ubuntu
สำหรับ Multi-container App

คู่มือทีละขั้นตอน ตั้งแต่ติดตั้ง Docker Engine จนรัน stack ที่มีหลาย service พร้อมกัน ไม่ว่าจะเป็น WordPress + MySQL หรือ Node.js + PostgreSQL + Redis

Docker Compose บน VPS Ubuntu — Multi-container App

สารบัญ

  1. Docker Compose คืออะไร ทำไมต้องใช้?
  2. ติดตั้ง Docker Engine และ Docker Compose บน Ubuntu
  3. โครงสร้างไฟล์ docker-compose.yml
  4. ตัวอย่าง: WordPress + MySQL + phpMyAdmin
  5. ตัวอย่าง: Node.js + PostgreSQL + Redis
  6. คำสั่ง Docker Compose ที่ใช้บ่อย
  7. Network และ Volume ใน Docker Compose
  8. ใช้ .env file จัดการ Secret อย่างปลอดภัย
  9. เทคนิค Production-ready
  10. แก้ปัญหาที่พบบ่อย
  11. คำถามที่พบบ่อย (FAQ)

Docker Compose คืออะไร ทำไมต้องใช้?

แอปพลิเคชันสมัยใหม่ไม่ได้รันใน container เดียว — ระบบ e-commerce ปกติต้องการ web server, database, cache, queue worker และ reverse proxy ทำงานร่วมกัน Docker Compose คือเครื่องมือที่ช่วยจัดการ multi-container application ทั้งหมดผ่านไฟล์ YAML ไฟล์เดียว

ด้านDocker (docker run)Docker Compose
จำนวน containerทีละตัวหลาย service พร้อมกัน
Networkสร้างเองสร้างอัตโนมัติ
Volumeระบุใน flagนิยามใน YAML
Dependencyจัดการเองdepends_on + healthcheck
Restartตั้ง flag ทีละตัวrestart policy ใน YAML

Docker Compose เหมาะสำหรับ development environment และ small-to-medium production บน VPS เดี่ยว ถ้าต้องการ scale หลาย server ข้ามไปดู Docker Swarm หรือ Kubernetes แทน

ติดตั้ง Docker Engine และ Docker Compose บน Ubuntu

แนะนำ Ubuntu 22.04 LTS หรือ 24.04 LTS สำหรับ production

ขั้นตอนที่ 1 — อัปเดต package และติดตั้ง dependency

sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release

ขั้นตอนที่ 2 — เพิ่ม Docker GPG key และ repository

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

ขั้นตอนที่ 3 — ติดตั้ง Docker Engine และ Compose Plugin

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

ขั้นตอนที่ 4 — ให้ user ใช้ Docker โดยไม่ต้อง sudo

sudo usermod -aG docker $USER
newgrp docker   # หรือ logout แล้ว login ใหม่

ตรวจสอบการติดตั้ง

docker --version          # Docker version 26.x.x
docker compose version    # Docker Compose version v2.x.x
💡 หมายเหตุ Docker Compose v2 ใช้คำสั่ง docker compose (ไม่มี hyphen) แทน docker-compose (มี hyphen) ในเวอร์ชันเก่า บทความนี้ใช้ v2 ทั้งหมด

โครงสร้างไฟล์ docker-compose.yml

ไฟล์ docker-compose.yml ใช้ YAML syntax นิยาม service, network และ volume ดังนี้

services:            # รายการ service/container
  web:               # ชื่อ service (ใช้เป็น hostname ใน network ได้)
    image: nginx:alpine
    ports:
      - "80:80"      # host_port:container_port
    volumes:
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      - app
    restart: unless-stopped

  app:
    build: .         # build จาก Dockerfile ในโฟลเดอร์ปัจจุบัน
    environment:
      - NODE_ENV=production
    env_file:
      - .env
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    restart: unless-stopped

volumes:             # named volumes (persistent)
  pgdata:

networks:            # custom networks (optional — default network สร้างอัตโนมัติ)
  default:
    driver: bridge

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

สร้างโฟลเดอร์และ compose file:

mkdir ~/wordpress-stack && cd ~/wordpress-stack
# docker-compose.yml
services:
  wordpress:
    image: wordpress:6.7-php8.2-apache
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
      WORDPRESS_DB_USER: ${MYSQL_USER}
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - wp_data:/var/www/html
    depends_on:
      mysql:
        condition: service_healthy
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  phpmyadmin:
    image: phpmyadmin:5-apache
    ports:
      - "8081:80"
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
    depends_on:
      - mysql
    restart: unless-stopped

volumes:
  wp_data:
  mysql_data:
# .env (สร้างแยกต่างหาก — ห้าม commit ขึ้น Git)
MYSQL_ROOT_PASSWORD=StrongRootPass2026!
MYSQL_DATABASE=wordpress_db
MYSQL_USER=wpuser
MYSQL_PASSWORD=StrongUserPass2026!
# รัน stack
docker compose up -d

# ตรวจสอบ container ทั้งหมดรันอยู่
docker compose ps

ตัวอย่าง: Node.js + PostgreSQL + Redis

mkdir ~/nodeapp-stack && cd ~/nodeapp-stack
# docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --save 20 1 --loglevel warning
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  pg_data:
  redis_data:

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

คำสั่งความหมาย
docker compose up -dรัน stack ใน background (detach)
docker compose downหยุดและลบ container (volume ยังอยู่)
docker compose down -vหยุดและลบทั้ง container + volume
docker compose psดูสถานะ container ทั้งหมด
docker compose logs -fดู log แบบ real-time
docker compose logs -f webดู log เฉพาะ service "web"
docker compose exec app shเข้า shell ใน container "app"
docker compose restartrestart ทุก service
docker compose pullดึง image เวอร์ชันใหม่
docker compose buildbuild image จาก Dockerfile ใหม่
docker compose configตรวจสอบ syntax ของ compose file

Network และ Volume ใน Docker Compose

Network

Docker Compose สร้าง default network ให้อัตโนมัติ — ทุก service ในไฟล์เดียวกันสามารถเชื่อมหากันผ่าน ชื่อ service ได้เลย เช่น mysql, redis, postgres

# service "app" เชื่อม postgres โดยใช้ hostname "postgres"
DATABASE_URL=postgresql://user:pass@postgres:5432/mydb
#                                   ^^^^^^^ ชื่อ service
⚠️ ข้อควรระวัง port ที่ map ออกมาให้ host (เช่น 3306:3306 สำหรับ MySQL) ควรปิดด้วย firewall ถ้าไม่ต้องการให้ external access ตรงๆ ให้ใช้แค่ internal network ระหว่าง container

Volume

มี 2 ประเภทหลัก:

ใช้ .env file จัดการ Secret อย่างปลอดภัย

Docker Compose โหลดไฟล์ .env ใน directory เดียวกันอัตโนมัติ ค่าตัวแปรสามารถใช้ใน compose file ผ่าน ${VARIABLE_NAME}

# .env
DB_PASSWORD=MySecurePassword2026
JWT_SECRET=long-random-string-here
REDIS_PASSWORD=RedisPass2026
# .gitignore — ห้าม commit .env เด็ดขาด!
.env
*.env
!.env.example
💡 Best Practice สร้างไฟล์ .env.example ที่มีชื่อ variable แต่ไม่มีค่าจริง เพื่อให้ developer คนอื่นรู้ว่าต้องกำหนดค่าอะไรบ้าง

เทคนิค Production-ready

1. Restart Policy

restart: unless-stopped  # รีสตาร์ทเองเสมอ ยกเว้น docker compose stop

2. Resource Limits

services:
  app:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          memory: 256M

3. Healthcheck

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s

4. Nginx Reverse Proxy

แนะนำให้รัน Nginx ข้างนอก Docker Compose หรือเป็น service แยกใน stack ทำหน้าที่ reverse proxy และจัดการ SSL certificate (Let's Encrypt ผ่าน Certbot)

5. Backup Volume

# backup named volume
docker run --rm \
  -v wordpress-stack_mysql_data:/data \
  -v $(pwd)/backup:/backup \
  alpine tar czf /backup/mysql-$(date +%Y%m%d).tar.gz /data

แก้ปัญหาที่พบบ่อย

ปัญหาสาเหตุวิธีแก้
Container หยุดทันทีหลัง upError ใน entrypoint หรือ healthcheck faildocker compose logs <service> ดู error
Port already in usePort ซ้ำกับ process อื่นsudo ss -tlnp | grep PORT หาตัวที่ใช้อยู่
Volume data หายใช้ down -v โดยไม่ตั้งใจตรวจสอบ backup ก่อน docker compose down
Service เชื่อมกันไม่ได้ไม่ได้อยู่ network เดียวกันตรวจสอบ network ใน docker compose config
Permission denied บน volumeUID/GID ใน container ไม่ตรงเพิ่ม user: "UID:GID" ใน service

คำถามที่พบบ่อย (FAQ)

Docker Compose ต่างจาก Docker อย่างไร?
Docker รัน container เดียว ส่วน Docker Compose จัดการหลาย container พร้อมกันผ่านไฟล์ docker-compose.yml ทำให้กำหนด network, volume และ dependency ระหว่าง service ได้สะดวก
VPS ต้องการ RAM เท่าไหร่สำหรับ Docker Compose?
ขั้นต่ำแนะนำ 2GB RAM สำหรับ 2-3 service เช่น Web + Database + Cache ถ้าต้องการรัน 5+ service ควรใช้ RAM 4GB ขึ้นไป AsiaGB VPS มีแพ็กเกจตั้งแต่ 1GB จนถึง 8GB เลือกได้ตามขนาด stack
docker-compose.yml ควรเก็บไว้ที่ไหน?
ควรสร้าง directory แยกต่างหากสำหรับแต่ละ project เช่น ~/myapp/ และเก็บ docker-compose.yml พร้อม .env file ไว้ใน directory นั้น และควรเก็บไว้ใน Git repository โดยไม่ commit .env
ทำอย่างไรให้ Docker Compose รันอัตโนมัติเมื่อ VPS reboot?
เพิ่ม restart: unless-stopped ใน docker-compose.yml ทุก service Docker Engine จะ restart container อัตโนมัติเมื่อ system boot ขึ้นมา
จะ update image ใหม่ใน Docker Compose ได้อย่างไร?
รัน docker compose pull เพื่อดึง image ใหม่ แล้วรัน docker compose up -d เพื่อ recreate container ด้วย image ใหม่ service ที่ไม่มีการเปลี่ยนแปลงจะไม่ถูก restart
Docker Compose รองรับ VPS ทุก OS ไหม?
รองรับ Linux ทุก distro หลัก (Ubuntu, Debian, CentOS, AlmaLinux) ใน production แนะนำ Ubuntu LTS เพราะมี community support ใหญ่และ package อัปเดตสม่ำเสมอ

สรุป

Docker Compose ช่วยจัดการ multi-container application บน VPS ได้อย่างมีระเบียบ ขั้นตอนหลักคือ ติดตั้ง Docker Engine + Compose Plugin, สร้าง docker-compose.yml นิยาม service, เก็บ secret ใน .env file และเพิ่ม restart policy ให้ container กลับมาทำงานเองหลัง reboot

สำหรับ VPS ที่เหมาะกับ Docker Compose แนะนำ RAM 2-4GB ขึ้นไป AsiaGB มี VPS ไทยและสิงคโปร์ พร้อม SSD รวดเร็ว Uptime 99% เริ่มต้นราคาคุ้มค่า