エラーメッセージ
ビルドが完了し、docker pushを実行したものの、無機質なエラーメッセージに阻まれてしまうことがあります。プロセスは直ちに停止し、以下のメッセージが表示されます。
Error response from daemon: Get "https://registry.example.com/v2/": unauthorized: authentication required
主な原因
簡単に言えば、レジストリがあなたを認識できていない状態です。バグのように感じるかもしれませんが、通常は設定の不備が原因です。よくある原因は以下の通りです。
- セッションの期限切れ: ログイントークンの有効期限が切れています。例えば、AWS ECRのトークンはちょうど12時間で期限切れになります。
- ホスト名の欠落: 完全修飾されたレジストリパスではなく、ローカルタグ(
my-app:v1など)をプッシュしようとしています。 - 古い認証情報: Dockerの認証ヘルパーが、古いパスワードや期限切れのパーソナルアクセストークン(PAT)を保持しています。
- RBAC(ロールベースアクセス制御)の制限: ログインはできていても、その特定のリポジトリに対して「Push」や「Maintainer」の権限が不足しています。
解決方法
1. 再ログインを強制する
以前のセッションがまだ有効であると決めつけないでください。再認証を行うのが、ローカルのconfig.jsonを更新する最も早い方法です。対象のレジストリに対してログインコマンドを実行します。
docker login registry.example.com
クラウドプロバイダーを使用している場合は、各社のCLIを使用して認証を行います。AWSの場合は、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を実行します。GitLabの場合は、デプロイトークンまたはwrite_registryスコープを持つPATを使用しているか確認してください。
2. イメージタグを修正する
Dockerはイメージ名を使用して送信先を決定します。イメージ名が単にweb-server:latestの場合、DockerはデフォルトでDocker Hubにプッシュしようとします。プライベートレジストリを対象にするには、ホスト名をタグの一部に含める必要があります。
間違った方法:
docker push web-server:v1
正しい方法:
# まず、正しくタグ付けします
docker tag web-server:v1 registry.example.com/my-team/web-server:v1
# 次に、特定のタグをプッシュします
docker push registry.example.com/my-team/web-server:v1
3. Docker設定を確認する
認証トークンは、Linuxでは~/.docker/config.json、Windowsでは%USERPROFILE%\.docker\config.jsonに保存されます。このファイルを開き、対象のレジストリがリストされているか確認してください。
cat ~/.docker/config.json
正常な設定ファイルは以下のようになります。
{
"auths": {
"registry.example.com": {
"auth": "ZXhhbXBsZTpwYXNzd29yZA=="
}
}
}
「Login Succeeded」と表示されるのにauthsセクションが空の場合、認証ヘルパーがデータをインターセプトしている可能性があります。テストとして、ファイルからcredsStoreの行を削除し、Dockerに認証情報をローカルに書き込ませてみてください。
4. リポジトリの権限を確認する
認証(Authentication)には成功しても、認可(Authorization)に失敗することがあります。HarborやGitLabなどのプラットフォームでは、「Guest」や「Reporter」権限の場合、プルは可能ですがプッシュはブロックされます。管理者に問い合わせて、ユーザーにDeveloperまたはMaintainerロールが付与されているか確認してください。これらの権限がないと、パスワードが正しくてもレジストリはプッシュを拒否します。
解決策のテスト
docker info | grep -i "registry"を実行して、Dockerがログインを認識しているか確認します。大容量のイメージを送信せずにプッシュを検証するには、まず5MB程度の小さなAlpineレイヤーをプッシュしてみてください。
docker pull alpine:latest
docker tag alpine:latest registry.example.com/my-project/test:latest
docker push registry.example.com/my-project/test:latest
プログレスバーが表示されれば、正常に動作しています。
CI/CDに向けたプロのヒント
自動化されたパイプラインでは、個人のパスワードを使用しないでください。代わりに、スコープを限定したサービスアカウントやデプロイトークンを使用します。セキュリティを強化するために、これらのアカウントには生成された32文字の強力なパスワードを使用することをお勧めします。私はよくこのパスワードジェネレーターを使用しています。ブラウザ上でローカルに動作し、厳格なレジストリ要件を満たす記号を確実に含めることができるからです。
最後に、企業のファイアウォール内にいる場合は、HTTP_PROXYの設定を確認してください。プロキシの設定が誤っていると、認証のハンドシェイクがインターセプトされ、誤って「unauthorized」と報告されることがあります。

