- 概要
- 手順
概要
当記事では、AWSコンテナサービス入門と題してAmazon ECR(以下、ECR)にコンテナイメージをプッシュする方法をご紹介します。
途中、Dockerコマンドの基本的な操作方法についても触れています。
全体像
4つのフェーズに分けて作業を行います。
- Docker Hubのコンテナイメージを実行
- Dockerfileからコンテナイメージをビルドし、コンテナを実行
- Amazon ECRへビルドしたイメージをプッシュ
- Amazon ECRのコンテナイメージを実行
Amazon ECR について
Amazon ECRは、コンテナイメージを安全に保存および管理するためのマネージドなコンテナレジストリサービスです。
前提
作業するに際してAWSの利用料金が発生します。
作業するAWSリージョンは東京リージョン(ap-northeast-1)を想定しています。
手順
1. Docker Hubのコンテナイメージを実行
まずはDocker Hubのコンテナイメージを実行する環境を準備します。
今回はAWS Cloud9で作業を実施します。
AWS Cloud9(以下、Cloud9)とは
オンラインの統合開発環境(IDE)で、AWSマネージドコンソール上でコード編集などが可能です。
AWSのリソースへのアクセスも簡単で、効率的に開発できます。
docs.aws.amazon.com
Cloud9 を起動する
AWS Cloud9 > Environments > Create environment
Details セクション
Name:任意の名前を入力
Network settings セクション
- Connection:Secure Shell (SSH)
- VPC:パブリックサブネットを持つVPCを選択
- Subnet:任意のパブリックサブネットを選択。(デフォルトVPCのサブネットはパブリックサブネットのため、デフォルトサブネットを選択でもOK)
Create
をクリック。
Cloud9 へ接続
数分後、Successfully created …
のメッセージが表示されたら環境作成が完了しています。
作成した環境の Open をクリックし、Cloud9へ接続します。
作業しやすいように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のパブリックレジストリへ登録されているコンテナイメージを実行できることを確認しました。
次は自分でコンテナイメージをビルドし、そのイメージを実行します。
Dockerfile を作成
以下の「Dockerfile」ファイルを作業環境のディレクトリ直下へ作成します。 - dockerfile
FROM php:8.0-apache COPY index.php /var/www/html EXPOSE 80
- FROM:ベースとなるイメージを宣言
- COPY:ローカルのファイルやディレクトリをDockerイメージ内の指定されたディレクトリにコピーします。ソースファイルとターゲットディレクトリを指定します
- EXPOSE:コンテナが実行された際に、コンテナ内で公開するポートを指定
Dockerfile」をダブルクリックし、先述の内容をペーストし、Command + Sで保存します。(Windowsの場合はCtrl + S)
index.php を作成
先程、ワンライナーで作成したindex.phpを内容を変えて作成します。
Dockerfile作成と同じ要領で以下の内容の「index.php」ファイルをディレクトリ直下へ作成します。
<?php echo 'Hello Container Self Build'; ?>
このindex.phpが、Dockerfileで指定した COPY index.php /var/www/html
の宣言によってコンテナ内の /var/www/html 配下へ配置される仕組みです。
作成したら、保存を忘れずに。
ビルドコマンドを実行
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 へプッシュします。
ECRリポジトリを作成
まずはプッシュ先となるECRのリポジトリを作成します。
Cloud9 IDE ナビゲーションバーから AWS アイコンを選択し、EXPLORER > Asia Pacific (Tokyo) を展開します。ECR メニューで右クリックし、Create Repository...
を選択します。
URLをコピー
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のコンテナイメージを実行
プッシュしたイメージを作業環境へプルして実行します。
確認しやすいようにまずは作業環境のイメージを全て削除します。コンテナの停止
コンテナを削除する前に、実行中のコンテナを停止します。
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マネジメントコンソールからも確認できます。
最後に
ECRへのコンテナイメージプッシュは基本的な作業ですが、AWSのコンテナサービスのベースとなる重要な部分です。
どなたかのお役に立てれば幸いです。