4
3

More than 3 years have passed since last update.

【Node.js】LINE MessageAPIで作った天気予報アプリをAWSでデプロイしてみる!

Last updated at Posted at 2021-06-22

先日、Node.jsでアプリを天気予報アプリを作成しました。

この記事内ではデプロイは、Glitchを使いました。

まぁ無料なわけで色々問題があります。
・プロジェクトは、利用されていないときは5分でスリープ状態になる
・4000件/1hのリクエスト制限がある(Error: 429 too many requests)

ということでAWSにデプロイすることにします。
それではアーキテクチャに関してみていきましょう。

アーキテクチャ

Architecture.png

ちなみにAWSのアーキテクチャなどを作るときは、drawioがおすすめです。
VSCodeから使えるので是非使ってみてください。

ハンズオン

1. AWSへログイン

2. 東京リージョンになっていることを確認

スクリーンショット 2021-05-01 14.21.09.png

3. VPCを作成(IP:10.0.0.0/21)

■ルート
コンソールで「VPC」と検索→左ペイン内の「VPC」を選択→「VPCを作成」を選択

スクリーンショット 2021-06-22 9.05.16.png

4. サブネットを作成(IP:10.0.0.0/24, 10.0.1.0/24)

■ルート
コンソールで「VPC」と検索→左ペイン内の「サブネット」を選択→「サブネットを作成」を選択

Public Subnetを作成(IP:10.0.0.0/24, 10.0.1.0/24)

Node.jsで使うサブネットを作成します。

スクリーンショット 2021-06-22 9.06.36.png

スクリーンショット 2021-06-22 9.07.10.png

5. Publicサブネットをインターネットに接続するためにInternet Gatewayを作成しアタッチする

■ルート
コンソールで「VPC」と検索→左ペイン内の「インターネットゲートウェイ」を選択→「インターネットゲートウェイの作成」を選択

スクリーンショット 2021-06-22 9.07.49.png

「VPCへアタッチ」をクリックする

スクリーンショット 2021-06-22 9.08.05.png

作成したVPCにアタッチします。

スクリーンショット 2021-06-22 9.10.01.png

6. EC2がインターネット接続するためにルートテーブルを作成

■ルート
コンソールで「VPC」と検索→左ペイン内の「サブネット」を選択→「Node-Pub-1」を選択→「ルートテーブル」を選択→「ルート」へ移動→「ルートを編集」を選択

スクリーンショット 2021-06-22 9.11.34.png

7. Publicサブネット内にEC2を構築

■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスを起動」を選択

■ステップの流れ

Amazon Linux 2 AMI (HVM), SSD Volume Typeを選択
t2.microを選択
③インスタンスの詳細の設定の、ネットワーク, サブネット, 自動割り当てパブリックIPを変更

スクリーンショット 2021-06-22 9.14.05.png

④ストレージはそのままでOK
⑤キーをNameで追加(値は任意でOK)

スクリーンショット 2021-06-16 13.15.42.png

⑥セキュリティーグループを変更

Node.jsは、TCPの3000番ポートでリクエストを受けるので、Security Groupに追加します。
スクリーンショット 2021-06-22 9.16.54.png

⑦キーペアの作成

私は事前に作成しているキーペアがあるのでそちらを使います。
このキーペアはdesktopにでも保存しておきましょう。
スクリーンショット 2021-06-16 13.17.03.png

以前書いたEC2の記事です。
基本的な内容になっているのでEC2ってなんやねんって方は見てもらえると!

8. EC2のIPアドレスを固定するためにElastic IPを導入する

IPアドレスを固定する理由としては、インスタンスを再起動しても同じIPアドレスに固定しておきたいためです。

通常、インスタンスを再起動するとIPアドレスが変わってしまいます。
それでは再起動する度にSSH接続の設定を変えないといけないため、IPアドレスを固定します。

ちなみに、Elastic IPは関連づけを行わなければ費用が発生します。
その点はご注意ください。

■ルート
コンソールで「EC2」と検索→左ペイン内の「Elastic IP」を選択→「Elastic IPアドレスの割り当て」を選択

スクリーンショット 2021-06-22 9.20.34.png

作成できたら次は関連づけを行います。

スクリーンショット 2021-06-22 9.20.53.png

スクリーンショット 2021-06-22 9.21.54.png

9. SSH接続でログイン

ターミナルを開きましょう。

ターミナル
// ①キーペアがあるところへ移動
$ cd desktop

// ②キーペア発見
$ ls -l Keypair.pem
-rw-r--r--@ 1 ryo  staff  1704  5  1 14:38 Keypair.pem

// ③権限を400に変更
$ chmod 400 Keypair.pem

// ④SSH接続
$ ssh -i Keypair.pem ec2-user@(パブリックIPアドレス)

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

これでEC2にログインできました。
それでは動作するために必要なものをまとめてみましょう。


  • パッケージのアップデート

  • g++コンパイラのインストール

  • Gitのインストール

  • nvmのインストール


    • nvmのダウンロード

    • nvmのパスを通す

    • nvmコマンドのパス設定


  • Node.jsをインストールする

  • GitHubからソースコードをクローン


    • 環境設定ファイルの準備

    • node_modulesなどをダウンロード

    • インスタンスが起動したら自動的にアプリケーションが起動するようにする


結構やることは多いですがそんなに難しくないので頑張りましょう!

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

まずはパッケージのアップデートを以下のコマンドで行います。

ターミナル
$ sudo yum update -y

g++コンパイラのインストール

Nodeモジュールのコンパイルなどに使います。

ターミナル
$ sudo yum -y install gcc-c++

Gitのインストール

後述するnvmのインストールや、リポジトリのダウンロードに使います。

ターミナル
$ sudo yum -y install git

nvmのインストール

nvmのダウンロード

Githubからnvmをクローンします。

ターミナル
$ git clone https://github.com/creationix/nvm.git ~/.nvm
nvmのパスを通す

これでどこからでもnvmが使えるようになります。(しかし後述の作業をしなければ毎回SSH接続するたびこの作業が必要になります)

ターミナル
$ source ~/.nvm/nvm.sh
nvmコマンドのパス設定

このままだとログアウトすると、nvmへのパスがリセットされます。
つまりnvmコマンドが使用できなくなり、その度にパスを通す必要があります。
そこで、Linuxにログインしたときに実行される.bash_profileに設定をします。

ターミナル
$ vi .bash_profile

以下のテキストを追記してください。

# nvm
if [[ -s ~/.nvm/nvm.sh ]] ; then
    source ~/.nvm/nvm.sh ;
fi

vim初心者の方はこちらの記事で操作方法を確認してください。

Node.jsをインストールする

まずはインストール可能なNode.jsのバージョンを確認しましょう。

ターミナル
$ nvm ls-remote
(省略)
v14.14.0
v14.15.0   (LTS: Fermium)
v14.15.1   (LTS: Fermium)
v14.15.2   (LTS: Fermium)
v14.15.3   (LTS: Fermium)
v14.15.4   (LTS: Fermium)
v14.15.5   (LTS: Fermium)
v14.16.0   (LTS: Fermium)
v14.16.1   (LTS: Fermium)
v14.17.0   (LTS: Fermium)
v14.17.1   (Latest LTS: Fermium)
v15.0.0
(省略)

2021年6月22日現在の最新のLTSはv14.17.1ということなのでこちらを使います。
ではインストールしましょう!

ターミナル
$ nvm install 14.17.1
Downloading and installing node v14.17.1...
Downloading https://nodejs.org/dist/v14.17.1/node-v14.17.1-linux-x64.tar.xz...
######################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v14.17.1 (npm v6.14.13)
Creating default alias: default -> 14.17.1 (-> v14.17.1)

では使用するバージョンの指定を行います。

ターミナル
$ nvm use v14.17.1
Now using node v14.17.1 (npm v6.14.13)

最後に確認作業を行います。

ターミナル
$ node -v
v14.17.1

GitHubからソースコードをクローン

ターミナル
// GitHubからソースコードをクローンをする準備
// ディレクトリを作成して移動する
$ sudo mkdir /var/www
$ cd /var/www

// アクセス権限を変更
$ sudo chmod 777 .

// GitHubからソースコードをクローン
$ git clone https://github.com/ssk9597/LINE-Node-Weather.git

// アクセス権限を変更して誰でも書き込みできないようにする
$ sudo chmod 0755 .

この後は.envnode_modulesのダウンロードなどを行います。
なのでディレクトリの移動をしましょう。

ターミナル
[ec2-user@ip-10-0-0-61 www]$ cd LINE-Node-Weather
環境設定ファイルの準備

.env.exampleの値は仮なので.envの値は修正しましょう。

ターミナル
// .env
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ cp .env.example .env
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ vi .env
node_modulesなどをダウンロード

GitHubからクローンしてもnode_modulesは付属してきません。
その理由としてはそもそもnode_modulesはパッケージの根幹機能がまとまったディレクトリになります。

そのため、バージョンが同じであれば同じ内容になります。
しかも容量が大きいためGitHubにアップロードするのは非効率です。

なので個別にダウンロードする必要があります。

ターミナル
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ npm install
インスタンスが起動したら自動的にアプリケーションが起動するようにする

Node.jsのアプリを起動するには、node api/index.jsを実行する必要があります。
しかしこれだとサーバーに接続した状態じゃなければサーバーが止まってしまいます。
なので、PM2というプロセスマネージャーを利用してアプリの自動起動を行いましょう。

簡単にPM2の説明をしておきます。
PM2はKeymetrics社によって開発が行われているNode.jsアプリケーションのプロセス管理を行うためのオープンソースです。
プロセスをデーモン化し、シェルを抜けてもアプリケーションが終了していた、ということが起きなくなります。

PM2は、PayPal、Microsoft、IBM、SOUTHWEST.COMなどのアプリケーションの1部で利用されているようです。

ターミナル
// PM2のインストール
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ npm install pm2@latest -g

// api/index.jsでアプリケーションの開始
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ pm2 start api/index.js
起動時にスクリプトやアプリケーションを自動的に開始する

PM2はスタートアップスクリプトを生成することで、マシンの再起動時にスクリプトやアプリケーションを自動的に開始することができます。

ターミナル
// スタートアップスクリプトを作成
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ pm2 startup
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/ec2-user/.nvm/versions/node/v14.17.1/bin /home/ec2-user/.nvm/versions/node/v14.17.1/lib/node_modules/pm2/bin/pm2 startup systemd -u ec2-user --hp /home/ec2-user

// 上記で出力されたコマンドをコピーして実行
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ sudo env PATH=$PATH:/home/ec2-user/.nvm/versions/node/v14.17.1/bin /home/ec2-user/.nvm/versions/node/v14.17.1/lib/node_modules/pm2/bin/pm2 startup systemd -u ec2-user --hp /home/ec2-user

// プロセスリストを確認しましょう
[ec2-user@ip-10-0-0-61 LINE-Node-Weather]$ pm2 list
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ index              │ fork     │ 0    │ online    │ 0%       │ 43.0mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

これで、EC2インスタンスを再起動したら、自動的にスクリプトが実行されます。
自分自身の「パブリックIPv4アドレス」に書き換えて下記にアクセスしてみましょう。

スクリーンショット 2021-06-17 9.22.43.png

となれば成功です。

10. AMIの作成

今回は冗長化されたウェブサービスを作るので上記と同じ内容のEC2インスタンスを作る必要があります。
しかし、またゼロからポチポチするのもめんどくさいので、上記で作ったEC2インスタンスからコピーしましょう。
その仕組みをAMIと言います。

作成した001-LINE-Weatherを停止してAMIを作成します。

■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスの状態」から停止を選択
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「アクション」から「イメージを作成」を選択

スクリーンショット 2021-06-22 9.32.32.png

AMIのステータスがavailableになるまで待ちます。

スクリーンショット 2021-06-22 9.35.14.png

11. 作成したAMIを使ってインスタンスを作成

■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスを起動」を選択

■ステップの流れ

作成したAMIを選択

スクリーンショット 2021-06-22 9.37.29.png

t2.microを選択
③インスタンスの詳細の設定の、ネットワーク, サブネット, 自動割り当てパブリックIPを変更

スクリーンショット 2021-06-22 9.39.56.png

④ストレージはそのままでOK
⑤キーをNameで追加(値は任意でOK)

スクリーンショット 2021-06-22 9.41.32.png

⑥セキュリティーグループを変更

スクリーンショット 2021-06-22 9.41.58.png

⑦キーペアの作成

先ほど使ったキーペアにしましょう。
スクリーンショット 2021-06-22 9.43.15.png

12. EC2のIPアドレスを固定するためにElastic IPを導入する

新しく作成したEC2インスタンスの002-LINE-WeatherElastic IPを導入しましょう。
上記でやったことを繰り返すだけなので省略します。

先ほど停止した001-LINE-Weatherも再起動し以下のようになれば完了です。

スクリーンショット 2021-06-22 9.45.59.png

13. ロードバランサーを導入

ロードバランサーは、負荷のバランスを取る装置です。
例えばWebサーバーに負荷がかかりやすいアプリケーションの場合、複数のサーバーに負荷を振り分けます。
これを冗長化と言います。
今回も2台のEC2を使っており冗長化しております。

ロードバランサーの主な機能としては3つです。
①ELBにはDNSのアクセスポイントが付与されます。
つまり、アクセスポイントを1つにして負荷を分散させることができます。

②ヘルスチェック機能がある
異常なインスタンスを発見したら通信をキャンセルしてくれます。

③ELBに証明書を付与することでSSL通信の終端になってくれる
HTTPS通信を復号する処理を担当してくれます。
つまり、internet gatewayの段階ではHTTPSだが、サブネット内ではHTTP通信となります。

以前書いたELBの記事です。
ELBに関して詳しく知りたい方はどうぞ。

■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「ロードバランサーの作成」を選択

今回は以下の記事と同じことをするのでこれだけでは意味がわからんという方はこちらを参照されてください。

現在は3000番ポートをつけないとアクセスできません。
スクリーンショット 2021-06-22 9.52.56.png
ポート番号なしでアクセスできるようにするためにロードバランサーを使います。
つまり、「ALBで80番で受けて3000番に転送する」ということです。

ALB → ターゲットグループ → EC2の流れでリクエストされるので、ALB(80)→TG(80->3000)→EC2(3000)になります。

それではやっていきましょう。

スクリーンショット 2021-06-22 9.46.36.png

スクリーンショット 2021-06-22 9.50.18.png

スクリーンショット 2021-06-22 9.56.16.png

スクリーンショット 2021-06-22 9.57.03.png

スクリーンショット 2021-06-22 9.57.49.png

作成できました。
スクリーンショット 2021-06-22 10.02.52.png

では、動作確認のためにDNS名でアクセスしてみましょう。
スクリーンショット 2021-06-22 10.04.04.png

アクセスできました!!

14. EC2のセキュリティグループのアクセス許可をロードバランサーからに変更する

■ルート
コンソールで「EC2」と検索→左ペイン内の「セキュリティグループ」を選択→「EC2-LINE-Weather-SG」を選択

スクリーンショット 2021-06-22 10.05.25.png

15. Freenomでドメインを購入する

Freenomは1年間ドメインを無料で使えます。
なのでこちらでドメインを購入しましょう!

どうやればいいかわからない方は以下の記事がわかりやすいので以下の記事を参考にしてみてください。

今回私は、line-weather-fashion.tkというドメインを取得しました。

スクリーンショット 2021-06-07 10.04.54.png

16. Route53と独自ドメインの紐付け

■ルート
コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「ホストゾーンの作成」を選択

スクリーンショット 2021-06-22 10.08.28.png

作成が正常に完了すると、NSレコードと呼ばれる値が割り振られます。

スクリーンショット 2021-06-22 10.09.42.png

この値をFreenomの方に書き写していきます。

スクリーンショット 2021-06-22 10.11.19.png

以前書いたS3とRoute 53の記事です。
S3とRoute 53に関して詳しく知りたい方はどうぞ。

17. ドメインとロードバランサーを紐付ける

■ルート
コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「line-weather-fashion.tk」を選択→「レコードを作成」を選択

スクリーンショット 2021-06-22 10.12.49.png

スクリーンショット 2021-06-22 10.13.25.png

スクリーンショット 2021-06-22 10.14.04.png

これでロードバランサーとline-weather-fashion.tkは結びつきました。

スクリーンショット 2021-06-22 10.14.49.png

それではアクセスできるか確認してみましょう。

スクリーンショット 2021-06-22 10.21.53.png

成功ですね!

もしアクセスができない時はDNSの設定をチェックしましょう。

スクリーンショット 2021-06-22 10.23.22.png

 Freenomの値がまだ入っていないようであれば、まだDNSの更新がされていないので待ちましょう!
スクリーンショット 2021-06-22 10.24.00.png

18. ロードバランサーでリスナーを追加する

AWS Certificate Manager(ACM) で証明書を取得します。

現状http通信でしかアプリケーションを利用できない状態です。

近年は常時SSL化(常に暗号化したデータをユーザーとサーバーでやりとり)が推奨されていて、
Google Chromeではhttp通信のままだと保護されていない通信と出てしまいます。

また、LINEでもhttpsでなければいけません。

スクリーンショット 2021-06-07 10.14.39.png

■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LINE-Weather-LB」を選択→「リスナーの追加」を選択

スクリーンショット 2021-06-22 10.26.40.png

スクリーンショット 2021-06-22 10.28.01.png

証明書を発行しましょう

スクリーンショット 2021-06-22 10.41.40.png

スクリーンショット 2021-06-22 10.32.06.png

Route 53でレコードの作成を行います。

スクリーンショット 2021-06-22 10.45.02.png

スクリーンショット 2021-06-22 10.45.41.png

証明書の検証に時間がかかるので成功になるまで待ちましょう。

スクリーンショット 2021-06-22 10.46.27.png

次はリスナーの追加に戻ってSSL証明書を取得しましょう。

スクリーンショット 2021-06-22 10.47.47.png

19. セキュリティグループの修正でHTTPSへのリダイレクト設定

■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LB-LINE-Weather-SG」を選択→「セキュリティグループ」を選択

スクリーンショット 2021-06-22 10.37.16.png

最後にロードバランサーのリスナーをHTTPSのみにしましょう。

スクリーンショット 2021-06-22 10.38.28.png

終わりに

HTTPSでアクセスできました。
たまにキャッシュなどで表示されないのでプライベートウィンドウの方が安全です。

スクリーンショット 2021-06-22 10.49.33.png

では実際にLINEが送られるか検証しましょう。

スクリーンショット 2021-06-22 10.51.17.png

名称未設定.png

完成です!!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3