This content originally appeared on DEV Community and was authored by duytruong09
1. Volumes: Lưu Trữ Dữ Liệu Bền Vững Trong Docker
1.1. Bind Mounts vs. Named Volumes
-
Bind Mounts:
- Khái niệm: Cho phép bạn mount một thư mục hoặc file từ host machine (máy tính của bạn) vào bên trong container.
- Ưu điểm: Rất tiện lợi cho việc phát triển cục bộ. Khi bạn chỉnh sửa mã nguồn trên máy tính, thay đổi sẽ được phản ánh ngay lập tức trong container mà không cần build lại image.
- Nhược điểm: Phụ thuộc vào cấu trúc thư mục của host. Kém portable hơn vì đường dẫn trên host có thể khác nhau giữa các môi trường.
-
Ví dụ:
services: web: image: nginx volumes: - ./nginx.conf:/etc/nginx/nginx.conf # Mount file cấu hình - ./src:/usr/share/nginx/html # Mount thư mục mã nguồn
-
Named Volumes:
- Khái niệm: Là các khu vực lưu trữ được Docker quản lý hoàn toàn. Bạn chỉ cần đặt tên cho chúng và Docker sẽ tự động tạo/quản lý vị trí lưu trữ trên host.
- Ưu điểm: Dễ dàng sao lưu, di chuyển và chia sẻ giữa các container. Không phụ thuộc vào cấu trúc thư mục của host, tăng tính portable. Lý tưởng cho dữ liệu database hoặc dữ liệu cần tồn tại độc lập với container.
- Nhược điểm: Khó truy cập trực tiếp từ host để chỉnh sửa nội dung (phải thông qua container hoặc Docker CLI).
-
Ví dụ:
services: db: image: postgres volumes: - db_data:/var/lib/postgresql/data # Sử dụng named volume 'db_data' volumes: db_data: # Khai báo named volume
1.2. Port Mapping (-p)
Port mapping (hay port forwarding) là cách để expose các cổng của container ra bên ngoài host machine, cho phép bạn truy cập ứng dụng đang chạy trong container từ trình duyệt hoặc các ứng dụng khác trên host.
-
Cú pháp:
-p HOST_PORT:CONTAINER_PORT
-
Ví dụ:
ports: - "8080:80"
nghĩa là cổng 80 của container sẽ được ánh xạ tới cổng 8080 trên host của bạn. Khi bạn truy cậplocalhost:8080
, yêu cầu sẽ được chuyển đến cổng 80 của container.
2. Docker Networks: Giao Tiếp Giữa Các Container
Các container cần giao tiếp với nhau. Docker cung cấp cơ chế network để các container có thể “nói chuyện” với nhau một cách an toàn và hiệu quả.
2.1. Cách Các Container Giao Tiếp
Khi bạn sử dụng Docker Compose, một mạng bridge mặc định sẽ được tạo cho toàn bộ ứng dụng của bạn. Tất cả các service trong file docker-compose.yml
sẽ tự động được kết nối vào mạng này.
-
Service Discovery: Các container có thể giao tiếp với nhau bằng cách sử dụng tên dịch vụ (service name) làm hostname. Ví dụ, nếu bạn có một service tên là
db
, serviceweb
có thể kết nối tới database bằng hostnamedb
.
services: web: image: myapp-web environment: DB_HOST: db # "db" là tên của service database db: image: postgres
2.2. Docker Networks
```
services:
web:
image: nginx
ports:
- "80:80"
networks:
- frontend_network # Kết nối vào mạng frontend
api:
image: myapp-api
networks:
- frontend_network
- backend_network # Kết nối vào cả frontend và backend
db:
image: postgres
networks:
- backend_network # Chỉ kết nối vào mạng backend
networks:
frontend_network:
driver: bridge # Có thể dùng driver khác nếu cần (ví dụ: overlay cho Swarm)
backend_network:
driver: bridge
```
Trong ví dụ này, `web` và `api` có thể giao tiếp với nhau qua `frontend_network`. `api` và `db` có thể giao tiếp qua `backend_network`. `web` và `db` không thể giao tiếp trực tiếp trừ khi cả hai cùng nằm trên một mạng chung.
3. Docker Compose: Ứng Dụng Đa Container Trong Một File
Docker Compose là công cụ giúp bạn định nghĩa và chạy các ứng dụng Docker đa container. Thay vì chạy từng container một bằng lệnh docker run
, bạn có thể dùng một file YAML để mô tả toàn bộ kiến trúc ứng dụng của mình.
3.1. Khái Niệm Multi-Container Apps
Một ứng dụng thực tế thường không chỉ có một container. Nó có thể bao gồm:
- Một web server (Nginx, Apache)
- Một backend API (Node.js, Python Flask, Java Spring Boot)
- Một database (PostgreSQL, MySQL, MongoDB)
- Một message queue (RabbitMQ, Kafka)
- Một cache (Redis)
Docker Compose giúp bạn quản lý tất cả các thành phần này một cách mạch lạc.
File docker-compose.yml
là nơi bạn định nghĩa cấu hình cho ứng dụng của mình. Nó thường bao gồm các phần chính:
-
services
:- Mỗi entry dưới
services
đại diện cho một container trong ứng dụng của bạn. - Bạn định nghĩa
image
(tên image Docker),build
(đường dẫn đến Dockerfile để build custom image),ports
,volumes
,environment
(biến môi trường),networks
, v.v. -
Ví dụ:
version: '3.8' # Phiên bản của Docker Compose file services: web: build: ./web # Build image từ Dockerfile trong thư mục ./web ports: - "80:80" volumes: - ./web/src:/app environment: NODE_ENV: development depends_on: - api # Đảm bảo service 'api' khởi động trước networks: - app_network api: image: my_api_image:latest # Sử dụng image đã có ports: - "3000:3000" environment: DB_HOST: db networks: - app_network - db_network db: image: postgres:13 volumes: - db_data:/var/lib/postgresql/data environment: POSTGRES_DB: mydb POSTGRES_USER: user POSTGRES_PASSWORD: password networks: - db_network
- Mỗi entry dưới
-
volumes
:- Khai báo các named volumes để lưu trữ dữ liệu bền vững.
-
Ví dụ:
volumes: db_data: # Định nghĩa named volume tên là 'db_data'
-
networks
:- Khai báo các mạng tùy chỉnh để kiểm soát giao tiếp giữa các service.
-
Ví dụ:
networks: app_network: db_network:
3.2. Các Lệnh Docker Compose Cơ Bản
-
docker compose up
: Xây dựng (nếu cần), tạo và khởi chạy tất cả các service được định nghĩa trongdocker-compose.yml
.-
docker compose up -d
: Chạy các service trong chế độ nền (detached mode)
-
-
docker compose down
: Dừng và xóa tất cả các container, network và volume được tạo bởiup
.-
docker compose down --volumes
: Dừng, xóa container, network và cả các named volumes. Hãy cẩn thận khi sử dụng, vì nó sẽ xóa dữ liệu.
-
-
docker compose logs [service_name]
: Hiển thị log output từ các service.-
docker compose logs -f
: Theo dõi log theo thời gian thực (follow).
-
docker compose build [service_name]
: Xây dựng hoặc tái xây dựng image cho một hoặc tất cả các service được định nghĩa bằngbuild
trong filedocker-compose.yml
This content originally appeared on DEV Community and was authored by duytruong09