Thông báo lỗi
Bạn vừa hoàn tất việc build và chạy lệnh docker push, nhưng lại gặp phải một thông báo lỗi khó chịu. Quá trình dừng lại ngay lập tức với nội dung:
Error response from daemon: Get "https://registry.example.com/v2/": unauthorized: authentication required
Nguyên nhân gốc rễ
Nói một cách đơn giản, registry không nhận diện được bạn. Mặc dù có vẻ giống như một lỗi phần mềm, nhưng đây thường là do cấu hình chưa đúng. Các nguyên nhân phổ biến nhất bao gồm:
- Phiên làm việc hết hạn: Token đăng nhập của bạn đã quá hạn. Ví dụ, token AWS ECR sẽ hết hạn sau chính xác 12 giờ.
- Thiếu Hostname: Bạn đang đẩy một tag nội bộ (như
my-app:v1) thay vì một đường dẫn registry đầy đủ. - Thông tin xác thực cũ: Docker credential helper đang lưu giữ mật khẩu cũ hoặc Personal Access Token (PAT) đã lỗi thời.
- Hạn chế RBAC: Bạn đã đăng nhập, nhưng tài khoản thiếu quyền "Push" hoặc "Maintainer" cho repository cụ thể đó.
Cách khắc phục
1. Buộc đăng nhập lại
Đừng mặc định rằng phiên làm việc trước đó của bạn vẫn còn hiệu lực. Xác thực lại là cách nhanh nhất để cập nhật tệp config.json cục bộ. Chạy lệnh đăng nhập cho registry cụ thể của bạn:
docker login registry.example.com
Nếu bạn đang sử dụng nhà cung cấp đám mây, hãy dùng CLI của họ để xử lý các bước phức tạp. Đối với AWS, hãy chạy aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.us-east-1.amazonaws.com. Đối với GitLab, hãy đảm bảo bạn đang sử dụng Deploy Token hoặc PAT với phạm vi (scope) write_registry.
2. Sửa lại Image Tag
Docker sử dụng tên image để xác định đích đến. Nếu image của bạn chỉ có tên là web-server:latest, Docker sẽ mặc định đẩy lên Docker Hub. Để đẩy lên một registry riêng tư, hostname phải là một phần của tag.
Cách làm sai:
docker push web-server:v1
Cách làm đúng:
# Đầu tiên, gắn tag chính xác
docker tag web-server:v1 registry.example.com/my-team/web-server:v1
# Sau đó, đẩy tag cụ thể lên
docker push registry.example.com/my-team/web-server:v1
3. Kiểm tra cấu hình Docker
Token xác thực được lưu tại ~/.docker/config.json trên Linux hoặc %USERPROFILE%\.docker\config.json trên Windows. Hãy mở tệp này để xem registry của bạn có thực sự được liệt kê hay không.
cat ~/.docker/config.json
Một tệp cấu hình chuẩn sẽ trông như thế này:
{
"auths": {
"registry.example.com": {
"auth": "ZXhhbXBsZTpwYXNzd29yZA=="
}
}
}
Nếu phần auths trống mặc dù có thông báo "Login Succeeded", có thể credential helper của bạn đang chặn dữ liệu. Hãy thử xóa dòng credsStore khỏi tệp để buộc Docker ghi thông tin xác thực cục bộ nhằm mục đích kiểm tra.
4. Xác minh quyền hạn trên Repository
Đôi khi việc xác thực thành công, nhưng việc phân quyền lại thất bại. Trên các nền tảng như Harbor hoặc GitLab, bạn có thể chỉ có quyền "Guest" hoặc "Reporter", cho phép pull nhưng chặn push. Hãy yêu cầu quản trị viên xác minh rằng tài khoản của bạn có vai trò Developer hoặc Maintainer. Nếu không có các quyền này, registry sẽ từ chối lệnh push của bạn ngay cả khi mật khẩu đúng.
Kiểm tra giải pháp
Kiểm tra xem Docker có nhận diện thông tin đăng nhập của bạn không bằng cách chạy docker info | grep -i "registry". Để xác minh việc đẩy image mà không cần gửi một image dung lượng lớn, hãy thử đẩy một lớp Alpine nhỏ 5MB trước:
docker pull alpine:latest
docker tag alpine:latest registry.example.com/my-project/test:latest
docker push registry.example.com/my-project/test:latest
Nếu thanh tiến trình xuất hiện, bạn đã khắc phục thành công.
Mẹo chuyên nghiệp cho CI/CD
Tránh sử dụng mật khẩu cá nhân trong các pipeline tự động. Thay vào đó, hãy sử dụng Service Accounts hoặc Deploy Tokens với phạm vi giới hạn. Để tăng cường bảo mật, tôi khuyên bạn nên sử dụng mật khẩu mạnh gồm 32 ký tự được tạo ngẫu nhiên cho các tài khoản này. Tôi thường sử dụng Trình tạo mật khẩu này vì nó chạy cục bộ trong trình duyệt và đảm bảo bao gồm các ký tự đặc biệt để đáp ứng các yêu cầu khắt khe của registry.
Cuối cùng, nếu bạn đang ở sau tường lửa của doanh nghiệp, hãy kiểm tra cài đặt HTTP_PROXY. Một proxy cấu hình sai có thể chặn quá trình bắt tay xác thực (authentication handshake), dẫn đến thông báo sai về lỗi "unauthorized".

