AWSでDockerコンテナを起動させる方法

## 目的
AWSのEC2でDockerで動かしていたプロジェクトを起動させ、アプリをHostingすること。

## 目次
1. EC2 Instanceを起動
1. SSHでInstanceに接続
1. GitとDockerをインストールする
1. 事前にBuildしたイメージを使うか、EC2でBuildするか
1. RepositoryをcloneしてDockerイメージをBuildする方法
1. Docker Hubからイメージをダウンロードする方法
1. コンテナを立ち上げる
1. セキュリティグループを設定する

## EC2 Instanceを起動
まずはこれから使うクラウド上のEC2 Instanceを立ち上げます。

EC2は、AWSでいう巨大な機械の最も基礎的な部品です。クラウド上で仮想コンピューターを作ってくれるサービスです。

![スクリーンショット 2021-12-17 9.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/73974fa8-ac83-5d1f-867a-aa150d94caa5.png)
インスタンスを起動をクリックします。
![スクリーンショット 2021-12-17 9.51.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/52f43737-3640-a4fa-3008-38a002d8677f.png)
マシンイメージを選択します。Linux、Windows、Macまでも選べますが、AWSのまーさる機能が込み込みのAmazon Linuxを使いたいので、一番上のKernel 5.10を選びましょう。
![スクリーンショット 2021-12-17 9.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/d209c465-3621-8ee6-9f3e-0c7e1698730e.png)
次はインスタンスタイプを指定します。これは、どれぐらいの資源を割り当てるかを決めるところですが、今回は無料枠を使いたいので、初期値のt2.microを使います。
機械学習とか、画像処理とか、多くのCPU資源を要するプロジェクトだったらここでその割り当てができます。
![スクリーンショット 2021-12-17 9.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/a80b5e91-df74-3810-be45-484f99d5589a.png)
次は詳細の設定でネットワーク設定を行いますが、下記のネットワークの部分にデフォルトの選択肢を選びます。なければ、新しいVPCの作成をクリックして作ってください。
![スクリーンショット 2021-12-17 9.58.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/e9e0d830-5c36-8952-ad12-7d400820b8ab.png)
他の設定は変えなくてもいいので、そのまま確認と作成をクリックします。
![スクリーンショット 2021-12-17 10.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/299757c0-8848-84c3-17cd-2b6fdeb5113b.png)
そして次のページでネットワークのセキュリティがやばいけど？という警告は出ます。これは、Instanceへの接続をどのIPアドレスからも許可しているからです。今度、アクセスができるIPアドレスを指定する方法について解説します。今回はそのままで起動をクリック。
![スクリーンショット 2021-12-17 10.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/43bcfe25-b3fd-0b05-757a-a521baebfcdd.png)
次の手順は非常に重要です。SSHで接続するには、キーペア（RSA鍵）が必要です。
新しいキーペアを作成し、名前をつけて、ダウンロードしましょう。この鍵を持っていれば、誰でも接続できる状態になっているので、扱いにご注意ください。
ダウンロードできたら、作成ボタンをクリックします。
![スクリーンショット 2021-12-17 10.03.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/6f9d6adb-dfd2-6ef5-e753-b5d8ed237014.png)
インスタンスが起動するまで待ちます。起動できたらこのような画面が確認できます。
![スクリーンショット 2021-12-17 10.07.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/3d02910a-2a54-9fb7-6cf6-c7b58a95a703.png)

## SSHでInstanceにアクセスする
まずダウンロードしたキーペア.pemファイルをユーザーのrootダイレクトリーに入れます。
Mac OSの場合だと、/Users/{ユーザー名}のところです。
それからTerminal（ターミナル）を開き、以下のCommandを実行

rootのダイレクトリーに念のために戻る

```
cd ~
```
ダウンロードした.pemファイルを隠れフォルダーの.sshに入れます。

```
mv next-socketio-chat.pem .ssh/
```

次、.pemファイルの権限をchownでお使いのパソコンのユーザーに直さないと読めないので、以下のCommandを実行します。

```
cd .ssh/
chmod 400 next-socketio-chat.pem 
```
これでこのキーペアが使えるので、接続してみましょう。 -i で.pemファイルを接続するときに使うように指定します。00-00-00-00のところは自分のパブリックIPv4アドレスを入れてください。

```
ssh -i "next-socketio-chat.pem" ec2-user@ec2-00-00-00-00.ap-northeast-1.compute.amazonaws.com
```
これで、この画面が出てきて、EC2に入れたぞ！ってことがわかって、喜ぶ場面になり、ティッシュで涙を拭い、下記を読み続けます。
![スクリーンショット 2021-12-17 10.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/86f34f9f-4781-035c-0ddf-df7a834d843e.png)

## GitとDockerをインストール
EC2のAmazon Linuxはyumでパッケージをインストールします。
一番最初にパッケージのアップデートをした方がいいので、以下のCommandを実行します。 -y はYes・Noを聞かれる時に全部Yesで答えといてくれよーという意味を持っています。

```
sudo yum update -y
```
次、Gitをインストールします。

```
sudo yum install git -y
```
並びに、Dockerを。だけど、ここは普通のインストールじゃなくて、AWSのサービスを通してインストールすると楽なので、以下のCommandを実行します。

```
sudo amazon-linux-extras install docker
```
GitもDockerも無事にインストールされたことを以下のCommandで確認できます。

```
docker --version
git --version
```
DockerのServicesを起動させます。

```
sudo service docker start
```
ここまでくると、Dockerが普通に使えます。dockerのCommandの前にsudoを付ける必要があります。

## 事前にBuildしたイメージを使うか、EC2でBuildするか
進む前に、少し解説したいです。
EC2にイメージを持ってくるのに二つのやり方があります。
1. EC2上にソースコードをGitなどでcloneし、そこでBuildする方法
1. ローカルのパソコンで作ったイメージをDocker Hubなどにアップロードして、EC2でそれをダウンロードする方法

筆者は後者の方法をお勧めします。なぜなら、イメージを実行するのは環境に依存しないが、イメージをBuildするのは環境に依存することがあるからです。
Dockerでそういった悩みを解決したわけだし、せっかくローカルで駆動実験を行ったわけだから、それをそのまま使いたいでしょう？

しかし、ネット環境が悪かったりして、イメージをアップロードするのはめんどいということもあるだろうから、両方の方法をご紹介しましょうね。

## RepositoryをcloneしてDockerイメージをBuildする方法
これから筆者が前回の記事で作ったNextアプリを使います。
https://qiita.com/tronicboy/items/7969a77817d8f2706b52

GitHubからソースコードをgitでcloneします。

```
git clone https://github.com/tronicboy1/next-socket.io-chat.git
```
そしてnext-socket.io-chatのフォルダーに入ってイメージをBuildします。

```
cd next-socket.io-chat/
sudo docker build -t next-socketio-chat .
```
このメッセージが表示されれば、無事にBuildできました！
![スクリーンショット 2021-12-17 10.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/5a57b98e-b9af-6a27-824b-1ccf0146cec4.png)


## Docker Hubからイメージをダウンロードする方法
もう一つのやり方があります。それは、Dockerイメージを事前にBuildして、Docker Hubなどにアップロードしたものを、EC2 Instanceにダウンロードする方法です。

今回は筆者がアップロードしたイメージを使いましょう。
https://hub.docker.com/repository/docker/tronicboy/next-socket.io-chat

以下のCommandを実行すればダウンロードされます。

```
sudo docker pull tronicboy/next-socket.io-chat:latest
```
ちなみに、次のdocker runのCommandを実行する時点で上記のイメージがダウンロードされていなければ、Dockerが自動でPullしてくれるので、正直にいうとこれは不要です。

とりあえず、イメージがあることを確認しましょう。

```
sudo docker images
```
![スクリーンショット 2021-12-17 11.10.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/432ba85a-1517-7557-1926-c120a235ca03.png)
バッチリ大丈夫やっさー

## コンテナを立ち上げる
次はEC2上でコンテナを作って実行します。

```
sudo docker run -d --rm -p 80:3000 tronicboy/next-socket.io-chat
```
EC2側のPortは80番で、Nodeはソースコードで指定している3000番。EC2側でPortの80番を使うのは、下記のセキュリティグループ設定でわかりますが、外部からのHTTPリクエストは80番のみが許可される仕組みになっているからです。

## セキュリティグループを設定する
今、Dockerでアプリを立ち上げて、よし！開けてみよう！と思ったら、ちょっと待った！今パブリックのIPアドレスで開こうとしてもつながりません。

セキュリティーグループで設定をしないと無理です。

まず、AWSで先ほど作成したInstanceの管理画面の下の方でセキュリティのタブをクリックして、セキュリティグループへのリンクをクリックします。
![スクリーンショット 2021-12-17 11.23.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/02aaf0c0-cae9-1049-6eaa-415650eb29cb.png)
「インバウンドルールを編集」をクリックします。
![スクリーンショット 2021-12-17 11.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/a6a15431-0fb3-e9c4-07b0-47768532f26f.png)
今表示されているのはPortの22番でSSHのための接続を許可するルールです。HTTPリクエストを許可するルールを追加したいので、追加をクリックします。
![スクリーンショット 2021-12-17 11.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/719ef694-e03c-98d1-dc75-1cfecdfe3c4f.png)
そして以下のように設定を変えて、保存します。
![スクリーンショット 2021-12-17 11.30.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/db14ce7b-5531-fe45-9214-7b05c1f99479.png)
そうするとパブリックのIPv4アドレスでアクセスすると、見事に顔を出してくれます！
![スクリーンショット 2021-12-17 11.32.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/18892aa8-a6a7-6cd7-c447-20529adf85d4.png)

## まとめ
以上、最も簡単なやり方でDockerのイメージをEC2上で起動させ、外部からアクセスできるようにしました。

dockerの前にsudoを使わんといけんかったり、実はこの辺にEC2の大事なことが秘められているのですが、今回はそれらについて触れてないです。

これからはより洗練されたやり方について記事を書いていきたいと思っています。