AWS CloudShellでDockerイメージを作成してAmazonECRプライべートリポジトリにpushしてみる


## 記事の概要
コンテナで動くアプリケーションをAWSでデプロイするために、ECRへコンテナイメージをプッシュしなければいけない、というシチュエーションは度々あると思います。(AppRunnerとか)
今回は開発環境でDockerイメージを作成し、ECRプライベートリポジトリへプッシュするまでの手順を記載します。開発環境はCloudShellを使っていきます。 

※ CloudShellのディスク容量は1GBで拡張もできないため、イメージのサイズが大きくなる場合は別の環境を利用する必要があります。 ~~Cloud9…~~
> それぞれ 1 GB の永続ストレージ AWS リージョン を無料で利用できます

出典：https://docs.aws.amazon.com/ja_jp/cloudshell/latest/userguide/limits.html

## Amazon ECRプライベートの作成
push先のリポジトリがある場合はスキップしてよいですが、今回はリポジトリの作成から行います。  

ECRの画面で **「Private registry」** の「repositories」を選択し、「リポジトリを作成」ボタンをクリック  

![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/9b8e1da9-2c26-de96-f912-4afa7864822b.png)  


任意のリポジトリ名を入力（プライベートなリソースなので重複などは気にしなくてよいです）  

![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/48b0d3e5-cfdd-bfee-7432-606f170e8e93.png)


これで「作成」ボタンを作成するとリポジトリが作成されます。リポジトリ名がリンクになっているので、そこをクリックすると画面遷移して、リポジトリ内のイメージ一覧が表示されます。   

![image (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/bd6b14ce-e56a-eede-d1ef-798280d5ac8e.png)  

今回はリポジトリ新規作成のため空っぽです。 

## 開発環境(CloudShell)へのアクセス
ここからコンテナイメージ作成の準備です。Dockerを動かすための開発環境を用意する必要がありますが、今回ははじめからDockerコマンドが使えるCloudShellを使っていきます。 
使い方は簡単で、AWSマネジメントコンソールの上部のバーにあるコマンドプロンプトっぽいアイコンをクリックします。  

 ![image (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/5e4918b4-e977-beef-a501-e61ce3b15f25.png)  

するとAWS上に自動でコンピューティング環境が用意され、AWSマネジメントコンソールの下部にターミナルが表示されます。
試しに `docker --version` を実行するとDockerがインストール済だと分かります。   

自分のノートパソコンで実行しようとすると、Dockerをインストールするところからはじめる必要がありますが、CloudShellだとアイコンをクリックするだけで完了します。~~これでディスクサイズがもっと大きければ…~~
## ソースコードの準備
今回はFlaskを使って簡単なWebサイトを公開するソースコードを用意します。ファイル名はapp.pyにしました。
```py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
        str_out = '<h2>Hello world</h2>'
        return str_out
        
app.run(host='0.0.0.0',port=80)
```
app.pyファイルはローカル環境で作成してもいいですし、cloudshellで作成してもよいです。（cloudshellは ~~cloud9と違って~~ IDE機能がないのでローカル環境で作成するのがおすすめです）  

ローカル環境で作成した場合、CloudShellのファイルアップロード機能でファイルをアップロードする必要がありますので忘れずに。  
ターミナル右上の「アクション」ボタンをクリックすると「ファイルのアップロード」が選択できます。  

![image (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/fa3e9a95-3931-d1fb-5402-6c3f31b459cb.png)
 

## Dockerイメージの作成
コンテナで動かすソースコードが準備できたので、コンテナイメージを作成するためのDockerfileを準備します。
### Dockerfile
Dockerfileの記述は以下です。注意点として、app.pyの`app.run(host='0.0.0.0',port=80)`で公開ポートとして80番を指定しているので、Dockerfileの`EXPOSE 80`でも同じく80番を指定します。
```yaml
#ベースイメージとして pythonn v3.12 を指定
FROM python:3.12

# 以降の RUN, CMDコマンドを実行する作業ディレクトリを指定
WORKDIR /app

# カレントディレクトリにあるファイルをコンテナ上の ｢/app｣ ディレクトリにコピー
ADD . /app

# Flaskインストール
RUN pip install flask

# ポートの指定
EXPOSE 80

# コンテナ起動時に実行するコマンドを指定
CMD ["python", "app.py"]
```

### ECRのプッシュコマンドを実行する(Dockerイメージの作成~ECRへのプッシュ)
さて、ここからコマンドを実行してDockerイメージの作成とECRへのプッシュを行います。実は必要なコマンドはECRのリポジトリを表示したときの「プッシュコマンドを表示」をクリックすると表示されるようになっています。  

![image (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/bd6b14ce-e56a-eede-d1ef-798280d5ac8e.png)  

このコマンドを一つずつ実行していけばOKです。  

![image (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/5168b4d7-2b05-1ae6-bc14-64ed87cb2230.png)

以下、簡単なコマンドの説明になります。
- 1つめのコマンドはECRリポジトリへの認証を行っています。CloudShell上でイメージを作成したあと、ECRリポジトリへイメージをpushする（いわゆる書込み操作をする）ため認証が必要になります。  
`aws ecr get-login-password —region <リージョン> | docker login —username AWS —password-stdin <アカウントID>.dkr.ecr.<リージョン>.amazonaws.com`

- 2つめのコマンドでCloudShell上でイメージを作成します。体感2,3分かかります。イメージが作成されていることを確認したい場合は、作成後に`docker image ls`でイメージ一覧を確認できます  
`docker build -t test .`

- 3つめのコマンドでは先ほど作成したイメージにタグを付与します。タグを付与しなくてもpushできるようですが、管理性の観点でイメージタグの付与が推奨されています   
`docker tag test:latest <アカウントID>.dkr.ecr.<リージョン>.amazonaws.com/test:latest`

- 最後のコマンドでECRリポジトリへのpushを行っています。1分ほどかかるかと思います  
`docker push <アカウントID>.dkr.ecr.<リージョン>.amazonaws.com/test:latest`  

## ECRにイメージが追加されたことを確認する
「プッシュコマンド」の実行により、ECRリポジトリへイメージが追加されているはずなのでマネジメントコンソール上で確認してみます。  

![image (9)-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261789/dcec675f-1be9-b0da-eee1-253ceff5c5b5.png)  


先ほど空だったイメージ一覧にイメージが追加されており、latestタグが付与されていることが分かりました。    

---
この記事はここまでとなります。  

Next:  
DockerイメージをAppRunnerにデプロイする▼  
[AWS AppRunnerを使ってAWS ECRに配置したDockerイメージをAWSにデプロイする](https://qiita.com/e52yamada/items/6f03efa4a164e6c9747a)

手動で行ったコマンド実行をCIっぽく自動化する▼  
[DockerイメージのビルドとAmazon ECRへのプッシュをCodeBuildで自動化する](https://qiita.com/e52yamada/items/9ef696737d20285c7498)