React/Next.jsアプリケーションを作成し、AWS EC2を使って本番環境にデプロイするまで

# 対象
* Next.js 等、Node.js で動かすアプリをローカル環境で作成することはできるが、それを本番環境で動かす方法と仕組みがわからない人
* Heroku や Zeit Now を使うと簡単にリリースできるが、その仕組がさっぱりわかっていない人

# この記事の存在意義
初心者が掲題のことをやろうと思ったときに、全体感を把握できる記事が見当たらなかったので、こういう記事があっても良いかなと思った。

# 流れ
以下のような手順で進める。
1. ローカル環境で動く Next.js を用いたサンプルアプリの作成
2. EC2 インスタンスの作成
3. EC2 インスタンス上でのサンプルアプリの起動&接続

# 1. ローカル環境で動く Next.js を用いたサンプルアプリの作成

* 事前に npm をインストール

```bash
npm install -g npm
```

* ↓の公式チュートリアルの Getting Started の部分を進める。
    * https://nextjs.org/learn/basics/getting-started/setup

* それ用の GitHub リポジトリを用意して、package.json と pages ディレクトリ は remote に push しておく。

# 2. EC2 インスタンスの作成
公式に従ってやっていく。
自分の環境から ssh できるようにしておき、かつ http 通信はできるようにしておく。

# 3. EC2 インスタンス上でのサンプルアプリの起動&接続


## 3.1 外部アクセスをローカルホストにつなげるようにする

外部からアクセスがあったときに、そのアクセスをサンプルアプリが受け取って結果を返さなければならない。
しかしここまでのところ、localhost:3000 でアプリケーションを起動することしかできていない
そこで、「外部からのアクセスを受けたらそれをローカルホストにつなげるような仕組みを用意する」ことにする。

nginx を使ってそれを実現する。すなわち、「nginx をリバースプロキシとして用い、ポート80へのアクセスをlocalhostの3000ポートに振り向ける」ようにする。

* ssh で EC2 インスタンスに入る。

```bash
ssh -i <key.pem>  <public ip address>
```

* nginx の install

```bash
sudo su - root
yum update -y
yum install nginx -y
```

↑これを実行すると、nginx の install 時に Amazon Linux 2だとエラーになる。

```bash
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
No package nginx available.
Error: Nothing to do


nginx is available in Amazon Linux Extra topics "nginx1.12" and "nginx1"

To use, run
# sudo amazon-linux-extras install :topic:

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras
```

エラーメッセージの指示に従う。

```bash
sudo amazon-linux-extras install nginx1.12
```

* nginx の起動

```bash
sudo systemctl start nginx.service
```

この時点で、ブラウザからアクセスすると以下のような状態になっているはず。

![スクリーンショット 2020-01-03 4.09.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183649/56036926-63c5-4a0f-153f-34f2640fafea.png)


* nginx の設定変更(リバースプロキシの設定)

```conf
# 〜省略〜
http {
    # 〜省略〜
    server {
        # 〜省略〜
        location / {
            # 以下の行を追加
            proxy_pass http://localhost:3000;
        }
        # 〜省略〜
    }
}
```

この1行を追加することにより、ローカルホストの port:3000 に向けることができるようになる。ただし、nginx の設定を反映させるために nginx を再起動させることを忘れてはならない。

* nginx の再起動

```bash
sudo systemctl restart nginx
```

この時点で、ブラウザからアクセスすると以下のような状態になっているはず。
![スクリーンショット 2020-01-03 4.18.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183649/57dc1d25-2eb2-d059-7db8-8776428c2cee.png)


これはまだサンプルアプリを起動しておらず、振り向けた先から応答が返ってこないから。


## 3.2 サンプルアプリの起動

* ssh で EC2 インスタンスに入る(既に入っていればそのままでOK)。

```bash
ssh -i <key.pem>  <public ip address>
```

* git の install

```bash
sudo yum -y install git
vim ~/.ssh/id_rsa  # 自分のローカルのものをコピーしてくる
chmod 400 ~/.ssh/id_rsa
git clone https://github.com/<your sample app repository>
```

* npm/node の install(公式のダウンロード方法は[こちら](https://github.com/nodesource/distributions#rpminstall))

```bash
sudo su - root
curl -sL https://rpm.nodesource.com/setup_13.x | bash -
yum install -y nodejs
```

* 確認

```bash
$ npm -v
6.13.4
$ node -v
v13.5.0
```

* アプリケーションのビルド

```bash
cd <your repository>
npm install
npm run build
```

* アプリケーションの実行


```bash
npm run start
```

ブラウザから見てみると、以下のように適切に表示されているはず！

![スクリーンショット 2020-01-03 4.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183649/f82b3c07-ee14-da60-dccc-9ef4b8c6c66a.png)


# まとめ
個人開発の際、なるべく早めに本番環境へのデプロイができることを確認しておくと、(不慣れな方は特に)不確実性を(そして心理的不安を)大きく減らすことができるかと思います。
まだ問題の切り分けを行いやすい最初のうちにこそ、本番環境でのデプロイを一度試してみることをおすすめします。