ローカルで build した docker image を ECR のリポジトリに push する
Amazon Lambda で、コンテナイメージを利用したかったのですが、そのためにはまず Amazon ECR に Docker Image をプッシュする必要があるとのことだったので、その手順について備忘録を残します。
なお、使用している OS は Ubuntu 22.04 です。
流れ
- AWS CLI の準備
- AWS CLI のインストール
- IAM ユーザーの設定
- ECR でプライベートリポジトリを作成
- Docker Image の作成
- Dockerfile の用意
- Docker Image のビルド
- ECR にプッシュ・確認
- ECR から認証を得る
- 作成したリポジトリへプッシュする
AWS CLI の準備
各設定が終了している場合は飛ばしてください。
IAM ロールだけ確認が必要かもしれません。
ここでやること
- AWS CLI のインストール
- IAM の設定
AWS CLI
まず、AWS CLI が必要になります。
使用する OS に合わせてインストールしてください。
IAM ユーザーの設定
次に、IAM ユーザーをセットアップします。
IAM Identity Center が推奨されていますが、ここでは、通常の IAM ユーザーを作成します。
アタッチするポリシーは、以下の通りです。カスタムポリシーを作成してアタッチしてください。
自分は、読み取り系のアクセス許可も同時に得るためにカスタムポリシーを作成して、アタッチしました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:GetAuthorizationToken",
"ecr:UploadLayerPart",
"ecr:InitiateLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:DescribeImages",
"ecr:DescribePullThroughCacheRules",
"ecr:ListImages"
],
"Resource": "*"
}
]
}
AWS CLI で 先ほど作成した IAM ユーザーをセットアップします。
aws configure
access key ID や secret access key などの入力を行います。
ECR でプライベートリポジトリを作成
AWS コンソールから、Elastic Container Registry(ECR) のページまで移動します。
ナビゲーションペインから「Private registry/Repositories」を選択し、「リポジトリを作成」から、新規作成画面に移動します。
「可視性設定」を「プライベート」、「名前」を入力し、新しいリポジトリを作成します。
名前は後ほど作成する Docker Image と同じ名前を使用する必要があります。
Docker Image の作成
ECR にプッシュする Docker Image を作成していきます
ここでやること
- Dockerfile の用意
- Docker Image のビルド
Dockerfile の用意
使用する Docker Image は、いつかの記事で作成した Lambda Web Adapter を利用したサーバーレス Meilisearch 環境のものを使います。
最終的には、Lambda で動作確認をしたいだけなので、手元に Lambda 用のものがあればそれでもかまいません。
Dockerfile
FROM gcr.io/distroless/cc-debian12:latest AS cc
FROM alpine:3.16
COPY /lambda-adapter /opt/extensions/lambda-adapter
# for execute meilisearch
ENV LD_LIBRARY_PATH="/usr/local/lib"
COPY /lib/*-linux-gnu/* /usr/local/lib/
RUN apk update --quiet \
&& apk add -q --no-cache libgcc tini curl \
&& mkdir /lib64 \
&& ln -s /usr/local/lib/ld-linux-*.so.2 /lib64/
# Install Meilisearch
ARG version="v1.6.0"
ARG os="meilisearch-linux-amd64"
ARG url="https://github.com/meilisearch/meilisearch/releases/download"
RUN curl -OL ${url}/${version}/${os} | sh \
&& mv ${os} meilisearch \
&& chmod +x meilisearch \
&& mv meilisearch /usr/bin/
ENV MEILI_HTTP_ADDR 0.0.0.0:8080
ENV MEILI_SERVER_PROVIDER docker
ENV MEILI_DB_PATH /mnt/meili_data/data.ms
ENV MEILI_MASTER_KEY meilisearch-master-key
ENV MEILI_ENV production
COPY ./meili_data /mnt/meili_data
# This directory should hold all the data related to meilisearch so we're going
# to move our PWD in there.
# We don't want to put the meilisearch binary
WORKDIR /mnt/meili_data
EXPOSE 8080/tcp
ENTRYPOINT ["tini", "--"]
CMD /usr/bin/meilisearch
Docker Image のビルド
Docker Image のビルドを行います。
Docker Image の名前は、先ほど作成した ECR のリポジトリ名と同じ名前を付けます。
docker build . -t <Docker Image の名前>:<タグ名> --no-cache
# 例) meilisearch-docker-lambda:latest
ビルドが完了したら、作成した Docker Image を確認します。
docker images
# こんな感じで指定したものが表示されていれば OK
# REPOSITORY TAG IMAGE ID CREATED SIZE
# meilisearch-docker-lambda latest xxxxxxxxxxx n minutes ago x.xxGB
続いて ECR で作成したリポジトリにプッシュできるようにタグ付けを行います。
リージョン名と Docker Image 名(リポジトリ名)は適宜入力してください。
AWS アカウント ID はコンソール画面の右上から確認することができます。
docker tag <Docker Image 名> <AWS アカウント ID>.dkr.ecr.<リージョン名>.amazonaws.com/<Docker Image 名>
もしくは、AWS コンソール -> ECR -> リポジトリ -> 詳細画面からコマンドの確認が可能です。
ECR にプッシュ・確認
最後に、作成したプライベートリポジトリへプッシュを行います。
ここでやること
- ECR から認証を得る
- 作成したリポジトリへプッシュする
- 確認する
ECR から認証を得る
手元の Docker クライアントから ECR に対して認証を得ます。
下記コマンドを実行し、「Login Succeeded」が表示されれば OK です。
得られた認証トークンは12時間有効なため、それ以降はもう一度このコマンドを実行して認証を得る必要があります。
aws ecr get-login-password --region region | docker login --username AWS --password-stdin <AWS アカウント ID>.dkr.ecr.<リージョン名>.amazonaws.com
作成したリポジトリへプッシュする
最後にプライベートリポジトリへプッシュを行います。
docker push <AWS アカウント ID>.dkr.ecr.<リージョン名>.amazonaws.com/<Docker Image 名>
確認する
AWS コンソール-> ECR -> 作成したリポジトリから、Docker Image が反映されているかどうかを確認します。
また、AWS CLI から確認することも可能です。
aws ecr describe-images --repository-name <リポジトリ名>
プッシュに成功していれば、対象のリポジトリ名を含んだ json 文字列が返ってきます。
失敗している場合は、「RepositoryNotFoundException」などのエラーメッセージが返ってきます。
参考
Discussion