技術検証：GitHub Actionsを使用してAmazon ECRにDockerイメージをプッシュする手順

## はじめに

本記事では、GitHub Actionsを使用して、Amazon Elastic Container Registry (ECR) にDockerイメージをプッシュする手順を紹介します。

:::note warn
***GitHub Actionsを活用することで、CI/CDパイプラインを簡単に構築でき、コードの変更を自動でデプロイできる環境を整えることができます。***
:::

![スクリーンショット 2024-12-07 22.40.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/8638439b-85a4-e05c-3036-ba6472e6b31e.png)

また、本記事は未来の自分への備忘録として技術検証を行い、その成果や学びを記録していきます。

## 前提知識について

GitやGitHub Actionsについては、過去の記事でまとめているので、そちらも参考にしてください。

https://qiita.com/free-honda/items/874b1cd9d4a41e82c3ee

https://qiita.com/free-honda/items/d1732bdf134f8dd4cdd1

さらに、今後はTerraformやCloudFormationを活用し、インフラのコード化（Infrastructure as Code）を進め、インフラの開発・運用をより効率的に行っていく予定です。

https://qiita.com/free-honda/items/c7a68a216eef2161c567

:::note
***これにより、手作業によるミスを減らし、再現性のあるインフラ構築を実現することを目指しています。***
:::

## 実際にやってみた
### IAMユーザと権限の準備
AWSコンソールで「IAM」サービスを開き、以下の手順でユーザーを作成し、必要な権限を設定します。

![スクリーンショット 2024-12-07 21.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/226955a5-feb6-27e1-d14c-2ec559ed9680.png)

必要な権限として、「```AmazonEC2ContainerRegistryFullAccess```」または、以下のカスタムポリシー（**※権限については、ご自身の環境に合わせて修正してください**）を設定します。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:BatchGetImage",
        "ecr:PutImage"
      ],
      "Resource": "arn:aws:ecr:<リージョン>:<アカウントID>:repository/<リポジトリ名>"
    }
  ]
}
```

### ECRリポジトリの作成
AWSコンソールで「サービス一覧」からECRを選択し、「リポジトリを作成」をクリックします。

![スクリーンショット 2024-12-07 21.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7a4189ba-ae5a-5722-8a20-8643ef7b9b8f.png)

リポジトリ名を設定し、プライベートに設定して問題ないことを確認後、作成します。CLIを使用して作成する場合、以下のコマンドでリポジトリを作成できます。

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

### GitHubリポジトリの準備

GitHubで「New Repository」を選択し、リポジトリ名を設定した後、パブリックまたはプライベートの設定を行います（公開設定については任意で問題ありません）。

![スクリーンショット 2024-12-07 21.25.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6893ad86-8a52-0497-7147-10b8a3afb549.png)

### GitHub Secretsの設定

GitHubリポジトリのページで、「Settings」 → 「Secrets and variables」 → 「Actions」を選択します。

![スクリーンショット 2024-12-07 21.31.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/9f530f86-5b50-fc6c-b069-dd8484a09dca.png)

次に、「New repository secret」をクリックし、以下のシークレットを1つずつ登録してください。

:::note warn
- **AWS_ACCESS_KEY_ID:**
 IAMユーザーのアクセスキー。

- **AWS_SECRET_ACCESS_KEY:** 
IAMユーザーのシークレットキー。

- **AWS_REGION:** 
ECRのリージョン（例: ap-northeast-1）。

- **ECR_REPOSITORY:** 
ECRリポジトリ名（例: my-docker-repo）。

- **IMAGE_TAG:** 
Dockerイメージのタグ（例: latest）。
:::

IAMユーザーのアクセスキーやシークレットキーは、アカウント設定の「セキュリティ認証情報」から作成して、取得できます。

![スクリーンショット 2024-12-07 21.44.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/3ba3660c-5ef5-bc20-a258-c88aa39ef1f9.png)

### GitHub Actionsワークフロー設定

以下の内容を ```.github/workflows/ecr-push.yml``` に記述します。

```.github/workflows/ecr-push.yml
name: Push to ECR

on:
  push:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      # リポジトリのクローン
      - name: Checkout code
        uses: actions/checkout@v3

      # AWS CLI のセットアップ
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      # Dockerログイン
      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} \
            | docker login --username AWS --password-stdin \
              $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

      # Dockerイメージのビルド
      - name: Build Docker image
        run: |
          docker build -t ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} -f Dockerfile .

      # Dockerイメージのタグ付け
      - name: Tag Docker image
        run: |
          docker tag ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}

      # Dockerイメージのプッシュ
      - name: Push Docker image to Amazon ECR
        run: |
          docker push \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}
```

GitHub Actionsの詳細な使い方については、過去の記事でまとめているので、ぜひ参考にしてください。

https://qiita.com/free-honda/items/d1732bdf134f8dd4cdd1

### Dockerfileの追加

作成したリポジトリに、以下のような ```Dockerfile``` を追加します（ここでは簡単なPythonアプリの構成例を示します）。

```dockerfile
# ベースイメージ
FROM python:3.9-slim

# 作業ディレクトリ
WORKDIR /app

# 必要なファイルをコピー
COPY . /app

# 必要なパッケージをインストール
RUN pip install flask

# アプリケーションを実行
CMD ["python", "app.py"]
```

## ローカルからpushしてみた

次に、ローカル環境でテスト的に ```main``` ブランチに push してみます。まず、任意のディレクトリを作成して、適当なファイルを作成して実施してください。

```bash
git init
git add .
git commit -m "test3"
git branch -M main
git remote add origin git@github.com:free-honda/GitHub-Actions-20241207.git
git push origin main
```

:::note alert
***エラーが発生した場合は、必要に応じて修正してください。***
:::

## push後の確認
GitHub Actionsの動作確認を行います。「Actions」タブで、ワークフローが正常に実行されているかを確認します。

![スクリーンショット 2024-12-07 22.03.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6ab55837-13fc-2866-0137-e5ae338eb55a.png)

この画面で、約「40秒」でDockerイメージが正常にプッシュされたことが確認できました。

![スクリーンショット 2024-12-07 22.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/13bd9380-821b-ebd1-066e-1f53543977c8.png)

最後に、ECRのサービス画面から確認し、想定通りイメージがpushされていることを確認できたので、GitHub Actionsを使ったECRへの自動デプロイが完了しました！

:::note warn
**これで、GitHub Actionsを使用して ```main``` ブランチにプッシュされた変更が自動的にECRにデプロイされる設定が完成です！**
:::

## まとめ

ここまでお読みいただき、ありがとうございました！少し整理しながらまとめた為、予想以上に時間がかかってしまいました（笑）。

今回は、GitHub Actionsを使用してECRにDockerイメージをプッシュする基本的な手順について紹介しました。

:::note
***インフラのコード化に向けた第一歩として、非常に重要なポイントです。この内容をまとめることで、より深い理解を得ることができました。***
:::

この記事が、誰かの技術的な支えになれば嬉しいです！

## 関連記事

https://zenn.dev/kou_pg_0131/articles/gh-actions-ecr-push-image

https://dev.classmethod.jp/articles/github-wf-docer-ecr/

https://dev.classmethod.jp/articles/github-action-ecr-push/