先日、Node.jsでアプリを天気予報アプリを作成しました。
この記事内ではデプロイは、Glitch
を使いました。
まぁ無料なわけで色々問題があります。
・プロジェクトは、利用されていないときは5分でスリープ状態になる
・4000件/1hのリクエスト制限がある(Error: 429 too many requests)
ということでAWSにデプロイすることにします。
それではアーキテクチャに関してみていきましょう。
アーキテクチャ
ちなみにAWSのアーキテクチャなどを作るときは、drawio
がおすすめです。
VSCodeから使えるので是非使ってみてください。
ハンズオン
1. AWSへログイン
2. 東京リージョンになっていることを確認
3. VPCを作成(IP:10.0.0.0/21)
■ルート
コンソールで「VPC」と検索→左ペイン内の「VPC」を選択→「VPCを作成」を選択
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で使うサブネットを作成します。
5. Publicサブネットをインターネットに接続するためにInternet Gatewayを作成しアタッチする
■ルート
コンソールで「VPC」と検索→左ペイン内の「インターネットゲートウェイ」を選択→「インターネットゲートウェイの作成」を選択
**「VPCへアタッチ」**をクリックする
作成したVPCにアタッチします。
6. EC2がインターネット接続するためにルートテーブルを作成
■ルート
コンソールで「VPC」と検索→左ペイン内の「サブネット」を選択→「Node-Pub-1」を選択→「ルートテーブル」を選択→「ルート」へ移動→「ルートを編集」を選択
7. Publicサブネット内にEC2を構築
■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスを起動」を選択
■ステップの流れ
①Amazon Linux 2 AMI (HVM), SSD Volume Typeを選択
②t2.microを選択
③インスタンスの詳細の設定の、ネットワーク
, サブネット
, 自動割り当てパブリックIP
を変更
④ストレージはそのままでOK
⑤キーをName
で追加(値は任意でOK)
⑥セキュリティーグループを変更
Node.jsは、TCPの3000番ポートでリクエストを受けるので、Security Groupに追加します。
⑦キーペアの作成
私は事前に作成しているキーペアがあるのでそちらを使います。
このキーペアはdesktop
にでも保存しておきましょう。
以前書いたEC2の記事です。
基本的な内容になっているのでEC2ってなんやねんって方は見てもらえると!
8. EC2のIPアドレスを固定するためにElastic IP
を導入する
IPアドレスを固定する理由としては、インスタンスを再起動しても同じIPアドレスに固定しておきたいためです。
通常、インスタンスを再起動するとIPアドレスが変わってしまいます。
それでは再起動する度にSSH接続の設定を変えないといけないため、IPアドレスを固定します。
ちなみに、Elastic IPは関連づけを行わなければ費用が発生します。
その点はご注意ください。
■ルート
コンソールで「EC2」と検索→左ペイン内の「Elastic IP」を選択→「Elastic IPアドレスの割り当て」を選択
作成できたら次は関連づけを行います。
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 .
この後は.env
やnode_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アドレス」に書き換えて下記にアクセスしてみましょう。
となれば成功です。
10. AMIの作成
今回は冗長化されたウェブサービスを作るので上記と同じ内容のEC2インスタンスを作る必要があります。
しかし、またゼロからポチポチするのもめんどくさいので、上記で作ったEC2インスタンスからコピーしましょう。
その仕組みをAMIと言います。
作成した001-LINE-Weatherを停止してAMIを作成します。
■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスの状態」から停止を選択
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「アクション」から「イメージを作成」を選択
AMI
のステータスがavailable
になるまで待ちます。
11. 作成したAMIを使ってインスタンスを作成
■ルート
コンソールで「EC2」と検索→左ペイン内の「インスタンス」を選択→「インスタンスを起動」を選択
■ステップの流れ
①作成したAMIを選択
②t2.microを選択
③インスタンスの詳細の設定の、ネットワーク
, サブネット
, 自動割り当てパブリックIP
を変更
④ストレージはそのままでOK
⑤キーをName
で追加(値は任意でOK)
⑥セキュリティーグループを変更
⑦キーペアの作成
12. EC2のIPアドレスを固定するためにElastic IP
を導入する
新しく作成したEC2インスタンスの002-LINE-WeatherにElastic IP
を導入しましょう。
上記でやったことを繰り返すだけなので省略します。
先ほど停止した001-LINE-Weatherも再起動し以下のようになれば完了です。
13. ロードバランサーを導入
ロードバランサーは、負荷のバランスを取る装置です。
例えばWebサーバーに負荷がかかりやすいアプリケーションの場合、複数のサーバーに負荷を振り分けます。
これを冗長化と言います。
今回も2台のEC2を使っており冗長化しております。
ロードバランサーの主な機能としては3つです。
①ELBにはDNSのアクセスポイントが付与されます。
つまり、アクセスポイントを1つにして負荷を分散させることができます。
②ヘルスチェック機能がある
異常なインスタンスを発見したら通信をキャンセルしてくれます。
③ELBに証明書を付与することでSSL通信の終端になってくれる
HTTPS通信を復号する処理を担当してくれます。
つまり、internet gatewayの段階ではHTTPSだが、サブネット内ではHTTP通信となります。
以前書いたELBの記事です。
ELBに関して詳しく知りたい方はどうぞ。
■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「ロードバランサーの作成」を選択
今回は以下の記事と同じことをするのでこれだけでは意味がわからんという方はこちらを参照されてください。
現在は3000番ポートをつけないとアクセスできません。
ポート番号なしでアクセスできるようにするためにロードバランサーを使います。
つまり、「ALBで80番で受けて3000番に転送する」ということです。
ALB → ターゲットグループ → EC2
の流れでリクエストされるので、ALB(80)→TG(80->3000)→EC2(3000)になります。
それではやっていきましょう。
アクセスできました!!
14. EC2のセキュリティグループのアクセス許可をロードバランサーからに変更する
■ルート
コンソールで「EC2」と検索→左ペイン内の「セキュリティグループ」を選択→「EC2-LINE-Weather-SG」を選択
15. Freenomでドメインを購入する
Freenomは1年間ドメインを無料で使えます。
なのでこちらでドメインを購入しましょう!
どうやればいいかわからない方は以下の記事がわかりやすいので以下の記事を参考にしてみてください。
今回私は、line-weather-fashion.tk
というドメインを取得しました。
16. Route53と独自ドメインの紐付け
■ルート
コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「ホストゾーンの作成」を選択
作成が正常に完了すると、NSレコードと呼ばれる値が割り振られます。
この値をFreenomの方に書き写していきます。
以前書いたS3とRoute 53の記事です。
S3とRoute 53に関して詳しく知りたい方はどうぞ。
17. ドメインとロードバランサーを紐付ける
■ルート
コンソールで「Route53」と検索→左ペイン内の「ホストゾーン」を選択→「line-weather-fashion.tk」を選択→「レコードを作成」を選択
これでロードバランサーとline-weather-fashion.tk
は結びつきました。
それではアクセスできるか確認してみましょう。
成功ですね!
もしアクセスができない時はDNSの設定をチェックしましょう。
Freenom
の値がまだ入っていないようであれば、まだDNSの更新がされていないので待ちましょう!
18. ロードバランサーでリスナーを追加する
AWS Certificate Manager(ACM) で証明書を取得します。
現状http通信でしかアプリケーションを利用できない状態です。
近年は常時SSL化(常に暗号化したデータをユーザーとサーバーでやりとり)が推奨されていて、
Google Chromeではhttp通信のままだと保護されていない通信と出てしまいます。
また、LINEでもhttps
でなければいけません。
■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LINE-Weather-LB」を選択→「リスナーの追加」を選択
証明書を発行しましょう
Route 53でレコードの作成を行います。
証明書の検証に時間がかかるので成功になるまで待ちましょう。
次はリスナーの追加に戻ってSSL証明書を取得しましょう。
19. セキュリティグループの修正でHTTPSへのリダイレクト設定
■ルート
コンソールで「EC2」と検索→左ペイン内の「ロードバランサー」を選択→「LB-LINE-Weather-SG」を選択→「セキュリティグループ」を選択
最後にロードバランサーのリスナーをHTTPS
のみにしましょう。
終わりに
HTTPSでアクセスできました。
たまにキャッシュなどで表示されないのでプライベートウィンドウの方が安全です。
では実際にLINEが送られるか検証しましょう。
完成です!!