AWSのEC2でReactアプリをGithubからクローンして、EC2でアプリを起動するまで(nginx)

##環境
MacOS BigSur 11.2.3


##事前に
*[AWSのアカウント作成](https://aws.amazon.com/jp/register-flow)が終わっている方向けの内容です。
*[AWSアカウントの初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888)の内容も実施推奨です。

###補足
*本記事はEC2のlocalhost:3000で起動しているアプリをローカルのブラウザからアクセスして表示する目的となります。

##目的
・ローカルでcreate-react-appで作成したアプリをGithubへpush、
アプリをEC2にclone、ブラウザからEC2へのアクセスして、アプリを表示させます。
・シンプルな構造で、AWSの主要サービスの理解を深める。
・本編で作成した環境は今後も拡張していき学習の効率化を図る。


##以下の方が対象になります
[create-react-app](https://ja.reactjs.org/docs/create-a-new-react-app.html)でReactアプリ作成したことがある。
AWSのEC2でReactアプリを起動してみたい。
Git/Githubが使える。
簡単なvim操作ができる。


##1.VPCの作成
AWS [マネジメントコンソール](https://aws.amazon.com/jp/console/)からVPCを検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/cc0b79b1-f3b8-c880-f510-8e7ebcc8728d.png)
*VPCはAWSクラウド内に独自にネットワークを構築できるサービスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/40f90813-36f8-117a-c4ae-d26bb8a2b905.png)
VPCを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/5e43a808-731f-43f4-813f-5a192e998316.png)
VPCの名前は任意で構いませんが、今回はmy-react-vpc-1で作成し、
IPv4 CIDR ブロック情報は10.0.0.0/2としています。
その他の項目はデフォルト値で作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/6ce4c00b-6fc7-31f2-e748-3022131f62e6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/32cd6ae7-656b-6f0c-441e-3489500ee4de.png)

##2.パブリックサブネット作成
サイドバーメニューのサブネットから作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/8df377be-209b-deb3-ad6a-565140a4bc3b.png)
サブネット名はmy-react-public-subnet-1で作成します。
作成したVPCを選択、アベイラビリティゾーン(ap-northeast-1a)を選択。
*IPv4 CIDRブロックは10.0.0.0/24を指定します。
先ほどのVPCを指定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/9c31db25-9c18-68d6-dec5-08b6ad1ff479.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/3414c414-483c-42f8-4c43-b0cdc5f3f7a8.png)

##3.プライベートサブネットを作成
同様の手順で、サブネット名my-react-private-subnet-1で作成していきます。
本記事ではプライベートサブネットにEC2や[RDS](https://aws.amazon.com/jp/rds)は配置しませんが、今後の拡張のため作成しています。
作成したVPCを選択、アベイラビリティゾーン(ap-northeast-1a)を選択。
*IPv4 CIDRブロックは10.0.2.0/24を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/40d53903-9fee-01e4-c69e-2df44b6eb5c0.png)

##4.インターネットゲートウェイを作成
*インターネットゲートウェイはVPCとインターネット間の通信を可能にするために必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/bb3be56c-9fe1-4a01-bf30-6b393c3a6afc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/8b0bf5df-b58c-ae8c-690f-93aeddf40e13.png)
名前タグはmy-react-internet-gw-1を入力、
インターネットゲートウェイの作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/7181616b-a960-f3ff-28ed-f183867bad2a.png)
作成したゲートウェイは、すでに作成しているVPCにアタッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/eff70b42-5837-17a2-e92c-00024516a3d7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/6547381e-7ccb-0ccd-7361-85cb681caae6.png)

##5.EC2インスタンス作成
インスタンスを作成していきます。
*EC2はクラウド内で提供されるコンピューター(リソース)です。
後に作成するReactアプリはこのEC2にクローンします。
検索窓でEC2を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/dc041840-8972-3d0b-8d18-df17853b7245.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/540685fd-5f22-bc0c-27ef-3ae4735836b2.png)
インスタンスを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/5860c5d2-e334-5937-d6cd-8aaae377cb9f.png)
マシンイメージはAmazon Linux 2 AMIを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/071a6515-6b20-be92-34f4-9733d134a41d.png)
インスタンスタイプはt2.microを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/866dbadc-7ba3-ab9b-329f-5a1349241d25.png)
次のステップをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/ca806654-b1ac-5346-4912-1a5445944615.png)
続いて、ネットワークはVPCを選択し、サブネットはmy-react-public-subnet-1、
自動割り当てパブリックIPを有効にします。
その他の項目はデフォルト値で次のステップに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/95d80956-8bd8-a476-18e5-52ab59e5ba27.png)
ストレージの追加もデフォルト値で次のステップに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/960c87f5-a956-f6eb-f912-583f422e39f3.png)
次のステップでタグを追加します。キーにName、値はmy-react-web-server-1として次のステップへ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/743f2094-9854-2d38-9ebf-9f0b896ca597.png)
続いて、新しいセキュリティグループを作成します。
セキュリティグループ名と説明はmy-react-sg-1として、
ルールを追加します。
ルールはタイプにHTTPを指定、プロトコルはTCPを選択、ポートは80を指定します。
入力が終わったら、起動と確認へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/26036f5e-5404-6fa0-15ee-48bde6bb4cc1.png)
設定に間違いがないことを確認し、起動をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/cd08bcb3-3a65-121d-0ec7-fa0118499537.png)
インスタンスの起動前にキーペアの作成画面が表示されるので、キーペアを新規作成します。
作成したキーペアはご自身のPCに保存します。(*このキーファイルは安全な場所に保管してください)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/5353f20c-7bb5-44ab-740f-a4acde11a2d8.png)
インスタンスの作成をクリックしてインスタンスの表示をクリック。
実行中になっていればインスタンスの作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/9bb4413e-1523-5076-d153-62adf27ef4b1.png)

##6.ルートテーブルの編集
VPC IDがmy-react-vpc-1のルートテーブルを選択、
ルートの編集をクリックし、ルートを追加していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/7b3a4caa-3fdc-d975-89bf-d9067376a988.png)
追加するルートの送信先は0.0.0.0/0、ターゲットはInternet Gatewayを選択、
すでに作成しているmy-react-internet-gw-1を選択し、ルートを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/6d601b6e-af6a-b6fa-3a85-a8e6d5da53d5.png)

##7.作成したEC2でreactアプリを起動する

Gitを使うので事前にご自身のPCに[npm](https://qiita.com/rihofujino/items/818ce07e5eb72acafd5a)をインストールします。

```terminal:Terminal
npm install -g npm
```

####EC2にSSH接続
SSH接続する際に先ほど作成したプライベートキーファイルが必要になります。
このキーペアファイルは権限を変更しないとエラーになるので、あらかじめchmodで権限変更しておきます。

```terminal:Terminal
chmod 400 キーペアファイルのパス
chmod 400 Downloads/my-react-key-pare-1.pem
```

キーペアの権限が変更されているか確認します。

```terminal:Terminal
ls -l my-react-key-pare-1.pem
```

以下のように-r--------となっていれば権限変更されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/b3e7fc17-4400-f733-e419-8f484d6f7027.png)
EC2へ接続します。

```terminal:Terminal
ssh -i <キーファイルを指定> ec2-user@<EC2のパブリックIPv4アドレス>
ssh -i Downloads/my-react-key-pare-1.pem ec2-user@10.0.1.1
```

*EC2のパブリックIPv4アドレスはEC2コンソール画面から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/486fd8cc-1757-a593-f1a2-129d4ef4b3d4.png)
接続の際に以下の内容を聞かれるので、yesを入力します。

```
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
```

以下のEC2が表示されればSSH接続完了できてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/ebb8916a-1810-6d20-d93f-2108ab0e277d.png)

##EC2への外部からのアクセスをローカルホストにつなげるようにする
現在の設定ではアプリケーションをクローンして起動しても、
localhost:3000で起動することしかできないので、
nginx を使って「外部からのアクセスをローカルホストにつなげる」仕組みを用意します。
nginx をリバースプロキシとして用い、ポート80へのアクセスをlocalhostの3000ポートに振り向けるようにします。

###nginxをインストール
*EC2にSSH接続した状態で以下コマンドを実行します。
権限ユーザーの切り替え

```terminal:EC2
sudo su - root
```

EC2のパッケージをアップデート

```terminal:EC2
yum update -y
```

nginxをインストール

```terminal:EC2
yum install nginx -y
```

↑これを実行すると、nginx の install 時に Amazon Linux 2だとエラーになるので、
エラーメッセージの指示に従い、以下を実行。

```terminal:EC2
sudo amazon-linux-extras install nginx1.12
```

nginxを起動します。

```terminal:EC2
sudo systemctl start nginx.service
```

以下のコマンドでnginxのstatusを確認します。

```terminal:EC2
sudo systemctl status nginx.service
```

Acrive: active (running)となっていれば起動しています。

Gitをインストールします。

```terminal:EC2
sudo yum -y install git
```

#####*あらかじめ、ご自身のPCで[create-react-app](https://ja.reactjs.org/docs/create-a-new-react-app.html)でアプリを作成し、ご自身のGithubリポジトリへpushしてください。

##EC2にアプリをクローン

```terminal:EC2
git clone <https://github.com/<your sample app repository>
```

Githubのユーザー名とパスワードを聞かれるので入力してクローンします。

アプリケーションのビルドにnode.jsが必要なのでインストールします。

```terminal:EC2
curl -sL https://rpm.nodesource.com/setup_14.x | bash -
yum install -y nodejs
```

npmとnodeがインストールされていることを確認します。
下記のようにバージョンが表示されれば無事インストールされています。

```terminal:EC2
npm -v
6.13.4
node -v
v13.5.0
```

アプリケーションのディレクトリへ移動します。

```terminal:EC2
cd アプリケーションディレクトリ
```

必要なパッケージをインストールして、ビルドします。

```terminal:EC2
npm install
npm run build
```

##EC2でアプリケーションを実行しEC2のパブリックIPv4アドレスに接続。
アプリケーション起動

```terminal:EC2
npm run start
```

その後、ブラウザのアドレスバーにEC2のパブリックIPアドレスを入力してみる。

しかし、このままでは下記エラーが表示されてしまうので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/49dd6640-32be-b1d7-cc98-bdfad2a63a71.png)
EC2の下記パスにnginxの設定ファイルがあるのでvimで編集していきます。

```terminal:EC2
vim /etc/nginx/nginx.conf
```

以下のlocationを追加します。

```conf:/etc/nginx/nginx.conf
server {
        location / {
            # WEBリクエストをローカルホスト3000番ポートへリダイレクト
            proxy_pass http://localhost:3000/;
        }
    }
```

ファイルの編集が完了したらnginxを再起動します。

```terminal:EC2
sudo systemctl restart nginx
```

再度、アプリケーションを起動。

```terminal:EC2
npm run start
```

アプリが起動している状態で、対象のEC2インスタンスのパブリックIPv4アドレスを
ブラウザに入力してアクセスします。
ロゴが表示されれば成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637321/872560ad-cfee-247a-b432-75ad40eb96fc.png)

***
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
***