
Bài 5: Tối ưu Docker image bằng multi-stage và distroless
Tách builder khỏi runtime, kiểm tra tương thích libc và native module; giảm thành phần không cần thiết mà không cam kết tỷ lệ dung lượng chưa đo.

Tra trạng thái, đọc log, kiểm tra OOM và giới hạn tài nguyên; hiểu tác động của stop, restart và prune trước khi thao tác trên máy production.
Đối chiếu ngày 24/10/2026. Các nguồn ở cuối bài dùng để kiểm tra phiên bản và giới hạn. Ví dụ phải điều chỉnh theo hệ điều hành và ứng dụng; không phải báo cáo thử nghiệm trên mọi nền tảng.
Một container Linux vận hành qua các trạng thái xác định trong vòng đời của nó:

Cú pháp khởi chạy một container đầy đủ các cờ thiết yếu cho môi trường sản xuất:
docker run -d \
--name web_app \
--restart unless-stopped \
-p 127.0.0.1:8080:80 \
-e APP_ENV=production \
-e DB_HOST=10.0.1.15 \
nginx:alpine
Giải thích các cờ quan trọng:
-d (detached mode): Chạy container ở chế độ nền ngầm (background).--name: Đặt tên định danh tường minh cho container thay vì tên ngẫu nhiên.--restart unless-stopped: Tự động khởi động lại container nếu nó bị crash hoặc khi máy chủ Linux reboot (chỉ trừ trường hợp quản trị viên chủ động gõ lệnh stop).-p 127.0.0.1:8080:80: Ánh xạ cổng (Port mapping) từ cổng 8080 trên máy chủ Host vào cổng 80 của Container.-e: Truyền biến môi trường vào ứng dụng.Nếu không đặt giới hạn, một container bị rò rỉ bộ nhớ (memory leak) có thể tiêu thụ toàn bộ RAM của máy chủ, kích hoạt cơ chế Linux Out-of-Memory (OOM) Killer bắn hạ các tiến trình quan trọng khác của hệ thống.
docker run -d \
--name api_service \
--memory=2g \
--memory-swap=2g \
--cpus=1.5 \
my-api:v1
--memory=2g: Giới hạn tối đa 2GB RAM cho container.--memory-swap=2g: Đặt swap bằng memory để ngăn container sử dụng đĩa ảo swap khi hết RAM, không cho swap thêm khi kernel/cgroup hỗ trợ; ứng dụng vẫn có thể bị OOM kill.--cpus=1.5: Cho phép container sử dụng tối đa tương đương 1.5 nhân CPU.Các lệnh điều khiển trạng thái cơ bản hàng ngày:
# Gui stop signal; thoi gian cho phu thuoc OS va cau hinh stop timeout
docker stop web_app
# Khoi dong lai container da dung
docker start web_app
# Khoi dong lai tuc thi
docker restart web_app
# Tam dung toan bo tien trinh ma khong tat container
docker pause web_app
# Phuc hoi trang thai hoat dong sau khi pause
docker unpause web_app
Khi một container gặp sự cố phản hồi chậm hoặc lỗi, bạn sử dụng bộ công cụ điều tra sau:
# Dang nhap vao bash shell cua container
docker exec -it web_app sh
# Theo doi log lien tuc (giong tail -f) va gioi han 100 dong gan nhat kem thoi gian
docker logs -f --tail 100 -t web_app
# Trich xuat dia chi IP noi bo cua container bang tham so format
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web_app
docker top web_app
Bạn có thể truyền file vào hoặc trích xuất file log ra khỏi container mà không cần cài đặt SSH bên trong container:
# Sao chep file tu Host vao Container
docker cp ./config.local.json web_app:/app/config.json
# Sao chep thu muc dump tu Container ra Host
docker cp web_app:/var/log/nginx/access.log ./nginx-access.log
Sau một thời gian vận hành và deploy liên tục, các image cũ không dùng (dangling images), các container đã tắt và build cache sẽ làm phình to dung lượng ổ cứng máy chủ.
# Xem thong ke dung luong chi tiet cac thanh phan Docker
docker system df
# Don dep toan bo container da tat, mang khong dung va cac image khong duoc gan tag
docker system prune
# Don dep triet de toan dien (bao gom ca cac image khong duoc su dung boi bat ky container nao)
docker system prune -a
# Khong them --volumes khi chua xac minh du lieu va backup.
Tác động dọn dẹp: system prune xóa container đã dừng, network không dùng, image dangling và build cache đủ điều kiện. -a mở rộng sang image không được container sử dụng. CLI hiện hành dùng --volumes để thêm anonymous volume không dùng, không phải mọi named volume; volume prune là lệnh khác. “Không dùng” không có nghĩa dữ liệu không cần. Không dùng -f mặc định khi thao tác tay.
Stop gửi stop signal của container, thường là SIGTERM, rồi có thể SIGKILL khi hết timeout. Restart ngắt tiến trình; pause đóng băng tiến trình và có thể gây timeout ở client. Image không có shell không chạy được docker exec ... sh. Đọc State, RestartCount và log trước khi restart.
docker inspect --format '{{json .State}}' web_app
docker inspect --format '{{.RestartCount}}' web_app
docker stats --no-stream
docker system df -v
Đọc đúng tài liệu theo phiên bản. Địa chỉ, tên và đường dẫn trong ví dụ cần thay theo môi trường. Sơ đồ là khái niệm, không phải screenshot hay benchmark.
Lưu cấu hình và digest cũ, kiểm tra backup phục hồi được, xác nhận endpoint và log sau thay đổi. Rollback phải tính đến dữ liệu đã ghi mới; đổi image không tự phục hồi database.

Tách builder khỏi runtime, kiểm tra tương thích libc và native module; giảm thành phần không cần thiết mà không cam kết tỷ lệ dung lượng chưa đo.

Chọn nơi lưu dữ liệu, kiểm tra quyền UID/GID và phục hồi thử backup; phân biệt dữ liệu tạm với database cần sao lưu nhất quán theo ứng dụng.

Chọn driver theo phạm vi kết nối, dùng DNS mạng tự tạo và kiểm tra published port; phân biệt mạng Docker Swarm với mô hình CNI của Kubernetes.

Sắp xếp layer, chọn exec form, quản lý dependency và đưa bí mật vào build đúng cách; kèm mẫu Node.js để điều chỉnh theo ứng dụng thực tế.