이미지를 다 빌드해 놓고 docker push를 쳤더니 denied: requested access to the resource is denied나 unauthorized가 뜨면, 십중팔구 로그인·태그·레지스트리 주소 중 하나가 어긋난 것입니다. 푸시 실패는 거의 다 인증과 이미지 이름 규칙 문제이고, 에러 메시지로 어느 쪽인지 구분할 수 있습니다.
1단계 — 로그인과 태그를 확인한다
로컬 터미널
# 레지스트리에 로그인 (Harbor/ECR/GHCR 등)
docker login registry.example.com
# 이미지 이름을 "레지스트리/프로젝트/이름:태그"로 맞춘다
docker tag myapp:latest registry.example.com/team/myapp:1.0.0
docker push registry.example.com/team/myapp:1.0.0
푸시할 이미지 이름의 앞부분이 레지스트리 주소와 정확히 같아야 합니다. 이 prefix가 없으면 도커는 Docker Hub로 밀어 넣으려다 권한 오류를 냅니다.
원인별 해결
| 에러 메시지 | 원인 | 해결 |
|---|---|---|
denied: requested access ... denied | 태그 prefix가 레지스트리와 불일치 | docker tag로 registry/project/name에 맞춤 |
unauthorized: authentication required | 로그인 안 됨/토큰 만료 | docker login 재실행, 토큰 갱신 |
no basic auth credentials | 자격증명 미저장 | login 후 ~/.docker/config.json 확인 |
http: server gave HTTP response to HTTPS client | 레지스트리가 HTTP | insecure-registries에 등록(또는 TLS 적용) |
name unknown / project not found | 프로젝트·네임스페이스 없음 | 레지스트리에서 프로젝트 먼저 생성 |
ECR처럼 토큰이 짧게 만료되는 레지스트리는 push 직전 자격증명을 새로 받아야 합니다.
로컬 터미널
# 예: AWS ECR 로그인 토큰 발급
aws ecr get-login-password --region ap-northeast-2 \
| docker login --username AWS --password-stdin <acct>.dkr.ecr.ap-northeast-2.amazonaws.com
HTTP만 지원하는 사내 레지스트리라면 데몬에 명시해야 합니다.
로컬 터미널
# /etc/docker/daemon.json
{ "insecure-registries": ["registry.example.com:5000"] }
# 적용
sudo systemctl restart docker
체크리스트
로컬 터미널
cat ~/.docker/config.json # 로그인된 레지스트리 목록
docker image ls # 태그 prefix가 레지스트리와 맞는지
docker push <full-tag> # 실패 시 에러 메시지로 원인 분기
"로그인됐나 → 태그 prefix가 맞나 → HTTPS/프로젝트 문제인가" 순서로 보면 푸시 실패는 대부분 빠르게 풀립니다.
프라이빗 레지스트리를 직접 띄우고 태그·인증을 맞춰 push해 보는 실습은 도커 트랙에서 무료로 해볼 수 있습니다.