はじめに
ローカル環境を汚さずに手軽にDockerイメージをECRにプッシュしたい...
本記事では、AWS CLIの公式Dockerイメージを用いて、自作したDockerイメージをECRにプッシュする方法をご紹介します。
ECR(Elastic Container Registry)とは、AWSが提供しているDockerイメージの保存場所です。プライベートリポジトリ、パブリックリポジトリ、Dockerイメージの脆弱性スキャンを利用できます。
前提条件
- AWSアカウントを持っている
- Dockerがインストールされている
- Windowsの場合: Docker Desktop for Windows
- Macの場合: Docker Desktop for Mac
- 「Dockerコンテナ上でTerraformとAWS CLIを実行する方法」を参考にして、TerraformとAWS CLIを実行する環境が作成済みである(本記事では、このファイル構成を利用して作業を行います)
ECRリポジトリを作成
今回は、Terraformを利用してAWS上にECRのプライベートリポジトリを作成します。
リージョンは「ap-northeast-1」を利用します。
下記のTerraformファイルを作成します。
# プロバイダ
provider "aws" {
region = "ap-northeast-1"
}
# ECR
resource "aws_ecr_repository" "test-app" {
# リポジトリ名
name = "test-app"
# イメージタグの変更不可(上書き禁止)
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
# プッシュ時に脆弱性スキャンを実行
scan_on_push = true
}
}
下記のコマンドを実行します。
今回はサンプルとしてtest-app
のリポジトリ名でプライベートリポジトリを作成します。
> docker-compose up -d
> docker-compose exec terraform sh
# cd /terraform/ecr/
# terraform init (Terraformの初期化を行う。初回に1回だけ実行)
# terraform plan (AWSの変更内容を確認します。まだAWSには反映されません)
# terraform apply (実際にAWS上にtest-appのECRリポジトリを作成します。
「Enter a value:」と表示されるので「yes」を入力します)
# exit
AWSのECRリポジトリ画面から、test-app
のリポジトリが追加されていることを確認します。
DockerからECRリポジトリにログイン
下記のコマンドを実行して、DockerからECRリポジトリを使えるようにログインを行います。
下記のコマンドに含まれる「{AWSアカウントID}」を、現在利用しているAWSアカウントID(12桁の数値、AWSのアカウント設定画面に表示されているアカウントID)に書き換えてから実行します。
> docker-compose up -d
> docker-compose exec aws-cli aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com
(Login Succeededと表示されればログイン成功)
(実行例: docker-compose exec aws-cli aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com)
「aws ecr get-login-password --region ap-northeast-1」コマンドで、DockerからECRにログインする際に利用するパスワードを標準出力として返します。
「docker login --username AWS --password-stdin {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com」コマンドで、「ユーザ名: AWS」、「パスワード: 標準入力(aws ecr get-login-passwordの標準出力をパイプで渡す)」、「Dockerレジストリサーバ: {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com」を設定し、DockerからECRを利用できるようにします。
パスワードの有効期限は12時間となっています。
Dockerイメージをプッシュやプルした際に認証エラーになる場合は、もう一度、上記のログインを行います。
DockerイメージをECRリポジトリにプッシュ
下記の構成でテスト用Dockerファイルを作成します。「test app」が表示されるWebサーバとなっています。
FROM nginx:1.21.3-alpine
ADD ./index.html /usr/share/nginx/html
<html>
<body>
<h1>test app</h1>
version 1.0.0
</body>
</html>
下記のコマンドを実行して、DockerのビルドとECRリポジトリにプッシュ(アップロード)します。
下記のコマンドに含まれる「{AWSアカウントID}」をAWSアカウントIDに書き換えてから実行します。
> cd docker/test-app/
> docker build -t {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-app:1.0.0 .
> docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-app:1.0.0
イメージタグの名前を「1.0.0」で作成しました。イメージタグの名前を変更したい場合は、上記のコマンドに含まれる「1.0.0」を任意の名前に変更します。
AWSのECRリポジトリ画面にあるtest-app
のリポジトリをクリックすると、プッシュしたDockerイメージを確認することができます。
ECRリポジトリからDockerイメージをプル
他の環境で今回ビルドしたDockerイメージを利用する場合は、下記のコマンドを実行して、ECRリポジトリからDockerイメージをプル(ダウンロード)します。
下記のコマンドに含まれる「{AWSアカウントID}」をAWSアカウントIDに書き換えてから実行します。
> docker pull {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-app:1.0.0
ECRリポジトリを削除
下記のコマンドを実行すると、ECRリポジトリを削除することができます。
> docker-compose up -d
> docker-compose exec terraform sh
# cd /terraform/ecr/
# terraform destroy (AWS上のtest-appのECRリポジトリを削除します。
「Enter a value:」と表示されるので「yes」を入力します)
# exit
> docker-compose down
AWSのECRリポジトリ画面から、test-app
のリポジトリが削除されていることを確認します。
まとめ
Dockerコンテナ上のAWS CLIを使うことにより、ローカル環境を汚さずに手軽にDockerイメージをECRにプッシュできました。
ローカル環境で複数のAWSアカウントを利用している場合、Dockerコンテナ内でAWSの操作をしているため、誤って別のAWS環境を壊してしまう事故を減らせます。
(AWSアカウントごとに、docker-compose.yml
とフォルダを分ける)
今回は、イメージタグの変更不可(上書き禁止)と、ECRにプッシュすると自動でDockerイメージの脆弱性スキャンを実行する設定にしてあります。将来、AWS CodePipelineやAWS CodeDeploy等でリリースの自動化する際に役立ちます。
ECRは無料利用枠があります。それを超えるとリポジトリに保存されたDockerイメージのサイズと転送量によって料金が発生します。もう利用しないDockerイメージがある場合は、AWSのECRリポジトリ画面からイメージを削除するようにします。
ECRの料金の詳細は下記をご覧ください。