[初心者向けシリーズ] Dockerイメージを作成しAmazon ECRにプッシュする方法を確認してみた

2023.06.19

はじめに

Dockerイメージを作成しAmazon ECRにプッシュするまでの方法を確認してみました。
Amazon ECR(Amazon Elastic Container Registry、以後 ECR)にはDocker HubのようにDockerイメージを保存できます。
保存したイメージはAmazon Elastic Container Service (Amazon ECS) やAmazon Elastic Kubernetes Service (Amazon EKS) などのコンテナ関連のサービスで利用できます。
私自身、DockerやAWSのコンテナサービスを最近使い始めたもので、もし内容に齟齬など有りましたらお気軽にご指摘いただければ思います。

今回の前提

今回の確認を実行するに当たっては、以下のソフトウェアが導入済みであることが前提となります。

  • Dockerをインストールしていること。また、私はRancher Desktopを使っています。Rancher Desktopの導入については弊社ブログにて紹介しているのでご参照ください。
  • AWS CLI v2がインストール済みであること。今回v2を使用しています。

実行環境

今回の検証に使ったソフトウェアのバージョンは以下の通りです。

項目名 バージョン
mac OS X Ventura 13.2
AWS CLI v2 2.4.29
Docker 20.10.14, build a224086
Rancher Desktop 1.8.1

確認するために実施する事の概要

実施内容の概要です。

  • ECRにリポジトリを作成
  • Dockerファイルを作成
  • Dockerイメージをビルド
  • DockerイメージをECRにプッシュ
  • DockerイメージをECRからプル

ECRにリポジトリを作成

まず、ECRにリポジトリを作成します。
リポジトリとは、Dockerイメージを保存する場所となるものです。これがないとイメージを保存できないので先に作っておきます。
リポジトリは、以下の2つの方法で作成してみました。

  • マネジメントコンソールから作成
  • CLIから作成

マネジメントコンソールから作成

マネジメントコンソールから作成する場合は、以下の手順で作成します。

1. ECRのコンソールにアクセス

AWSのコンソールからECRのコンソールを開きます。検索窓にregistory等の文言を入れていただくと候補として出て来ます。
開いたら、左側のペインに有るRepositoriesという項目をクリックしてください。

2. リポジトリを作成する

リポジトリの一覧画面に移りますので、右上のリポジトリを作成というボタンをクリックしてください。

リポジトリ作成画面でリポジトリ名を入力して、作成ボタンを押下してください。リポジトリが作成されます。

作成されたリポジトリは一覧画面画から確認することができます。

CLIから作成

リポジトリはAWS CLIのコマンドでも作成できます。
コマンドは以下の通りです。
※ 実施前にECRの操作権限を持っているロールのAssume roleを行っています。

$ aws ecr create-repository --repository-name test

指定が必須の項目がリポジトリ名となっています。

作成されたリポジトリの確認は以下のコマンドから可能です。

$ aws ecr describe-repositories --repository-name  test
{
    "repositories": [
        {
            "repositoryArn": "arn:aws:ecr:ap-northeast-1:<アカウントID>:repository/test",
            "registryId": "<アカウントID>",
            "repositoryName": "test",
            "repositoryUri": "<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/test",
            "createdAt": "2023-06-18T19:39:47+09:00",
            "imageTagMutability": "MUTABLE",
            "imageScanningConfiguration": {
                "scanOnPush": false
            },
            "encryptionConfiguration": {
                "encryptionType": "AES256"
            }
        }
    ]
}

Dockerイメージの作成

サーバーアプリケーション部分の作成

webサーバー用のアプリではNode.jsとexpressを用いてます。 最低限の内容で以下のjavascroptファイルを作成しました。

app.js

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.status(200).send('Hello World!');
});

app.listen(port, () => {
  console.log(`Listening at http://localhost:${port}`)
});

Dockerファイルを作成

Dockerファイルを作成します。 今回検証で使用するwebサーバーはnode.jsで構築してるので、Dockerのベースイメージはnodeを使用します。
nodeのイメージはDockerHubの以下のページから確認できます。
https://hub.docker.com/_/node/tags
この中で一番新しい node:16.20.0-alpine3.18を使用したDockerfileが以下の通りです。

Dockerfile

FROM node:16.20.0-alpine3.18
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 3000
CMD [ "node", "app.js" ]

Dockerイメージのビルド

Dockerイメージの作成は以下のコマンドで実行します。

docker build . -t express-server-image:latest

-tオプションでリポジトリ名とタグを指定しています。

-t <リポジトリ名>:<タグ>

作成したイメージを確認します。

$ docker image ls

REPOSITORY                     TAG                  IMAGE ID       CREATED         SIZE
express-server-image           latest               c5a1931551f5   4 minutes ago   122MB

DockerイメージをECRにプッシュ

ECRへのイメージのプッシュにはAWS CLIのコマンドを使用します。
どのようなコマンド郡を使ってプッシュするかについては、マネジメントコンソールからも確認できます。
ECRのプライベートリポジトリに戻り、プッシュ先のリポジトリを選択した状態で、画面右上のプッシュコマンドの表示をクリックすると以下の画像のように必要手順が表示されます。

このコマンドを順に実行して行きます。

1.レジストリの認証を行う

1のコマンドではレジストリの認証を行います。

ECRのレジストリはDockerイメージを一元管理するためのリポジトリサービスの事を指します。 Docker クライアントはリポジトリを管理しているECRのレジストリから認証を得る必要があります。その際の認証トークンは12時間有効となります。

以下コマンド実行します。 get-login-password

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com

Login Succeeded

Login Succeededと表示されれば認証成功です。

補足

AWS CLI v1では以下のコマンドで認証が可能でした。

aws ecr get-login

こちらは現在非推奨となっており、AWS CLIのリファレンスに以下のコメントが記載されています。

Note: This command is deprecated. Use get-login-password instead.

参照:https://docs.aws.amazon.com/cli/latest/reference/ecr/get-login.html

AWS CLI v2では aws ecr get-loginが使用できなくなっています。

2.イメージの作成

2のコマンドではイメージ作成となりますが、すでに作成済みですので飛ばします。

3.イメージにタグ付けをする

3のコマンドではリポジトリにプッシュできるようにするために、タグを変更します。

$ docker tag express-server-image:latest <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-server:latest

コマンドの引数の内容はdocker tag 元のリポジトリ名:元のタグ名 変更後のリポジトリ名:変更後のタグ名となります。 実行後にイメージを確認します。

$ docker images

REPOSITORY                                                               TAG                  IMAGE ID       CREATED         SIZE
<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-server    latest               c5a1931551f5   2 hours ago     122MB
express-server-image                                                     latest               c5a1931551f5   2 hours ago     122MB

イメージIDc5a1931551f5に対して変更したタグが追加されました。

補足

コマンドに記載されているdkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-serverは作成したリポジトリのURIです。

4.イメージをプッシュする

4つめのコマンドでイメージをプッシュします。

$ docker push <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-server:latest

以下のコマンドでイメージを確認します。

$ aws ecr describe-images --repository-name sample-nodejs-server

{
    "imageDetails": [
        {
            "registryId": "<アカウントID>",
            "repositoryName": "sample-nodejs-server",
            "imageDigest": "sha256:e00a2d5aecf0264828fdce9c14ed3aeed9037502e72d2f3048957f05009a06dc",
            "imageTags": [
                "latest"
            ],
            "imageSizeInBytes": 43841867,
            "imagePushedAt": "2023-06-18T22:31:31+09:00",
            "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "artifactMediaType": "application/vnd.docker.container.image.v1+json"
        }
    ]
}

無事にプッシュできていることが確認できました。

Dockerイメージのプル

プッシュしたイメージをローカル環境にプルして、ローカルで立ち上げたコンテナでイメージを実行できるか確かめてみます。

まずはすでにローカル環境に同じイメージが存在するので削除します。 削除は以下のコマンドで可能です。

$ docker image rm -f c5a1931551f5

イメージに対して複数のリポジトリ名が紐づいている際は-fオプションを使用する事で削除可能です。

次にECRからイメージをプルします。コマンドは以下の通りです。 引数にはプッシュした際に使用したリポジトリURIおよびタグを指定します。

$ docker pull <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-server:latest

イメージの確認

$ docker image ls

REPOSITORY                                                               TAG                  IMAGE ID       CREATED         SIZE
<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sample-nodejs-server   latest               c5a1931551f5   4 hours ago     122MB

プルしたイメージが間違いなくECRにプッシュしたイメージと同じものであることが確認できました。

では、このイメージを元にコンテナを起動します。

$ docker run -p 80:3000 c5a1931551f5

ブラウザでhttp://localhostにアクセスすると以下の画面が表示されます。

無事にサーバーアプリが動いていることが確認できました。

最後に

今回はDockerイメージをECRにプッシュする方法を紹介しました。初めてでしたがプッシュ用のコマンドも丁寧に表示されるので、あまり迷わずに進めることができました。
今後はECSで今回プッシュしたイメージを元にAWS上でコンテナを動かして見たいと思います。
以上