Sửa nhanh: Tóm tắt
Lỗi này thường có nghĩa là Docker BuildKit không thể tìm thấy tệp hoặc thư mục được nhắc đến trong lệnh COPY hoặc ADD. Hầu hết các cách xử lý đều xoay quanh ba bước kiểm tra sau:
- Build Context (Ngữ cảnh Build): Bạn có đang chạy lệnh
docker buildtừ đúng thư mục không? Thông thường, đây phải là thư mục gốc của dự án. - Độ chính xác của đường dẫn: Đường dẫn nguồn trong
Dockerfilecủa bạn có tồn tại so với vị trí bạn bắt đầu build không? - .dockerignore: Tệp bạn đang cố sao chép có vô tình bị chặn bởi một quy tắc trong
.dockerignorekhông?
Tại sao lỗi này xảy ra
BuildKit tạo ra một cache key duy nhất cho mỗi layer. Khi gặp lệnh COPY, nó sẽ quét "build context" — đường dẫn thư mục mà bạn cung cấp ở cuối lệnh (ví dụ: .). Nếu bạn yêu cầu Docker COPY config.json . nhưng config.json không nằm trong thư mục context đó, BuildKit sẽ dừng ngay lập tức với lỗi "not found".
failed to solve: rpc error: code = Unknown desc = failed to compute cache key: "/config.json" not found: not found
Các nguyên nhân gốc rễ phổ biến
1. Sai Build Context
Lỗi context thường xảy ra nhất khi lập trình viên chạy build từ các thư mục con. Hãy tưởng tượng cấu trúc dự án như thế này:
my-project/
├── app/
│ ├── main.py
│ └── Dockerfile
└── requirements.txt
Nếu bạn cd app rồi chạy docker build -t my-app ., Docker chỉ nhìn thấy các tệp bên trong thư mục app/. Vì requirements.txt nằm ở thư mục cha, lệnh COPY requirements.txt . sẽ thất bại. Hãy sửa lỗi này bằng cách chạy build từ thư mục gốc:
# Chạy lệnh này từ thư mục my-project/
docker build -t my-app -f app/Dockerfile .
2. Quy tắc .dockerignore quá nghiêm ngặt
Tệp .dockerignore giúp ngăn các tệp lớn hoặc nhạy cảm gửi đến Docker daemon. Tuy nhiên, các ký tự đại diện quá rộng như *.json hoặc dist/ có thể chặn mất tệp bạn thực sự cần cho image. Nếu một tệp bị bỏ qua, BuildKit sẽ coi như nó không tồn tại.
Giải pháp: Kiểm tra lại các mẫu trong .dockerignore. Nếu bạn cần bao gồm một tệp cụ thể mà bình thường sẽ bị bỏ qua, hãy sử dụng tiền tố ngoại lệ !:
# Bỏ qua tất cả các tệp JSON...
*.json
# ...ngoại trừ tệp mà ứng dụng cần
!important-config.json
3. Xung đột phân biệt chữ hoa chữ thường
Hệ thống tệp của Windows và macOS thường không phân biệt chữ hoa chữ thường, nhưng Docker container chạy trên Linux, vốn phân biệt rất nghiêm ngặt. Một Dockerfile yêu cầu COPY app.js . sẽ thất bại nếu tệp thực tế tên là App.js. Mặc dù nó có thể hoạt động trên máy cục bộ khi phát triển, nhưng nó thường sẽ gây lỗi trong pipeline CI/CD chạy trên Linux.
Cách sửa: Kiểm tra lại tên tệp của bạn. Đảm bảo cách viết hoa/thường trong Dockerfile khớp chính xác với tệp trên ổ đĩa.
4. Dấu gạch chéo ở đầu đường dẫn nguồn
Đường dẫn nguồn trong COPY hoặc ADD phải tương đối với build context. Việc thêm dấu gạch chéo ở đầu sẽ thay đổi hành vi tìm kiếm và thường dẫn đến lỗi.
# SAI: Tìm kiếm /src trong thư mục gốc của hệ thống
COPY /src ./src
# ĐÚNG: Tìm kiếm src bên trong thư mục dự án của bạn
COPY src ./src
Kiểm tra lỗi (Debug) Context của bạn
Nếu bạn vẫn gặp bế tắc, hãy sử dụng một bản build "debug" để xem chính xác những gì Docker nhìn thấy. Việc này chỉ mất khoảng 30 giây và loại bỏ các phỏng đoán.
- Tạo một tệp
debug.Dockerfile:
FROM alpine
WORKDIR /check
COPY . .
CMD ls -R
- Chạy build và kiểm tra kết quả:
docker build -t build-debug -f debug.Dockerfile .
docker run --rm build-debug
Nếu ls -R không hiển thị tệp của bạn, có thể nó bị thiếu trong thư mục hoặc đã bị loại trừ bởi .dockerignore.
Các thực hành tốt nhất (Best Practices)
- Chuẩn hóa thư mục gốc: Luôn chạy build từ thư mục gốc của dự án để đảm bảo đường dẫn dễ đoán.
- Giới hạn kích thước context: Các thư mục context lớn (ví dụ trên 500MB) sẽ làm chậm quá trình build. Hãy sử dụng
.dockerignorechonode_modulesvà.git. - Sử dụng đường dẫn tương đối: Tránh sử dụng đường dẫn tuyệt đối hoặc dấu gạch chéo ở đầu cho các tệp nguồn.
- Khớp chữ hoa/thường: Nên đặt tên tệp toàn bộ bằng chữ thường để tránh các rắc rối khi làm việc trên nhiều nền tảng khác nhau.

