ECRを使ったコンテナ管理：DockerイメージをECRにプッシュするための基本と実践

## はじめに
AWSのサービス群の中で、Amazon Elastic Container Registry (ECR) は、Dockerイメージを安全に保存・共有するための強力なツールです。

:::note warn
**ECRを使用することで、オンプレミスやクラウドのインフラにまたがって効率的にコンテナアプリケーションをデプロイできます。**
:::

この記事では、ECRの学習を始めたばかりの私が、将来の自分への備忘録として、学んだことをまとめていきます。

## ECRについて

Amazon Elastic Container Registry (ECR) は、完全マネージド型のコンテナレジストリサービスです。

![スクリーンショット 2024-11-15 22.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/13d2fc67-34d5-71ff-8aa0-a0a7c695b610.png)
引用画像：https://zenn.dev/yoshii0110/articles/1de56128d7be2c

さらに詳しく学習されたい方は、AWSの公式サイトをご参照ください。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/what-is-ecr.html

### 主な機能
ECRの主な機能は以下の通りです。

:::note
- **イメージの保存と管理**
Dockerイメージを安全に保存し、アクセス制御も容易です。

- **セキュリティ**
AWS Identity and Access Management (IAM) を使って、細かなアクセス制御が可能です。

- **高可用性と統合性**
他のAWSサービス（CodePipeline、CodeBuildなど）とスムーズに連携できます。
:::

### ユースケース
ECRの利用例として、以下のシナリオがあります。

:::note
- **CI/CDパイプラインでのイメージ管理**
- **複数環境でのDockerイメージ共有**
- **コンテナアプリケーションのセキュアなデプロイメント**
:::

## レポジトリの作成
ECRにDockerイメージを保存するには、まずレポジトリを作成する必要があります。

![スクリーンショット 2024-11-15 23.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c2704479-318b-46c1-d9e4-aca620fc1318.png)

AWSコンソールで「ECR」サービスにアクセスし、「レポジトリを作成」をクリックします。
（ここでは、プライベートレポジトリを作成します。）

![スクリーンショット 2024-11-15 23.19.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/1e32cd8f-c898-f1e5-291a-2d979c9b10c7.png)

「レポジトリ名」に任意の名前を入力（例: ``my-app-repo``）し、必要に応じてオプション（暗号化、イミュータブル設定）を設定します。

![スクリーンショット 2024-11-15 23.22.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/e3dce2a6-053d-87f1-2b0d-bfe8ce49eb0d.png)

ここでは、特に変更せずデフォルト設定で作成します。

余談ですが、CLIを使ってレポジトリを作成する場合は、以下のコマンドを使用します。

```bash
aws ecr create-repository --repository-name my-app-repo
```

これで、ECR上に空のレポジトリが作成されていることが確認できました。

![スクリーンショット 2024-11-15 23.26.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7941a799-eb11-7020-1d26-be4fe5275ffa.png)

## Dockerイメージのプッシュとプル

ここでは、以下のようなプロジェクト構成を使用します。

```css
├── Dockerfile
└── html/
    └── index.html
```

CloudShellを使用して、以下のようなシンプルなDockerfileを作成します。

```Dockerfile
FROM nginx:latest
COPY ./html /usr/share/nginx/html
```

``/usr/share/nginx/html`` は、nginxのデフォルトの静的コンテンツディレクトリです。

![スクリーンショット 2024-11-15 23.36.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/4f17566d-3ebe-01e1-f1c8-4f81f988ffba.png)

次に、以下のようなサンプルHTMLファイルを準備します。

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Web App</title>
</head>
<body>
    <h1>Welcome to My Web App!</h1>
</body>
</html>
```

その後、以下のコマンドを使用してDockerイメージをビルドします。

```bash
docker build -t my-app .
```

## ECRにログイン

CloudShellを使用して、ECRにログインします。

```bash
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
```

:::note warn
**リージョンやアカウントIDは、ご自身のものに置き換えてください。**
:::

例えば、以下のように実行します。

```bash
[cloudshell-user@ip-10-134-28-216 ~]$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxx.dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/cloudshell-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
```

ECRへのログインが成功し、``Login Succeeded`` と表示されることが確認できました！

## Dockerイメージをプッシュ

ECRにDockerイメージをプッシュするには、まずイメージにタグを付けます。

```bash
docker tag my-app:latest <account_id>.dkr.ecr.<region>.amazonaws.com/my-app-repo:latest
```

:::note warn
**リージョンやアカウントIDは、ご自身のものに置き換えてください。**
:::

タグ付けが完了したら、次にそのイメージをECRにプッシュします。

```bash
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/my-app-repo:latest
```

ここでは、CloudShellを使い作成したECRのリポジトリにプッシュしています。

![スクリーンショット 2024-11-15 23.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/2f11a2eb-eeab-438f-e17a-30e0b4d0b2f4.png)

ECRのサービス画面からも、正常にプッシュされていることが確認できました。

![スクリーンショット 2024-11-15 23.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/8bd24859-42c3-57a1-666e-83fe41a2e7f1.png)

## ECRからローカル環境にDockerイメージをpull

:::note warn
**ここでは、AWS CLIのインストールと設定、およびECRへのログインが完了していることを前提に進めます。**
:::

ECRに保存されたイメージを別の環境で使用するには、以下のコマンドを実行してプルします。

```bash
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/my-app-repo:latest
```

これで、プライベートリポジトリから ``my-app-repo`` の最新イメージが私のローカル環境のMacBookにダウンロードされます。

ダウンロードされたイメージを確認するには、以下のコマンドを実行して、ローカルのDockerイメージをリスト表示します。

```bash
docker images | grep my-app-repo
```

以下のように表示されれば、イメージが正常にpullされたことが確認できます。

![スクリーンショット 2024-11-16 0.28.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c40dfbfb-ace9-1fed-9690-e599a86c17ab.png)

:::note
**ECRに保存したイメージを利用することで、他のAWSサービス（例: ECS、EKS）やローカル環境で簡単にコンテナを展開できます。**
:::

## まとめ

AWSのクラウド環境では、コンテナを簡単に展開したりスケールさせたりできるので、今後の自分にも役立つと感じています。

:::note warn
**次回は、ECRにプッシュしたイメージをECSにデプロイして、実際にコンテナ管理をさらに深掘りしていきます。**
:::

ECRとECSを組み合わせることで、もっとスムーズにコンテナを運用できるようになるので、継続してキャッチアップしていきたいです！

## 関連記事

https://qiita.com/K5K/items/0d8dbdb39fbb0375e2bd

https://qiita.com/kengo-sk8/items/4e6c241584da46f5de95

https://qiita.com/zumax/items/e241894713016871301e