Docker: khắc phục các vấn đề thường gặp
Container liên tục khởi động lại, cổng đang được sử dụng, hết dung lượng, “permission denied”, một dịch vụ không thấy hàng xóm của nó — bảng triệu chứng và quy trình khắc phục sự cố.
Cập nhật 23 tháng 8, 2026
Hầu hết các vấn đề về container đều xoay quanh một tá nguyên nhân phổ biến. Việc chẩn đoán luôn bắt đầu bằng ba lệnh giống nhau.
Ba lệnh đầu tiên
docker compose ps
docker compose logs --tail 100 <service>
docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}' <container>
Trạng thái, những dòng cuối của log và mã thoát trả lời phần lớn câu hỏi. Sau đó, hãy xử lý dựa theo triệu chứng.
Bảng triệu chứng
| Triệu chứng | Nguyên nhân có thể | Cần làm gì |
|---|---|---|
Liên tục Restarting | Ứng dụng crash khi khởi động | docker compose logs --tail 200, đọc lỗi đầu tiên, không phải lỗi cuối cùng |
Mã thoát 137, OOMKilled: true | Hết bộ nhớ | Tăng giới hạn hoặc tìm chỗ rò rỉ, xem giới hạn tài nguyên |
| Mã thoát 1 ngay sau khi khởi động | Lỗi trong cấu hình hoặc biến | docker compose config — kiểm tra các giá trị thay thế |
port is already allocated | Cổng bị tiến trình khác chiếm | sudo ss -tulpn | grep :<port> |
no space left on device | Hết dung lượng đĩa hoặc inode | df -h và df -i, xem dung lượng đĩa |
permission denied trên một tệp volume | UID không khớp | docker compose exec app id, sau đó chown hoặc PUID/PGID |
| Ứng dụng không thấy cơ sở dữ liệu | Khác mạng hoặc yêu cầu tới localhost | Xem Mạng Docker |
Cannot connect to the Docker daemon | Dịch vụ không chạy hoặc bạn thiếu quyền | sudo systemctl status docker, nhóm docker |
| Mọi thứ chậm, tải thấp | Nút thắt ở đĩa | iostat -x 2, xem tốc độ đĩa |
Container crash, nhưng log trống
Điều này xảy ra khi tiến trình chết trước khi kịp in ra bất cứ thứ gì. Hãy chạy image thủ công bằng shell thay vì lệnh chính:
docker run --rm -it --entrypoint sh <image>
Bên trong, chạy lệnh khởi động bằng tay — lỗi sẽ hiện ra trên màn hình. Nhân tiện, hãy kiểm tra xem các tệp cấu hình có nằm đúng chỗ không:
docker compose run --rm app cat /app/config.yaml
Thay đổi không được áp dụng
Kiểu kinh điển: bạn sửa một tệp, khởi động lại, và không có gì thay đổi.
docker compose config # does Compose see your changes
docker compose up -d --force-recreate app
docker compose exec app cat /etc/app/config.yaml
Thường có hai nguyên nhân: tệp được mount ở chỗ khác với chỗ bạn nghĩ, hoặc container thấy một bản sao đã lọt vào image trong lúc build.
Đừng khắc phục vấn đề bằng
docker system prune -a. Lệnh này xóa các image, network và bộ nhớ đệm build không dùng đến, và với cờ--volumesthì xóa cả volume chứa dữ liệu. Một volume trở thành “không dùng đến” ngay khi container của nó bị dừng. Hãy tìm ra nguyên nhân trước, rồi mới dọn dẹp.
Khi nào thì dọn dẹp sau cùng
docker system df
docker image prune
docker builder prune
docker container prune
docker system df sẽ cho biết chính xác thứ gì đang chiếm chỗ: image, bộ nhớ đệm build, volume hay log của container. Thường thì bộ nhớ đệm build là thủ phạm — xóa nó là an toàn.
Nếu máy không phản hồi
SSH không kết nối được, trang web không mở — thường là một container đã ăn hết bộ nhớ và hệ thống đã chuyển sang swap. Hãy đăng nhập qua console trong bảng điều khiển của máy. Với htop và btop, bạn cần chế độ “Screen”: kích thước cửa sổ không được truyền qua dòng văn bản, nên nó luôn là 80×24.
free -h
sudo dmesg -T | tail -40
sudo systemctl restart docker
Nếu hệ thống hoàn toàn không khởi động, hãy chuyển chế độ khởi động sang đĩa phục hồi SystemRescue trong tab “Access”: máy sẽ khởi động lại vào đó, đăng nhập root không cần mật khẩu, và đĩa sẽ hiện ra dưới dạng /dev/sda. Từ đó, bạn có thể mount phân vùng và lấy lại dữ liệu.
Những gì cần kiểm tra trước, không phải sau
- Đã đặt giới hạn kích thước log — xem log container.
- Đã đặt giới hạn bộ nhớ cho tất cả dịch vụ.
- Phiên bản image đã được ghim, và image cũ chưa bị xóa — xem cập nhật container.
- Đã có bản sao dữ liệu và đã được xác minh — xem diễn tập khôi phục.