Docker Compose คืออะไร: จัดการหลาย Container ง่ายๆ
ในบทความก่อนหน้านี้ เราได้เรียนรู้พื้นฐานของ Docker และวิธีการสร้างและรัน Container เดียวๆ แต่ในโลกของการพัฒนาซอฟต์แวร์สมัยใหม่ แอปพลิเคชันส่วนใหญ่มักจะประกอบด้วยหลายส่วนที่ทำงานร่วมกัน เช่น เว็บเซิร์ฟเวอร์, ฐานข้อมูล, และ Cache Server แต่ละส่วนเหล่านี้อาจถูกแยกเป็น Container ของตัวเอง แล้วเราจะจัดการ Container เหล่านี้ได้อย่างไร? นี่คือที่มาของ Docker Compose!
Docker Compose เป็นเครื่องมือที่ช่วยให้เราสามารถกำหนดค่าและจัดการแอปพลิเคชันที่ประกอบด้วยหลาย Docker Container พร้อมกันได้ โดยใช้ไฟล์ YAML ที่เรียกว่า docker-compose.yml ไฟล์นี้จะอธิบายว่าแต่ละ Container ของเราคืออะไร, มีความสัมพันธ์กันอย่างไร, และต้องถูกรันอย่างไร ทำให้การจัดการแอปพลิเคชันที่ซับซ้อนเป็นเรื่องง่าย
ทำความเข้าใจ Docker Compose file (docker-compose.yml)
ไฟล์ docker-compose.yml คือหัวใจหลักของ Docker Compose มันเป็นไฟล์ YAML ที่กำหนดค่า Services (Container), Networks, และ Volumes ที่แอปพลิเคชันของเราต้องการ มาดูโครงสร้างพื้นฐานของไฟล์นี้กัน:
version: "3.9" # ระบุ version ของ Docker Compose file format
services:
web: # กำหนด service ชื่อ "web" (เว็บเซิร์ฟเวอร์)
image: nginx:latest # ใช้ image nginx เวอร์ชั่นล่าสุด
ports:
- "80:80" # map port 80 บน host ไปยัง port 80 ใน container
depends_on:
- db # กำหนดให้ service "web" ขึ้นอยู่กับ service "db"
db: # กำหนด service ชื่อ "db" (ฐานข้อมูล)
image: mysql:5.7 # ใช้ image mysql เวอร์ชั่น 5.7
environment:
MYSQL_ROOT_PASSWORD: password # กำหนด environment variable สำหรับ password ของ root user
volumes:
- db_data:/var/lib/mysql # Mount volume เพื่อเก็บข้อมูลฐานข้อมูล
volumes:
db_data: # กำหนด volume ชื่อ "db_data"
จากตัวอย่างข้างต้น เรามี docker-compose.yml ที่กำหนด 2 Services:
- web: เป็นเว็บเซิร์ฟเวอร์ที่ใช้ image
nginx:latestและ map port 80 บน host ไปยัง port 80 ใน Container นอกจากนี้ยังกำหนดให้ขึ้นอยู่กับ Servicedbซึ่งหมายความว่า Docker Compose จะเริ่มต้นdbก่อนweb - db: เป็นฐานข้อมูล MySQL ที่ใช้ image
mysql:5.7และกำหนด environment variable สำหรับ password ของ root user นอกจากนี้ยังใช้ Volume ชื่อdb_dataเพื่อเก็บข้อมูลฐานข้อมูล
นอกจากนี้ เรายังมีการกำหนด Volume ชื่อ db_data ซึ่งจะถูกใช้เพื่อเก็บข้อมูลฐานข้อมูลอย่างถาวร แม้ว่า Container จะถูกลบไปแล้วก็ตาม
การกำหนดค่า Services, Networks, และ Volumes ใน Docker Compose
เรามาเจาะลึกถึงวิธีการกำหนดค่า Services, Networks, และ Volumes ใน Docker Compose กัน:
Services
Service คือ Container ที่ถูกรันจาก image ที่กำหนด ใน docker-compose.yml เราสามารถกำหนดค่าต่างๆ ให้กับ Service ได้ เช่น:
- image: ระบุ image ที่จะใช้ในการสร้าง Container
- ports: กำหนด port mapping ระหว่าง host และ Container
- environment: กำหนด environment variables ที่ Container จะใช้
- depends_on: กำหนด dependencies ระหว่าง Services
- volumes: กำหนด Volume mount
- restart: กำหนดนโยบายการ restart Container (เช่น
always,on-failure) - build: ระบุ directory ที่มี Dockerfile เพื่อสร้าง image เอง
ตัวอย่างการใช้ build เพื่อสร้าง image จาก Dockerfile:
services:
web:
build: ./web # ระบุ directory ที่มี Dockerfile
ports:
- "80:80"
ในตัวอย่างนี้ Docker Compose จะสร้าง image จาก Dockerfile ที่อยู่ใน directory ./web
Networks
Docker Compose สร้าง Network โดยอัตโนมัติเพื่อให้ Services สามารถสื่อสารกันได้ แต่เราก็สามารถกำหนด Network เองได้เช่นกัน:
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- my_network # กำหนดให้ service "web" อยู่ใน network "my_network"
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
networks:
- my_network # กำหนดให้ service "db" อยู่ใน network "my_network"
networks:
my_network: # กำหนด network ชื่อ "my_network"
ในตัวอย่างนี้ เราได้สร้าง Network ชื่อ my_network และกำหนดให้ทั้ง Service web และ db อยู่ใน Network นี้ ทำให้ทั้งสอง Services สามารถสื่อสารกันได้โดยใช้ชื่อ Service เป็น hostname (เช่น db)
Volumes
Volumes ใช้สำหรับเก็บข้อมูลที่ Container สร้างขึ้นอย่างถาวร แม้ว่า Container จะถูกลบไปแล้วก็ตาม เราสามารถกำหนด Volumes ได้ดังนี้:
version: "3.9"
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db_data:/var/lib/mysql # Mount volume "db_data" ไปยัง /var/lib/mysql ใน container
volumes:
db_data: # กำหนด volume ชื่อ "db_data"
ในตัวอย่างนี้ เราได้สร้าง Volume ชื่อ db_data และ mount ไปยัง /var/lib/mysql ใน Container db ซึ่งเป็น directory ที่ MySQL ใช้เก็บข้อมูล
การรันและจัดการ Application ที่ประกอบด้วยหลาย Container ด้วย Docker Compose
เมื่อเรามีไฟล์ docker-compose.yml แล้ว เราสามารถใช้คำสั่ง docker-compose เพื่อจัดการแอปพลิเคชันของเราได้:
docker-compose up: สร้างและรัน Services ที่กำหนดในdocker-compose.ymldocker-compose down: หยุดและลบ Containers, Networks, และ Volumes ที่สร้างโดยdocker-compose updocker-compose ps: แสดงสถานะของ Services ที่กำหนดในdocker-compose.ymldocker-compose logs [service_name]: แสดง logs ของ Service ที่ระบุdocker-compose stop [service_name]: หยุด Service ที่ระบุdocker-compose start [service_name]: เริ่ม Service ที่หยุด
ตัวอย่างการรันแอปพลิเคชัน:
docker-compose up -d # รันใน detached mode (background)
ตัวอย่างการหยุดและลบแอปพลิเคชัน:
docker-compose down
ตัวอย่างการใช้งาน Docker Compose กับ Application ง่ายๆ เช่น Web server และ Database
เรามาสร้างแอปพลิเคชันง่ายๆ ที่ประกอบด้วย Web Server (Nginx) และ Database (MySQL) โดยใช้ Docker Compose:
- สร้าง directory สำหรับโปรเจกต์:
mkdir my-app - เข้าไปใน directory:
cd my-app - สร้างไฟล์
docker-compose.ymlและใส่ code ด้านล่าง:
version: "3.9"
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html # Mount directory "./html" ไปยัง /usr/share/nginx/html ใน container
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
- สร้าง directory
html:mkdir html - สร้างไฟล์
html/index.htmlและใส่ code ด้านล่าง:
<!DOCTYPE html>
<html>
<head>
<title>Hello Docker Compose!</title>
</head>
<body>
<h1>Hello Docker Compose!</h1>
<p>This is a simple web page served by Nginx using Docker Compose.</p>
</body>
</html>
- รันแอปพลิเคชัน:
docker-compose up -d - เปิด browser และเข้าไปที่
http://localhostคุณควรจะเห็นหน้าเว็บ "Hello Docker Compose!" - หยุดและลบแอปพลิเคชัน:
docker-compose down
ในตัวอย่างนี้ เราได้สร้างแอปพลิเคชันที่ประกอบด้วย Web Server (Nginx) และ Database (MySQL) โดยใช้ Docker Compose Web Server จะแสดงหน้าเว็บ index.html ที่เราสร้างขึ้น และ Database จะถูกใช้เพื่อเก็บข้อมูล (แม้ว่าในตัวอย่างนี้เราจะไม่ได้ใช้ Database อย่างจริงจัง)
Docker Compose เป็นเครื่องมือที่มีประโยชน์อย่างมากสำหรับการจัดการแอปพลิเคชันที่ประกอบด้วยหลาย Docker Container มันช่วยให้เราสามารถกำหนดค่าและจัดการ Container เหล่านี้ได้อย่างง่ายดาย ทำให้การพัฒนาและ deployment แอปพลิเคชันเป็นเรื่องที่ง่ายและรวดเร็วขึ้น ในบทความต่อไป เราจะมาเรียนรู้เกี่ยวกับ Docker Network เพื่อทำความเข้าใจวิธีการสื่อสารระหว่าง Container ที่ซับซ้อนยิ่งขึ้น