Cách khắc phục nhanh trong 5 giây
Bạn muốn làm biến mất cảnh báo đó ngay lập tức? Chỉ cần thêm flag --remove-orphans khi khởi chạy stack. Điều này yêu cầu Docker xóa bỏ bất kỳ container nào không còn được định nghĩa trong file YAML của bạn.
docker compose up -d --remove-orphans
Nếu bạn muốn dọn dẹp mà không cần khởi động các dịch vụ mới, hãy chạy lệnh down với cùng flag đó:
docker compose down --remove-orphans
Tại sao Docker lại đưa ra cảnh báo này?
Docker Compose theo dõi mọi container mà nó tạo ra bằng một "tên dự án" (project name). Cảnh báo này xuất hiện khi Docker tìm thấy một container thuộc dự án của bạn nhưng không còn được nhắc đến trong file docker-compose.yml. Ngay cả một container Alpine đang nhàn rỗi cũng có thể chiếm từ 5MB đến 10MB RAM, trong khi một cơ sở dữ liệu bị bỏ quên có thể ngốn hơn 200MB bộ nhớ mà không có lý do.
Hầu hết các lập trình viên gặp phải vấn đề này trong ba trường hợp cụ thể:
- Đổi tên dịch vụ: Bạn đã đổi
db:thànhpostgres-db:. Containerdbcũ giờ đây trở thành một "bóng ma" trong hệ thống của bạn. - Cắt giảm stack: Bạn đã xóa một dịch vụ như
redishoặcmailhogvì bạn đã chuyển sang một dịch vụ được quản lý (managed service) hoặc một công cụ khác. - Chuyển nhánh Git: Bạn chuyển từ một nhánh tính năng có kiến trúc 6 dịch vụ phức tạp về lại nhánh
main, vốn chỉ sử dụng 2 dịch vụ. 4 container dư thừa đó giờ đây là các orphan (container mồ côi).
Ba cách để giải quyết vấn đề
Cách 1: Sử dụng Flag tiêu chuẩn (Tốt nhất cho nhu cầu hàng ngày)
Thông thường, bạn chỉ muốn những container này biến mất. Chúng làm lộn xộn đầu ra của lệnh docker ps và thỉnh thoảng có thể chiếm giữ các cổng như 8080 hoặc 5432, ngăn cản các dịch vụ mới khởi động. Thêm flag vào lệnh up là quy trình làm việc hiệu quả nhất.
# Dọn dẹp và khởi động cùng lúc
docker compose up -d --remove-orphans
Bên dưới hệ thống, Docker xác định ID của các container không hợp lệ và thực hiện lệnh docker rm -f trên chúng trước khi tiếp tục với cấu hình hiện tại của bạn.
Cách 2: Kiểm tra trước khi xóa
Đừng xóa container ngay lập tức nếu bạn nghĩ rằng nó có thể chứa dữ liệu chưa được lưu. Nếu cảnh báo đề cập đến Found orphan containers (legacy_api_service), hãy kiểm tra bên trong trước.
# Kiểm tra xem container mồ côi có còn đang chạy không
docker ps -a --filter "name=legacy_api_service"
# Kiểm tra log để xem nó có đang thực hiện việc gì quan trọng không
docker logs legacy_api_service
# Xóa thủ công sau khi bạn đã chắc chắn
docker rm -f legacy_api_service
Cách tiếp cận thủ công này là "phao cứu sinh" nếu bạn vô tình xóa định nghĩa dịch vụ nhưng quên sao lưu cơ sở dữ liệu được lưu trữ trong lớp tạm thời (ephemeral layer) của container.
Cách 3: Khắc phục xung đột tên dự án
Theo mặc định, Docker sử dụng tên thư mục của bạn làm tên dự án. Nếu bạn có hai dự án khác nhau trong các thư mục đều có tên là /app, Docker sẽ nhầm lẫn các container của chúng. Nó có thể cố gắng "dọn dẹp" các container từ một dự án hoàn toàn khác.
Khắc phục điều này bằng cách thiết lập một tên dự án duy nhất trong file .env của bạn:
# file .env
COMPOSE_PROJECT_NAME=ecommerce_v2_staging
Ngoài ra, hãy sử dụng flag -p trong các lệnh CLI để giữ mọi thứ tách biệt:
docker compose -p unique_project_name up -d --remove-orphans
Xác nhận dọn dẹp thành công
Kiểm tra môi trường của bạn sau khi thực hiện sửa lỗi. Lệnh docker compose ps nhanh chóng sẽ hiển thị một danh sách sạch sẽ. Đầu ra bây giờ sẽ khớp chính xác với file docker-compose.yml của bạn. Nếu bạn chạy up một lần nữa, văn bản cảnh báo màu vàng khó chịu đó sẽ biến mất.
Mẹo nhỏ: Sử dụng Alias
Nếu bạn mệt mỏi với việc gõ thêm các ký tự, hãy thêm một alias vào file .zshrc hoặc .bashrc của bạn. Tôi sử dụng cách này để giữ cho không gian làm việc của mình sạch sẽ theo mặc định:
alias dcup='docker compose up -d --remove-orphans'
Lưu ý về dữ liệu ẩn
Việc xóa một container không tự động xóa các volume của nó. Nếu dịch vụ mồ côi của bạn có một volume được đặt tên để lưu trữ dữ liệu bền vững, dữ liệu đó vẫn đang chiếm dung lượng trên NVMe hoặc SSD của bạn. Để xem bạn đang lãng phí bao nhiêu dung lượng cho các volume không sử dụng (dangling volumes), hãy chạy:
docker system df
Nếu bạn muốn xóa sạch những volume không còn gắn kết đó, hãy sử dụng lệnh docker volume prune. Hãy cẩn thận—lệnh này mang tính hủy diệt và sẽ xóa bất kỳ volume nào hiện không được kết nối với một container đang hoạt động.

