Dockerを使用してコンテナを作成し、AWSのECS（Elastic Container Service）にデプロイする基本手順

Dockerコンテナの基本的な使い方をまとめました。
コンテナにハードルを感じている方々が、「なんだ、簡単じゃん」と感じてくれて、
コンテナの活用が進むと幸いです。

今回の構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/d3a2bf96-efd7-e05e-4590-9696c2d37701.png)


Dockerを使用してコンテナを作成し、AWSのECS（Elastic Container Service）にデプロイする手順
--

1 . **Dockerfileの作成**
Dockerfileに必要な指定内容を入力。

2 . **コンテナイメージの作成**
`docker build`コマンドを使用して、Dockerfileからコンテナイメージを作成。

3 . **ECRへのコンテナイメージのアップロード**
`docker login`コマンドを使用して、ECRにログイン。
`docker push`コマンドを使用して、ECRにコンテナイメージをアップロード。

 ★ECRの使い方は、以前記載したブログをご参考にしてください。
 ④ECRにdockerイメージを登録する
 https://qiita.com/kimuni-i/items/54249bf7d8620280fd2c

4 . **クラスターの作成**
AWSのECSコンソールから新しいクラスターを作成。

5 . **タスク定義の作成**
ECSコンソールからタスク定義を作成し、必要な設定を行います。

6 . **クラスターへのサービスのデプロイ**
ECSコンソールから新しいサービスをデプロイします。
必要なタスク数を設定し、ロードバランサーで新しいターゲットグループとして設定します。

__前提条件docker環境が用意されている事
(Cloud9には、既に環境が用意されているので、環境作成の手間は、かからない)__

Dockerが使える状態であるのかを確認
--
docker コマンドの確認
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker version
Client:
 Version:           20.10.25
 API version:       1.41
 Go version:        go1.20.12
 Git commit:        b82b9f3
 Built:             Fri Dec 29 20:37:18 2023
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.25
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.20.12
  Git commit:       5df983c
  Built:            Fri Dec 29 20:38:05 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.11
  GitCommit:        64b8a811b07ba6288238eefc14d898ee0b5b99ba
 runc:
  Version:          1.1.11
  GitCommit:        4bccb38cc9cf198d52bebf2b3a90cd14e7af8c06
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
Admin_8fd6cc7b33f6a9f5:~/environment $
~~~

1.Dockerfileの作成
--
__Dockerfile に以下の内容を入力する__

~~~
#作成するコンテナイメージの基となるベースイメージは DockerHub で公開されている Ubuntu 18.04
ここで指定する
FROM ubuntu:18.04

# Install dependencies
# Web サーバーとして Apache HTTP Server をインストール
RUN apt-get update && \
 apt-get -y install apache2

# Install apache and write hello world message
# 'Hello World!'と表示するindex.htmlファイルを作成する
RUN echo 'Hello World!' > /var/www/html/index.html

# Configure apache
RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && \
 echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh && \
 echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh && \ 
 echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh && \ 
 chmod 755 /root/run_apache.sh

#コンテナが利用するネットワークポートを指定　ポート80 http通信
EXPOSE 80

#コンテナ実行時に動かすコマンド
#Webサーバを起動するシェルスクリプト
CMD /root/run_apache.sh
~~~
参考 AWS Document : https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html

HTML ファイルから Dockerfile の文字列を張り付けるときに、ノーブレークスペースが入ることがある。これがあると正常に稼働しないため、以下の sed コマンドでノーブレークスペースを削除する
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ sed -i "s/$(echo -ne '\u200b')//g" Dockerfile
~~~

既に存在している DockerImage の一覧を確認
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
~~~
現状、何もないことがわかる

2.コンテナイメージを作成
--
docker build コマンドを実行することで、Dockerfile で設定した内容を基に、コンテナイメージを作成

-t : 作成するコンテナイメージに指定したタグを付与。
hello-world というわかりやすいタグを指定
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker build -t hello-world .
Sending build context to Docker daemon  9.288MB
Step 1/6 : FROM ubuntu:18.04
18.04: Pulling from library/ubuntu
7c457f213c76: Pull complete 
Digest: sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Status: Downloaded newer image for ubuntu:18.04
 ---> f9a80a55f492
Step 2/6 : RUN apt-get update &&  apt-get -y install apache2
 ---> Running in 02d0c76cd3bc
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
・・・
Processing triggers for libc-bin (2.27-3ubuntu1.6) ...
Removing intermediate container 02d0c76cd3bc
 ---> 3eaea64c4ace
Step 3/6 : RUN echo 'Hello World!' > /var/www/html/index.html
 ---> Running in fd4b9bc73ad4
Removing intermediate container fd4b9bc73ad4
 ---> 4f54400202cc
Step 4/6 : RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh &&  echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh &&  echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh &&  echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh &&  chmod 755 /root/run_apache.sh
 ---> Running in f8132314a3a9
Removing intermediate container f8132314a3a9
 ---> ed08c62a508b
Step 5/6 : EXPOSE 80
 ---> Running in f892873fd1ee
Removing intermediate container f892873fd1ee
 ---> 2b6a40c5c729
Step 6/6 : CMD /root/run_apache.sh
 ---> Running in d8129f714c30
Removing intermediate container d8129f714c30
 ---> 3ce3f58ab047
Successfully built 3ce3f58ab047
Successfully tagged hello-world:latest
~~~

作成されたことを確認するために、DockerImage の一覧を確認
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker images 
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
hello-world   latest    3ce3f58ab047   30 seconds ago   205MB
ubuntu        18.04     f9a80a55f492   10 months ago    63.2MB
~~~

現在なにもコンテナを動かしていないことを確認するために、docker ps コマンドを実行する
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker ps                                                                                                                     
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
~~~

コンテナを動かす
--
Dockerコンテナを起動し、その動作を確認する

~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker run -d -p 8080:80 --name Hello-local-run hello-world
5ed45c17eee0d4747ea015c047dc2c4e61df5b5f0fa025c7846c1c437bd673af
~~~
このコマンドは、hello-worldというイメージからHello-local-runという名前のコンテナを作成し、バックグラウンドで実行します。また、ホストの8080番ポートとコンテナの80番ポートをマッピングします。

~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                                   NAMES
5ed45c17eee0   hello-world   "/bin/sh -c /root/ru…"   11 seconds ago   Up 11 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   Hello-local-run
~~~
現在実行中のDockerコンテナを表示するコマンドです。結果として、Hello-local-runという名前のコンテナが8080番ポートで実行中であることが示されます。

~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ curl localhost:8080
Hello World!
~~~
ホストの8080番ポートにHTTPリクエストを送信してレスポンスを取得するコマンドです。結果として、"Hello World!"というレスポンスが返され、コンテナが正常に動作していることが確認されます。

~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                                   NAMES
5ed45c17eee0   hello-world   "/bin/sh -c /root/ru…"   3 minutes ago   Up 3 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   Hello-local-run
~~~
コンテナがまだ実行中であることを確認します。

docker exec コマンドを実行して、コンテナの中身を確認
--
NAMES で確認した名前を指定
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker exec -i -t Hello-local-run bash
root@5ed45c17eee0:/# pwd
/
root@5ed45c17eee0:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@5ed45c17eee0:/# ls -la
total 8
drwxr-xr-x   1 root root   28 Apr  8 01:24 .
drwxr-xr-x   1 root root   28 Apr  8 01:24 ..
-rwxr-xr-x   1 root root    0 Apr  8 01:24 .dockerenv
drwxr-xr-x   2 root root 4096 May 30  2023 bin
drwxr-xr-x   2 root root    6 Apr 24  2018 boot
drwxr-xr-x   5 root root  340 Apr  8 01:24 dev
drwxr-xr-x   1 root root   66 Apr  8 01:24 etc
drwxr-xr-x   2 root root    6 Apr 24  2018 home
drwxr-xr-x   1 root root   45 May 23  2017 lib
drwxr-xr-x   2 root root   34 May 30  2023 lib64
drwxr-xr-x   2 root root    6 May 30  2023 media
drwxr-xr-x   2 root root    6 May 30  2023 mnt
drwxr-xr-x   2 root root    6 May 30  2023 opt
dr-xr-xr-x 186 root root    0 Apr  8 01:24 proc
drwx------   1 root root   27 Apr  8 01:22 root
drwxr-xr-x   1 root root   33 Apr  8 01:24 run
drwxr-xr-x   2 root root 4096 May 30  2023 sbin
drwxr-xr-x   2 root root    6 May 30  2023 srv
dr-xr-xr-x  13 root root    0 Apr  8 01:24 sys
drwxrwxrwt   1 root root    6 Apr  8 01:22 tmp
drwxr-xr-x   1 root root   53 May 30  2023 usr
drwxr-xr-x   1 root root   17 Apr  8 01:22 var
root@5ed45c17eee0:/# cd /root 
root@5ed45c17eee0:~# ls -la
total 12
drwx------ 1 root root   27 Apr  8 01:22 .
drwxr-xr-x 1 root root   28 Apr  8 01:24 ..
-rw-r--r-- 1 root root 3106 Apr  9  2018 .bashrc
-rw-r--r-- 1 root root  148 Aug 17  2015 .profile
-rwxr-xr-x 1 root root  108 Apr  8 01:22 run_apache.sh
root@5ed45c17eee0:~# cat run_apache.sh
. /etc/apache2/envvars
mkdir -p /var/run/apache2
mkdir -p /var/lock/apache2
/usr/sbin/apache2 -D FOREGROUND
root@5ed45c17eee0:~# cd /var/www/html/
root@5ed45c17eee0:/var/www/html# ls -la
total 4
drwxr-xr-x 1 root root 24 Apr  8 01:22 .
drwxr-xr-x 1 root root 18 Apr  8 01:22 ..
-rw-r--r-- 1 root root 13 Apr  8 01:22 index.html
root@5ed45c17eee0:/var/www/html# cat index.html
Hello World!
root@5ed45c17eee0:/var/www/html# exit
exit
~~~

:::note info
__run_apache.shの内容を確認すると、
dockerfileで記載したものと同じ内容のものがある事がわかる。__
:::

3.コンテナイメージを、ECR にアップロードする
--
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker build -t アカウントid.dkr.ecr.ap-northeast-1.amazonaws.com/Hello-ecs-helloworld0408:0.0.1 .
Sending build context to Docker daemon  9.288MB
Step 1/6 : FROM ubuntu:18.04
 ---> f9a80a55f492
Step 2/6 : RUN apt-get update &&  apt-get -y install apache2
 ---> Using cache
 ---> 3eaea64c4ace
Step 3/6 : RUN echo 'Hello World!' > /var/www/html/index.html
 ---> Using cache
 ---> 4f54400202cc
Step 4/6 : RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh &&  echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh &&  echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh &&  echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh &&  chmod 755 /root/run_apache.sh
 ---> Using cache
 ---> ed08c62a508b
Step 5/6 : EXPOSE 80
 ---> Using cache
 ---> 2b6a40c5c729
Step 6/6 : CMD /root/run_apache.sh
 ---> Using cache
 ---> 3ce3f58ab047
Successfully built 3ce3f58ab047
Successfully tagged アカウントid.dkr.ecr.ap-northeast-1.amazonaws.com/Hello-ecs-helloworld0408:0.0.1
Admin_8fd6cc7b33f6a9f5:~/environment $ docker images 
REPOSITORY                                                                 TAG       IMAGE ID       CREATED          SIZE
hello-world                                                                latest    3ce3f58ab047   28 minutes ago   205MB
アカウントid.dkr.ecr.ap-northeast-1.amazonaws.com/Hello-ecs-helloworld0408   0.0.1     3ce3f58ab047   28 minutes ago   205MB
ubuntu                                                                     18.04     f9a80a55f492   10 months ago    63.2MB
~~~

ECR にアップロードするために、docker login 
--
--password-stdin には、コンテナレジストリからコピーしてきた URL のうち、スラッシュ(/)より前の部分を指定する
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ aws ecr get-login-password | docker login --username AWS --password-stdin アカウント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
~~~

docker push で ECR に作成したコンテナイメージをアップロード
~~~
Admin_8fd6cc7b33f6a9f5:~/environment $ docker push アカウントid.dkr.ecr.ap-northeast-1.amazonaws.com/Hello-ecs-helloworld0408:0.0.1 
The push refers to repository [アカウントid.dkr.ecr.ap-northeast-1.amazonaws.com/Hello-ecs-helloworld0408]
bf74da574259: Pushed 
3947945c0619: Pushed 
89111c7b09f4: Pushed 
548a79621a42: Pushed 
0.0.1: digest: sha256:d6ff2816c249e31520c66b1d006f885a64f0ed563a6a9aced0224ce2f7688026 size: 1155
~~~

4.クラスターを作成
--
![ECSクラスターを作成する.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/6a08d05a-f7ac-12ba-7431-714511650953.png)

5.タスク定義を作成する
--
![タスク定義を作成する1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/87c72ae6-9b99-26e5-c400-c29528f75ba0.png)

タスク定義の設定箇所
![タスク定義を作成する1 設定箇所.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/e0dcf8b5-fb88-5cd8-5a0b-6f92591fc05c.png)

__イメージURIには、先程ECRにプッシュしたイメージを記載する__

6.クラスターにサービスをデプロイ
--
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/796272c9-a009-c3c7-b82d-927632d06258.png)

作成ボタンからデプロイの設定を行う
![デプロイ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/bbf53290-798f-cf22-d44b-f4a2d098bf1e.png)

必要なタスクは、2つとし、
![必要なタスクを２つデプロイする.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/2167f4ff-5d4f-56f7-da82-bbcb183af05f.png)

ロードバランサで、新しいターゲットグループとして設定
![ロードバランサ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/2e59ffc6-8c10-5461-c37c-f6330c4606e8.png)

以上で完了です。意外と簡単です。