Appearance
Buổi 3: Docker Containers
🎯 Mục tiêu
- Quản lý vòng đời container: run, stop, start, rm
- Sử dụng exec để chạy lệnh trong container đang chạy
- Đọc logs từ container
- Hiểu port mapping và environment variables
- Biết cách attach/detach container
1. Vòng đời Container
Các trạng thái của container
docker create
┌──────────────────────────────┐
│ ▼
┌─────────┐ docker start ┌──────────┐
│ Created │────────────────▶│ Running │
└─────────┘ └────┬─────┘
▲ │
│ docker stop │
│ │ │ docker kill
│ ▼ ▼
│ ┌──────────┐
│ docker restart │ Stopped │
│◀──────────────────────│ (Exited) │
│ └────┬─────┘
│ │
│ docker rm │
│ ▼
│ ┌──────────┐
└───────────────────────│ Removed │
└──────────┘2. Chạy Container (docker run)
Cú pháp cơ bản
bash
docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]Các cách chạy phổ biến
bash
# Chạy nền (detached)
$ docker run -d --name web nginx
# Chạy tương tác (interactive)
$ docker run -it --name my-ubuntu ubuntu bash
# Chạy và tự xóa khi dừng
$ docker run --rm nginx
# Chạy với port mapping
$ docker run -d -p 8080:80 --name web nginx
# Chạy với environment variables
$ docker run -d -e MYSQL_ROOT_PASSWORD=secret --name db mysql:8
# Chạy với giới hạn tài nguyên
$ docker run -d --memory=512m --cpus=1.0 --name app my-appBảng tổng hợp flags quan trọng
| Flag | Viết đầy đủ | Ý nghĩa |
|---|---|---|
-d | --detach | Chạy nền |
-it | --interactive --tty | Chạy tương tác |
-p | --publish | Map port host:container |
-e | --env | Đặt biến môi trường |
-v | --volume | Mount volume |
--name | --name | Đặt tên container |
--rm | --rm | Tự xóa khi dừng |
--restart | --restart | Chính sách restart |
-w | --workdir | Thư mục làm việc |
--network | --network | Chọn network |
3. Quản lý Container
Liệt kê containers
bash
# Container đang chạy
$ docker ps
# Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp web
# Tất cả containers (kể cả đã dừng)
$ docker ps -a
# Chỉ hiện ID
$ docker ps -q
# Format tùy chỉnh
$ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"Dừng và xóa container
bash
# Dừng container (gửi SIGTERM, chờ 10s, rồi SIGKILL)
$ docker stop web
# Dừng ngay lập tức (SIGKILL)
$ docker kill web
# Khởi động lại container đã dừng
$ docker start web
# Restart container
$ docker restart web
# Xóa container đã dừng
$ docker rm web
# Xóa container đang chạy (force)
$ docker rm -f web
# Xóa tất cả container đã dừng
$ docker container prunedocker stop vs docker kill
docker stop | docker kill | |
|---|---|---|
| Signal | SIGTERM → SIGKILL | SIGKILL |
| Timeout | 10s mặc định | Ngay lập tức |
| Graceful | ✅ App có thể cleanup | ❌ Bị kill ngay |
| Dùng khi | Bình thường | Container bị treo |
4. Exec – Chạy lệnh trong container
Cú pháp
bash
docker exec [OPTIONS] CONTAINER COMMAND [ARGS...]Ví dụ thực tế
bash
# Mở shell trong container đang chạy
$ docker exec -it web bash
# Chạy lệnh đơn lẻ
$ docker exec web ls /usr/share/nginx/html
# Kiểm tra process
$ docker exec web ps aux
# Xem biến môi trường
$ docker exec web env
# Chạy lệnh với user khác
$ docker exec -u root web whoamidocker run vs docker exec
docker run | docker exec | |
|---|---|---|
| Tạo container | ✅ Tạo mới | ❌ Dùng container có sẵn |
| Trạng thái | Bất kỳ image | Container phải đang chạy |
| Use case | Khởi tạo | Debug, admin |
5. Logs – Xem nhật ký container
bash
# Xem toàn bộ logs
$ docker logs web
# Xem 20 dòng cuối
$ docker logs --tail 20 web
# Theo dõi logs real-time (như tail -f)
$ docker logs -f web
# Logs với timestamp
$ docker logs -t web
# Logs từ thời điểm cụ thể
$ docker logs --since 2h web
$ docker logs --since 2025-01-01T00:00:00 web
# Kết hợp: 50 dòng cuối + real-time
$ docker logs --tail 50 -f web6. Port Mapping
Cách mapping port
Host Machine Container
┌────────────────────┐ ┌─────────────────┐
│ │ │ │
│ localhost:8080 ───┼─────┼──▶ port 80 │
│ │ │ (nginx) │
│ localhost:3000 ───┼─────┼──▶ port 3000 │
│ │ │ (node app) │
│ localhost:5432 ───┼─────┼──▶ port 5432 │
│ │ │ (postgres) │
└────────────────────┘ └─────────────────┘Các cách map port
bash
# Map port cụ thể: host:container
$ docker run -d -p 8080:80 nginx
# Map nhiều port
$ docker run -d -p 8080:80 -p 8443:443 nginx
# Map port ngẫu nhiên
$ docker run -d -P nginx
# Docker tự chọn port host ngẫu nhiên
# Map chỉ localhost (không public)
$ docker run -d -p 127.0.0.1:8080:80 nginx
# Map UDP
$ docker run -d -p 5353:53/udp dns-server
# Xem port mapping
$ docker port web
80/tcp -> 0.0.0.0:80807. Environment Variables
Truyền biến môi trường vào container
bash
# Dùng -e flag
$ docker run -d \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=admin \
--name db mysql:8
# Dùng --env-file
$ docker run -d --env-file .env --name app my-app
# Kiểm tra biến môi trường
$ docker exec db env | grep MYSQL
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=mydb
MYSQL_USER=adminFile .env
env
# .env
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=mydb
MYSQL_USER=admin
MYSQL_PASSWORD=admin123
NODE_ENV=production8. Inspect & Stats
Xem chi tiết container
bash
# Toàn bộ thông tin container
$ docker inspect web
# Lấy IP address
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
# Xem mount points
$ docker inspect -f '{{json .Mounts}}' web | jq
# Xem trạng thái
$ docker inspect -f '{{.State.Status}}' webTheo dõi tài nguyên
bash
# Real-time stats tất cả containers
$ docker stats
# Stats cho container cụ thể
$ docker stats web
# Output:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
a1b2c3d4e5f6 web 0.05% 10.5MiB / 7.77GiB 0.13% 1.2kB / 648B 0B / 0B🏋️ Bài tập thực hành
Bài 1: Quản lý vòng đời container
- Chạy container nginx:
docker run -d --name web -p 8080:80 nginx - Kiểm tra:
docker ps - Dừng:
docker stop web - Kiểm tra:
docker ps -a - Khởi động lại:
docker start web - Xóa:
docker rm -f web
Bài 2: Exec và Logs
- Chạy nginx:
docker run -d --name web -p 8080:80 nginx - Mở shell:
docker exec -it web bash - Sửa trang web:
echo "Hello Docker!" > /usr/share/nginx/html/index.html - Thoát:
exit - Kiểm tra:
curl http://localhost:8080 - Xem logs:
docker logs web
Bài 3: Environment variables
- Chạy MySQL:
docker run -d -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=testdb --name db -p 3306:3306 mysql:8 - Kết nối:
docker exec -it db mysql -uroot -psecret - Kiểm tra database:
SHOW DATABASES; - Thoát:
exit
Bài 4: Multi-container
- Chạy 3 containers nginx trên các port khác nhau (8081, 8082, 8083)
- Xem stats:
docker stats - Dừng tất cả:
docker stop $(docker ps -q) - Xóa tất cả:
docker container prune