Docker Compose

Docker Compose

เครื่องมือที่ช่วยให้คุณสามารถ กำหนดและจัดการหลายๆ Docker Container ได้ในไฟล์เดียว โดยใช้ไฟล์ docker-compose.yml แทนที่จะต้องรันคำสั่ง docker run แยกทีละ container สรุปสั้นๆ คือ Docker Compose = “Script สำหรับควบคุมระบบ Docker หลาย container พร้อมกัน”

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

คำสั่งคำอธิบาย
docker-compose upสร้างและรันทุก container ที่ระบุไว้ในไฟล์
docker-compose up -dรันแบบ background
docker-compose downหยุดและลบ container
docker-compose psดูสถานะ container
docker-compose logsดู log ของทุก container
docker-compose exec <service> <cmd>เข้ารันคำสั่งใน container

การเขียนไฟล์ docker-compose.yml เป็นวิธีที่สะดวกและชัดเจนในการจัดการหลายๆ Container พร้อมกันในโปรเจกต์เดียว โดยระบุว่าให้รันอะไร ใช้ image ไหน, เชื่อมโยง network, volume, environment ฯลฯ ได้ทั้งหมดในไฟล์เดียว

รูปแบบพื้นฐานของ docker-compose.yml

version: '3.8'  # ระบุเวอร์ชันของ Compose

services:       # กำหนด service ต่าง ๆ ที่จะรัน
  web:          # ชื่อ service เช่น web
    image: nginx:latest       # ใช้ image จาก Docker Hub
    ports:
      - "8080:80"             # พอร์ตบน host:container
    volumes:
      - ./html:/usr/share/nginx/html  # mount ไฟล์จาก local ไปยัง container
    networks:
      - mynet

  app:
    build: ./app              # สร้าง image จาก Dockerfile ในโฟลเดอร์ ./app
    depends_on:
      - db                    # รอ db ก่อนจึงเริ่ม app
    environment:
      - APP_ENV=production
    networks:
      - mynet

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydb
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - mynet

volumes:
  db_data:

networks:
  mynet:

คำอธิบาย docker-compose.yml

ส่วนความหมาย
versionเวอร์ชันของ Compose (แนะนำ 3.8 สำหรับ Docker modern)
servicesรายการ container ที่จะรัน
imageใช้ image ที่ระบุ
buildกำหนด path ไปยัง Dockerfile เพื่อสร้าง image เอง
portsMapping port (host:container)
volumesการ mount ไฟล์หรือโฟลเดอร์
networksระบุ network ที่ใช้ร่วมกัน
environmentกำหนดตัวแปรแวดล้อม
depends_onระบุลำดับการเริ่มต้นของ service

ตัวอย่าง MySQL กับ phpMyAdmin

docker-compose.yml ที่ใช้สำหรับสร้าง Docker network และรัน MySQL กับ phpMyAdmin โดยให้ทั้งสอง container เชื่อมต่อกันผ่าน network เดียวกัน และสามารถเข้าถึง phpMyAdmin ผ่าน browser ได้

docker-compose.yml

version: '3.8'  # กำหนดเวอร์ชันของ Docker Compose ที่ใช้ (3.8 เหมาะกับ Docker เวอร์ชันใหม่)

services:  # ส่วนที่ใช้กำหนดบริการ (containers) ต่าง ๆ ภายในโปรเจกต์

  mysql:  # ตั้งชื่อ service ว่า mysql
    image: mysql:8.0  # ใช้ image mysql เวอร์ชัน 8.0 จาก Docker Hub
    container_name: my-mysql  # ตั้งชื่อ container ว่า my-mysql
    restart: always  # ให้ container restart ใหม่อัตโนมัติถ้าหยุดหรือพัง
    environment:  # กำหนดค่าตัวแปรแวดล้อมให้กับ MySQL container
      MYSQL_ROOT_PASSWORD: rootpass  # รหัสผ่านของ root user
      MYSQL_DATABASE: mydb  # สร้างฐานข้อมูลชื่อ mydb ทันทีเมื่อ container start
      MYSQL_USER: myuser  # สร้าง user ชื่อ myuser
      MYSQL_PASSWORD: mypass  # กำหนดรหัสผ่านให้ user myuser
    ports:
      - "3306:3306"  # map พอร์ต 3306 ของ host ไปยังพอร์ต 3306 ใน container
    volumes:
      - mysql_data:/var/lib/mysql  # ผูก volume ชื่อ mysql_data ไปยังโฟลเดอร์เก็บข้อมูล MySQL
    networks:
      - mynet  # เชื่อมต่อกับ network ชื่อ mynet

  phpmyadmin:  # ตั้งชื่อ service ว่า phpmyadmin
    image: phpmyadmin/phpmyadmin  # ใช้ image ของ phpMyAdmin จาก Docker Hub
    container_name: my-phpmyadmin  # ตั้งชื่อ container ว่า my-phpmyadmin
    restart: always  # ให้ container restart ใหม่อัตโนมัติถ้าหยุดหรือพัง
    environment:  # กำหนดค่าตัวแปรแวดล้อมให้กับ phpMyAdmin
      PMA_HOST: mysql  # บอก phpMyAdmin ให้เชื่อมกับ container mysql (โดยใช้ชื่อ service)
      PMA_PORT: 3306  # ใช้พอร์ต 3306 ในการเชื่อมต่อกับ MySQL
    ports:
      - "8080:80"  # map พอร์ต 8080 ของ host ไปยังพอร์ต 80 ของ container (เปิดใช้งานผ่าน browser)
    depends_on:
      - mysql  # ให้ phpMyAdmin เริ่มหลังจาก mysql service พร้อมใช้งาน
    networks:
      - mynet  # เชื่อมต่อกับ network ชื่อ mynet เช่นเดียวกับ mysql

volumes:  # กำหนด volume สำหรับใช้เก็บข้อมูลถาวร
  mysql_data:  # ชื่อ volume ที่จะใช้กับ mysql

networks:  # กำหนดเครือข่ายภายใน Compose project
  mynet:  # ชื่อ network
    driver: bridge  # ใช้ driver แบบ bridge (default network แบบ isolated สำหรับ container ภายในเครื่องเดียวกัน)

วิธีใช้งาน

  1. บันทึกไฟล์ docker-compose.yml
  2. รันคำสั่ง docker-compose up -d
  3. เปิด browser ไปที่ http://localhost:8080

ตัวอย่าง การทำเว็บแอปพลิเคชัน ประกอบด้วย

  • NGINX (เว็บเซิร์ฟเวอร์)
  • PHP (ประมวลผล backend)
  • MySQL (ฐานข้อมูล)
  • phpMyAdmin (จัดการ MySQL)

ถ้าใช้ docker run → ต้องพิมพ์คำสั่ง 4 ชุด + config ซับซ้อน
แต่ถ้าใช้ docker-compose.yml → แค่ไฟล์เดียว สั่ง docker-compose up ก็พร้อมรันทั้งหมดในครั้งเดียว

โครงสร้างโฟลเดอร์ที่สร้างขึ้น

~/Desktop/docker-webserver/
  • docker-compose.yml
  • php/
    • Dockerfile
  • nginx/
    • default.conf
  • app/
    • index.php

php/Dockerfile (สำหรับ PHP-FPM)

FROM php:8.2-fpm

# ติดตั้ง extension ที่จำเป็น
RUN apt-get update && apt-get install -y \
    libzip-dev zip unzip \
    && docker-php-ext-install zip pdo pdo_mysql

# ตั้ง timezone (ถ้าต้องการ)
RUN ln -snf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && echo "Asia/Bangkok" > /etc/timezone

# ตั้ง working directory
WORKDIR /var/www/html

# Copy source code ไปใน container (ถ้าต้องการในขั้น build)
COPY ../app /var/www/html

สร้าง docker-compose.yml

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: my-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - mynetwork

  php:
    build:
      context: ./php
    container_name: my-php
    volumes:
      - ./app:/var/www/html
    networks:
      - mynetwork

  nginx:
    image: nginx:latest
    container_name: my-nginx
    ports:
      - "8080:80"
    volumes:
      - ./app:/var/www/html
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    networks:
      - mynetwork

  phpmyadmin:
    image: phpmyadmin
    container_name: my-phpmyadmin
    ports:
      - "8081:80"
    environment:
      PMA_HOST: my-mysql
      PMA_USER: user
      PMA_PASSWORD: pass
    depends_on:
      - mysql
    networks:
      - mynetwork

volumes:
  db_data:

networks:
  mynetwork:

สร้าง nginx/default.conf

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass my-php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
    }
}

สร้าง app/index.php

<?php
echo "<h1>Hello! KDAI KMITL <br> from PHP on NGINX via Docker Compose</h1>";
?>

เริ่มใช้งานเปิด Terminal แล้วรัน

cd ~/Desktop/docker-webserver
docker-compose up -d

เข้าเว็บผ่านเบราว์เซอร์

บริการURL
เว็บไซต์http://localhost:8080
phpMyAdminhttp://localhost:8081