【AWSコンテナサービス入門】Amazon ECR にコンテナイメージをプッシュする

記事タイトルとURLをコピーする

概要

当記事では、AWSコンテナサービス入門と題してAmazon ECR(以下、ECR)にコンテナイメージをプッシュする方法をご紹介します。
途中、Dockerコマンドの基本的な操作方法についても触れています。

全体像

4つのフェーズに分けて作業を行います。

全体像

  1. Docker Hubのコンテナイメージを実行
  2. Dockerfileからコンテナイメージをビルドし、コンテナを実行
  3. Amazon ECRへビルドしたイメージをプッシュ
  4. Amazon ECRのコンテナイメージを実行

Amazon ECR について

aws.amazon.com

Amazon ECRは、コンテナイメージを安全に保存および管理するためのマネージドなコンテナレジストリサービスです。

前提

作業するに際してAWSの利用料金が発生します。
作業するAWSリージョンは東京リージョン(ap-northeast-1)を想定しています。

手順

1. Docker Hubのコンテナイメージを実行

1. Docker Hubのコンテナイメージを実行

まずはDocker Hubのコンテナイメージを実行する環境を準備します。
今回はAWS Cloud9で作業を実施します。

AWS Cloud9(以下、Cloud9)とは

オンラインの統合開発環境(IDE)で、AWSマネージドコンソール上でコード編集などが可能です。
AWSのリソースへのアクセスも簡単で、効率的に開発できます。 docs.aws.amazon.com

Cloud9 を起動する

AWS Cloud9 > Environments > Create environment

AWS Cloud9 > Environments > Create environment

Details セクション

Name:任意の名前を入力

Network settings セクション

Network settings セクション

  • Connection:Secure Shell (SSH)
  • VPC:パブリックサブネットを持つVPCを選択
  • Subnet:任意のパブリックサブネットを選択。(デフォルトVPCのサブネットはパブリックサブネットのため、デフォルトサブネットを選択でもOK)

Create をクリック。

Cloud9 へ接続

AWS Cloud9 > Environments > Open クリック
数分後、Successfully created … のメッセージが表示されたら環境作成が完了しています。

作成した環境の Open をクリックし、Cloud9へ接続します。

Welcome ページ削除、コンソールタブを上へ
作業しやすいようにWelcome ページタブを削除し、コンソールタブを上へ持ってきます。

Docker 確認

起動されたプラットフォーム(Amazon Linux2)には、デフォルトインストールされたDockerが起動しています。

administrator:~/environment $ docker -v
Docker version 20.10.23, build 7155243

administrator:~/environment $ service docker status
Redirecting to /bin/systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2023-06-02 18:25:40 UTC; 16s ago
…

パブリックレジストリのPHPのコンテナイメージを実行する

Docker Hubのパブリックレジストリから「php:8.0-apache」のコンテナイメージをプルし、作業環境のコンテナとして実行させます。

administrator:~/environment $ docker run -d -p 80:80 --name test-web php:8.0-apache
Unable to find image 'php:8.0-apache' locally
8.0-apache: Pulling from library/php
9e3ea8720c6d: Pull complete 
07353b772b5e: Pull complete 
5908153120ba: Pull complete 
8681ad2eeea6: Pull complete 
92711ce78973: Pull complete 
bf1c5be6427e: Pull complete 
1d02a81768ed: Pull complete 
d674a0135f85: Pull complete 
6d87d0359817: Pull complete 
5e8c2df9b69e: Pull complete 
aacfb138e3c1: Pull complete 
2db2528ade33: Pull complete 
beeef66f0c04: Pull complete 
Digest: sha256:8eb40b6bb4f5095e8f83366fe7fadec55ccd5ac48cbe31f3b83b5ebdfb78683b
Status: Downloaded newer image for php:8.0-apache
628f6697b8a54fe10d5340b70f81c78cb61f21df4b722aa1901f8b5e0549084e

docker run コマンド1回の実行でイメージプルとコンテナ実行を同時に実行しています。
--name test-web で、作業環境の実行コンテナを識別する名前をつけます。

イメージの確認

administrator:~/environment $ docker images
REPOSITORY   TAG          IMAGE ID       CREATED       SIZE
php          8.0-apache   55a8611898bb   2 weeks ago   455MB

実行中コンテナの確認

administrator:~/environment $ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS              PORTS                               NAMES
628f6697b8a5   php:8.0-apache   "docker-php-entrypoi…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   test-web

実行したコンテナへアクセス

実行中のコンテナで稼働しているPHPへアクセスして確認します。

administrator:~/environment $ curl http://localhost/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<hr>
<address>Apache/2.4.56 (Debian) Server at localhost Port 80</address>
</body></html>

Apacheは起動しているようですが、403 Forbiddenが表示されました。

PHPの動作確認のため、index.phpを作成します。

実行中のコンテナへ接続

administrator:~/environment $ docker exec -it test-web bash
root@31bd88f96776:/var/www/html#

index.phpを作成

ワンライナーで作成します。

root@31bd88f96776:/var/www/html# echo "<?php echo 'Hello Container'; ?>" > index.php                                                                                          
root@31bd88f96776:/var/www/html# exit
exit

再び、PHPへアクセス

administrator:~/environment $ curl http://localhost/
Hello Containeradministrator:~/environment $

PHPが動作していることを確認できました。

実行中のコンテナを停止

コンテナを停止して状態を確認します。

administrator:~/environment $ docker stop test-web
test-web

コンテナの状態を確認

administrator:~/environment $ docker images
REPOSITORY   TAG          IMAGE ID       CREATED       SIZE
php          8.0-apache   55a8611898bb   2 weeks ago   455MB

administrator:~/environment $ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

administrator:~/environment $ docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS                      PORTS     NAMES
31bd88f96776   php:8.0-apache   "docker-php-entrypoi…"   24 minutes ago   Exited (0) 13 seconds ago             test-web

docker images コマンドで、コンテナイメージは存在していることが確認できます。
docker ps コマンドは、実行中のコンテナのみ表示されるので、
docker ps -a コマンドで全てのコンテナを表示しています。
プロセスの STATUS は Exited (0) 13 seconds ago で13秒前に停止したことが確認できます。

2. Dockerfileからコンテナイメージをビルドし、コンテナを実行

ここまでで、Docker Hubのパブリックレジストリへ登録されているコンテナイメージを実行できることを確認しました。
次は自分でコンテナイメージをビルドし、そのイメージを実行します。

2. Dockerfileからコンテナイメージをビルドし、コンテナを表示

Dockerfile を作成

以下の「Dockerfile」ファイルを作業環境のディレクトリ直下へ作成します。 - dockerfile

FROM php:8.0-apache
COPY index.php /var/www/html
EXPOSE 80
  • FROM:ベースとなるイメージを宣言
  • COPY:ローカルのファイルやディレクトリをDockerイメージ内の指定されたディレクトリにコピーします。ソースファイルとターゲットディレクトリを指定します
  • EXPOSE:コンテナが実行された際に、コンテナ内で公開するポートを指定

「環境名」 フォルダ 右クリック > New File

「Untitled」を「Dockerfile」へ変更

Dockerfile」をダブルクリックし、先述の内容をペーストし、Command + Sで保存します。(Windowsの場合はCtrl + S)

index.php を作成

先程、ワンライナーで作成したindex.phpを内容を変えて作成します。

Dockerfile作成と同じ要領で以下の内容の「index.php」ファイルをディレクトリ直下へ作成します。

<?php echo 'Hello Container Self Build'; ?>

index.php

このindex.phpが、Dockerfileで指定した COPY index.php /var/www/html の宣言によってコンテナ内の /var/www/html 配下へ配置される仕組みです。

作成したら、保存を忘れずに。

ビルドコマンドを実行

bash のタブを表示し、ビルドコマンドを実行します。

bash タブ

administrator:~/environment $ docker build -t my-php:v1 .                                                                                 
Sending build context to Docker daemon  14.55MB
Step 1/3 : FROM php:8.0-apache
 ---> 429895214b18
Step 2/3 : COPY index.php /var/www/html
 ---> f4b804b5e102
Step 3/3 : EXPOSE 80
 ---> Running in 97c79c99e02c
Removing intermediate container 97c79c99e02c
 ---> e54d6613bd33
Successfully built e54d6613bd33
Successfully tagged my-php:v1

my-php は、イメージに付与したい任意の名前を、v1 の部分は任意のタグ名を指定します。
タグは主にイメージのバージョンを管理するためのものです。
作業ディレクトリのDockerfileとindex.phpを元にイメージをビルドさせるので、 . を指定します。

ビルドイメージの確認

administrator:~/environment $ docker images
REPOSITORY   TAG          IMAGE ID       CREATED          SIZE
my-php       v1           e54d6613bd33   59 seconds ago   455MB
php          8.0-apache   429895214b18   4 days ago       455MB

my-php:v1 のイメージが、登録されていることが確認できました。

ビルドイメージからコンテナを実行

administrator:~/environment $ docker run -d -p 80:80 --name my-test-web my-php:v1
f9305c630b84b1847dd0708b90e46032779a3748acf04821872b31119f5ca4a2

実行中コンテナの確認

administrator:~/environment $ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                               NAMES
f9305c630b84   my-php:v1   "docker-php-entrypoi…"   10 minutes ago   Up 10 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   my-test-web

実行したコンテナへアクセス

実行したPHPのコンテナへアクセスして確認します。

administrator:~/environment $ curl http://localhost/
Hello Container Self Buildadministrator:~/environment $

作成したindex.phpの内容が表示され、自分でビルドしたイメージが実行されていることを確認できました。

3. Amazon ECRへビルドしたイメージをプッシュ

ビルドしたコンテナイメージをECR へプッシュします。

3. Amazon ECRへビルドしたイメージをプッシュ

ECRリポジトリを作成

まずはプッシュ先となるECRのリポジトリを作成します。

AWS > EXPLORER > ECR > Create Repository…
Cloud9 IDE ナビゲーションバーから AWS アイコンを選択し、EXPLORER > Asia Pacific (Tokyo) を展開します。

ECR メニューで右クリックし、Create Repository... を選択します。

「リポジトリ名」入力、Enter
任意のリポジトリ名を入力し、Enter。

URLをコピー

ECR > 「リポジトリ名」 > Copy Repository URI
ECRを展開すると作成したリポジトリ名が確認できます。
右クリックでCopy Repository URIを選択し、コピーしておきます。

イメージのタグ付けとECRのリポジトリを登録

administrator:~/environment $ docker tag my-php:v1 [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1
administrator:~/environment $ docker images
REPOSITORY                                                 TAG          IMAGE ID       CREATED          SIZE
[AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php   v1           ab739128b1a7   39 minutes ago   455MB
my-php                                                     v1           ab739128b1a7   39 minutes ago   455MB
php                                                        8.0-apache   429895214b18   4 days ago       455MB

ビルドしたそのままのイメージをプッシュしようとするとデフォルトでDocker Hubのリポジトリにプッシュしてしまいます。
そのため、プッシュする前に tag オプションで イメージのプッシュ先/リポジトリ名:タグ としてイメージを登録します。

[AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1 の部分は先述のコピーしておいたURIに :v1 を付けたものです。

ECRへプッシュするイメージの確認

administrator:~/environment $ docker images
REPOSITORY                                                 TAG          IMAGE ID       CREATED          SIZE
[AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php   v1           ab739128b1a7   39 minutes ago   455MB
my-php                                                     v1           ab739128b1a7   39 minutes ago   455MB
php                                                        8.0-apache   429895214b18   4 days ago       455MB

ビルドした my-php イメージとは別のリポジトリ名でイメージが登録されていることが確認できます。
このイメージをECRへプッシュします。

ECRへ認証

ECRへプッシュするために事前に認証します。

administrator:~/environment $ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/ec2-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

WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.は、/home/ec2-user/.docker/config.jsonに認証情報が保存されているというメッセージです。
本作業ではこのまま進めますが、本番環境などでは適切に処置することをおすすめします。

ECRへプッシュ

docker push コマンドで、ECRにコンテナイメージをプッシュします。

administrator:~/environment $  docker push [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1
The push refers to repository [AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/my-php]
c4494cd13028: Pushed 
c0c53cc6687c: Pushed 
f9878015f10b: Pushed 
e7487bb4bb0f: Pushed 
1c7bc8e4260f: Pushed 
141ab80e91a2: Pushed 
bc67315bbd3e: Pushed 
5e33913e7a80: Pushed 
d54990acf4bf: Pushed 
91692ec0375d: Pushed 
d682838149b0: Pushed 
9a6e8fbbcab1: Pushed 
2656be2aa5fa: Pushed 
8cbe4b54fa88: Pushed 
v1: digest: sha256:42d8a708f221698c2f206e5df02243d56b3a6b6ccecb266d15f4db0a4273fcc2 size: 3242

4. Amazon ECRのコンテナイメージを実行

プッシュしたイメージを作業環境へプルして実行します。

4. Amazon ECRのコンテナイメージを実行
確認しやすいようにまずは作業環境のイメージを全て削除します。

コンテナの停止

コンテナを削除する前に、実行中のコンテナを停止します。

administrator:~/environment $ docker stop my-test-web
my-test-web

コンテナの削除

docker rm でコンテナを削除します。

コンテナIDを指定するため、docker ps -a で事前確認して指定します。

administrator:~/environment $ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS                     PORTS     NAMES
7c7dd54575cd   ab739128b1a7   "docker-php-entrypoi…"   About an hour ago   Exited (0) 2 minutes ago             my-test-web
54d6586b4a4e   429895214b18   "docker-php-entrypoi…"   2 hours ago         Exited (0) 2 hours ago               test-web
administrator:~/environment $ docker rm 7c7dd54575cd
7c7dd54575cd
administrator:~/environment $ docker rm 54d6586b4a4e
54d6586b4a4e
administrator:~/environment $ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

コンテナイメージの削除

docker rmi でコンテナイメージを削除します。

イメージIDを指定するため、docker images で事前確認して指定します。

administrator:~/environment $ docker images
REPOSITORY                                                 TAG          IMAGE ID       CREATED             SIZE
[AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php   v1           ab739128b1a7   About an hour ago   455MB
my-php                                                     v1           ab739128b1a7   About an hour ago   455MB
php                                                        8.0-apache   429895214b18   4 days ago          455MB
administrator:~/environment $ docker rmi -f ab739128b1a7
administrator:~/environment $ docker rmi 429895214b18
administrator:~/environment $ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

タグを付与したイメージはリポジトリが複数あるため、 -f をオプション指定しています。
これで実行中のコンテナも作業環境のコンテナイメージも存在しないまっさらな状態に戻りました。

ECRのコンテナイメージを実行

administrator:~/environment $ docker run -d -p 80:80 --name dl-my-test-web  [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1                                                 
Unable to find image '[AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1' locally
v1: Pulling from my-php
f03b40093957: Pull complete 
662d8f2fcdb9: Pull complete 
78fe0ef5ed77: Pull complete 
4e258eed73a3: Pull complete 
1ddd4f300547: Pull complete 
0edd0b2ea53b: Pull complete 
ee9d310c9717: Pull complete 
3be73cbb78ed: Pull complete 
62edfdaa6c06: Pull complete 
a7d809597732: Pull complete 
8dcda23a1ec0: Pull complete 
8e82d36bf349: Pull complete 
be2504a04769: Pull complete 
948790cc79e3: Pull complete 
Digest: sha256:42d8a708f221698c2f206e5df02243d56b3a6b6ccecb266d15f4db0a4273fcc2
Status: Downloaded newer image for [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/my-php:v1
3bb9b05937fe5ca0489614b8b2b623a9b162ab76715657d3e53d6593e0df8aca

プッシュして登録していたECRのリポジトリからイメージをプルし、コンテナ実行します。

実行したコンテナへアクセス

実行したPHPのコンテナへアクセスして確認します。

administrator:~/environment $ curl http://localhost/
Hello Container Self Build

ECRの情報をコンソールから確認

プッシュしたコンテナイメージの情報がAWSマネジメントコンソールからも確認できます。

Amazon ECR > リポジトリ > 「リポジトリ名」

最後に

ECRへのコンテナイメージプッシュは基本的な作業ですが、AWSのコンテナサービスのベースとなる重要な部分です。
どなたかのお役に立てれば幸いです。

折戸 亮太(執筆記事の一覧)

2021年10月1日入社
クラウドインテグレーション部技術1課

屋根裏エンジニア