Hướng dẫn toàn tập về Docker Compose
Docker Compose là một công cụ thuộc hệ sinh thái của Docker giúp bạn định nghĩa và chạy nhiều container cùng lúc chỉ bằng một file cấu hình duy nhất (thường là docker-compose.yml). Bài viết này mình chia sẻ các bạn toàn tập về Docker Compose.

1. Danh sách Tính năng
Quản lý Multi-Container Application:
- Cấu trúc ngôn ngữ YAML – Định nghĩa các ứng dụng qua file YAML cực kỳ đơn giản
- Service Orchestration – Kết nối và quản trị nhiều containers
- Network Management – Tự động thiết lập kết nối cũng như cô lập mạng ảo
- Volume Management – Gắn chặt dữ liệu không để mất kể cả khi container khởi động lại
- Environment Variables – Gọi các biến thông qua file
.env - Dependency Management – Kiểm soát thứ tự bắt buộc App nào được quyền khởi động trước
- Scaling Support – Có thể tăng số lượng luồng container hoặc giảm xuống.
- Override Capabilities – Cấp riêng cấu hình nháp độc lập cho từng hệ thống Test
- Development Workflows – Một công cụ hoàn hảo dành cho môi trường các Dev giả lập phát triển code
- Production Deployment – Hoàn toàn phù hợp để triển khai chạy ở máy chủ production nếu được cấu hình đúng chuẩn an toàn.
2. Cài đặt
2.1 Cài đặt trên máy Ubuntu
Cài đặt phiên bản Docker Compose v2 (mới nhất)
# Cập nhật các gói cần thiết
sudo apt update
# Cài gói công cụ Docker Compose plugin (khuyến khích)
sudo apt install docker-compose-plugin
# Kiểm tra sau khi cài
docker compose version
Bản thay thế: Cài đặt Docker Compose v1 (bản cũ)
# Tải và chạy phiên bản gạch ngang legacy
sudo apt install docker-compose
# Kiểm thử check lại kết quả
docker-compose --version
2.2 Cài đặt thủ công
Tải trực tiếp bản Releases từ nguồn
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
3. Cấu Trúc Cơ Bản
3.1 File Docker Compose
Cấu trúc tệp tiêu chuẩn docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
container_name: my-nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
networks:
- webnet
database:
image: mysql:8.0
container_name: my-mysql
environment:
MYSQL_ROOT_PASSWORD: secretpassword
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
volumes:
- mysql_data:/var/lib/mysql
restart: unless-stopped
networks:
- webnet
volumes:
mysql_data:
networks:
webnet:
driver: bridge
3.2 Các biến cấu hình
Phương pháp tách file .env riêng
# Tao và viết vào file .env mới
nano .env
# Các biến Database
MYSQL_ROOT_PASSWORD=your-secure-password
MYSQL_DATABASE=myapp
MYSQL_USER=appuser
MYSQL_PASSWORD=another-secure-password
# Các biến cấp ứng dụng chạy
APP_ENV=production
APP_DEBUG=false
Gọi tên viến tại tệp tin chính Compose
version: '3.8'
services:
database:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
4. Cấu hình nâng cao
4.1 Khởi động đồng thời nhiều ứng dụng
Xem ví dụ mô hình Full stack hoàn chỉnh bên dưới
version: '3.8'
services:
# Lớp giao tiếp trước Frontend Web Server
nginx:
image: nginx:alpine
container_name: app-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- web_content:/var/www/html
depends_on:
- app
restart: unless-stopped
networks:
- frontend
- backend
# Phần application server
app:
build:
context: ./app
dockerfile: Dockerfile
container_name: app-server
environment:
- DATABASE_URL=mysql://appuser:${MYSQL_PASSWORD}@database:3306/myapp
- REDIS_URL=redis://redis:6379
volumes:
- web_content:/var/www/html
- ./app/config:/app/config:ro
depends_on:
- database
- redis
restart: unless-stopped
networks:
- backend
# Phần Database
database:
image: mysql:8.0
container_name: app-mysql
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
- ./mysql/init:/docker-entrypoint-initdb.d:ro
restart: unless-stopped
networks:
- backend
# Phần lưu trữ cache Redis
redis:
image: redis:alpine
container_name: app-redis
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- backend
volumes:
mysql_data:
redis_data:
web_content:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
4.3 Ghi đè file
Bạn có thể ghi đè biến riêng ở môi trường Local như sau
# File ghi đè: docker-compose.override.yml
version: '3.8'
services:
app:
environment:
- APP_ENV=development
- APP_DEBUG=true
volumes:
- ./app/src:/app/src
ports:
- "3000:3000"
database:
ports:
- "3306:3306"
File ghi đè cho việc Build chạy chính thức trên Server Live
# File ghi đè: docker-compose.prod.yml
version: '3.8'
services:
app:
deploy:
replicas: 3
resources:
limits:
memory: 512M
reservations:
memory: 256M
nginx:
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
5. Những câu lệnh cần ghi nhớ
5.1 Câu lệnh thực hiện tác vụ cơ bản
Quản lí vòng đời (Lifecycle Management)
# Khởi chạy một ứng dụng và thoát
docker compose up -d
# Kiểm tra xem service có ứng dụng hoạt động không
docker compose ps
# Xem lỗi/cảnh báo logs
docker compose logs
# Xem chi tiết logs realtime
docker compose logs -f
# Tạm thời Stop
docker compose stop
# Xóa và ngừng ứng dụng
docker compose down
# Xóa và ngừng ứng dụng kèm volume dữ liệu cũ
docker compose down -v
5.2 Các lệnh khác
Các lệnh dùng build & test
# Build đóng gói Images
docker compose build
# Kéo image về local
docker compose pull
# Start lại 1 ứng dụng
docker compose restart nginx
# Scale App ra 3 bản sao
docker compose up -d --scale app=3
# Vào một container
docker compose exec app bash
# Theo dõi tiến trình trên ram container
docker compose top
5.3 Lệnh troubleshooting
Các lệnh Debugging và Maintenance
# Chuẩn hóa file cú pháp kiểm định xem có lỗi không
docker compose config
# Kiểm tra service đang chạy
docker compose ps --services
# Xem RAM CPU (resource usage)
docker stats $(docker compose ps -q)
# Dọn Rác unused images
docker image prune
# Dọn rác volume
docker volume prune
6 Networking
6.2 Custom networks
Cấu hình Network Configuration cơ bản
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
app:
image: myapp
networks:
- frontend
- backend
database:
image: mysql
networks:
- backend
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
backend:
driver: bridge
internal: true
6.2 External Networks
Thiết lập phần networks giao tiếp với bên ngoài
version: '3.8'
services:
app:
image: myapp
networks:
- existing-network
networks:
existing-network:
external: true
7. Quản lí volumes
7.1 Tên volumes
Lưu data dùng Persistent Data Storage. Lưu tại folder gốc
version: '3.8'
services:
database:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backups:/backups
volumes:
postgres_data:
driver: local
driver_opts:
type: none
o: bind
device: /opt/docker/postgres
7.2 Phương pháp dùng bind mounts
Gắn ánh xạ Host Directory Mapping
version: '3.8'
services:
web:
image: nginx
volumes:
- type: bind
source: ./html
target: /usr/share/nginx/html
read_only: true
- type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
8. Phương pháp tối ưu nhất
Để bảo mật ứng dụng khi triển khai lên production. Bạn có thể tham khảo vài phương pháp bên dưới.
Tham khảo 1
version: '3.8'
services:
app:
image: myapp
user: "1000:1000"
read_only: true
tmpfs:
- /tmp
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
Tham khảo 2
version: '3.8'
services:
app:
image: myapp
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
9 Lời kết
Hi vọng qua bài này chúng ta có cái nhìn toàn tập về Docker Compose.