はじめに
CodePipelineのCodeBuildでの工程で、以下のエラーがたびたび発生しました。
toomanyrequests: You have reached your pull rate limit.
You may increase the limit by authenticating and upgrading:
https://www.docker.com/increase-rate-limit
DockerHubでは、匿名ユーザによるDockerHubからのコンテナイメージの呼び出し回数は、以下のような制限があります。
| 設定 | 意味 |
|---|---|
| 無料プラン(匿名ユーザー) | 100 pull/6時間あたり |
| 無料プラン(認証ユーザー) | 200 pull/6時間あたり |
| Pro | 無制限 |
| Team | 無制限 |
匿名ユーザーは、 IP アドレス単位で回数制限がかかるため、CodeBuildからの実行では自分が行った回数に関係なく制限に引っかかってしまうため、今回のようなエラーが出ていました。
そのため、今回は、無料プランの認証ユーザーとして、DockerHubにログインすることで、Buildのエラーになる確率をぐっと減らしたいと思います。
実際の本番環境ですと、有料プランに入るべきですが。。
前提条件
- CodepipelineでCodeBuild作成済み
作成方法はこちらの記事を参考にしてください。
CodePipelineを利用したECSのローリングデプロイ
流れ
①DockerHubのアカウント作成
②SystemsManagerでパラメータ作成
③サービスロールにポリシーをアタッチ
④buildspec.ymlの修正
⑤CodeBuildに環境変数を追加
DockerHubのアカウント作成
こちらのリンクからDockerHubアカウントを作成します。
アカウント作成に必要なDockerID・メールアドレス・パスワードを設定します。
DockerIDは、ユーザ名に近い使い方をします。

Codebuildで必要な値は、以下の2つです。
DockerIDアカウントパスワード
Docker Hub で Two-Factor Authentication(MFA)を有効にしている場合は、アカウントパスワード の代わりにアクセストークンを使用する必要があります。
アカウント設定に移動し、左タブSecurityをクリックし、New Access Tokensをクリックすると、アクセストークンが発行されます。

-
Access Token Description:ForCodeBuild -
Access permissions:Read, Write, Delete
Generateをクリックします。
SystemsManagerでパラメータ作成
以下の2つのパラメータを作成します。
DockerIDアカウントパスワード
SystemsManagerのマイパラメータに遷移し、パラメータの作成をクリックします。
パラメータを作成をクリックします。
同様にアカウントパスワード用も作成します。
-
名前:DOCKER_HUB_PASSWORD(何でも可) -
利用枠:標準 -
タイプ:安全な文字列 -
KMSキーソース:現在のアカウント -
KMSキーID:alias/aws/ssm -
値:Dockerアカウントのパスワードの値を入れます
サービスロールにポリシーをアタッチ
ビルドプロジェクトがSystems Managerのパラメータストアに保存されているパラメータを参照する場合、ビルドプロジェクトのサービスロールにssm:GetParametersアクションを許可する必要があります。
サービスロールは、CodeBuildコンソールのビルドプロジェクト→編集→環境から確認できます。
IAMのコンソールからサービスロールに遷移し、ポリシー名をクリックします。
さらにアクセス許可を追加するをクリックします。
以下の通りに、GetParametersを追加します。
buildspec.ymlの修正
CodePipelineでのBuildステージにおいて、DockerHubにログインし、認証ユーザーとしてイメージをpullするために、以下の一行をbuildspec.ymlに加えます。
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
version: 0.2
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
+ - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
build:
commands:
CodeBuildに環境変数を追加
Buildステージに環境変数を追加する方法は、以下の2つあります。
・buildspec.ymlに環境変数を追加する。
・CodePipelineのCodeBuildのステージに環境変数を追加する。
方法①buildspec.ymlに環境変数を追加する
以下のenvにパラメータを入れます。
version: 0.2
+ env:
+ parameter-store:
+ DOCKER_USER: DOCKER_HUB_ID
+ DOCKER_PASSWORD: DOCKER_HUB_PASSWORD
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
commands:
DOCKER_HUB_IDとDOCKER_HUB_PASSWORDは、パラメータストアで設定した名前になります。
方法②CodePipelineのCodeBuildのステージに環境変数を追加する
こちらの方法で行う場合、DOCKER_HUB_IDとDOCKER_HUB_PASSWORDの名前は、/CodeBuild/を頭につける必要があるため、あまりおすすめしません。
パラメータストアで作り直します。
DOCKER_HUB_ID → /CodeBuild/DOCKER_HUB_ID
DOCKER_HUB_PASSWORD → /CodeBuild/DOCKER_HUB_PASSWORD
環境変数の名前と値、タイプを以下のように追加します。
・DOCKER_USER:/CodeBuild/DOCKER_HUB_ID:パラメータ
・DOCKER_PASSWORD:/CodeBuild/DOCKER_HUB_PASSWORD:パラメータ
これによって、環境変数に設定した値には、パラメーターストアで設定した値が入ります。
これで、ビルドで失敗する確率がぐっと下がりました。
ビルド時のエラー集①
サービスロールにSystems Managerのssm:GetParameters がアタッチされていない場合に発生します。
Phase context status code: Decrypted Variables Error Message: AccessDeniedException: User: arn:aws:sts::xxxxxxxxx:assumed-role/codebuild-wordpress-service-role/AWSCodeBuild-1b8f0170-e973-4b24-8b03-f61cfb95a403 is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-northeast-1:xxxxxxxxxx:parameter/
ビルド時のエラー集②
環境変数の値が間違っています。
Phase context status code: Decrypted Variables Error Message: parameter does not exist:
ビルド時のエラー集③
CodeBuildに環境変数が設定されていない場合に発生します。
Error: Cannot perform an interactive login from a non TTY device
ビルド時のエラー集④
パラメータに設定しているユーザ名かパスワードが間違っています。
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
#参考
ビルドプロジェクトの設定の変更 (コンソール)
CodeBuildのIPガチャを回避
Docker Hub の Rate Limitに引っかかったのでdocker loginで対策

