2024年の下書きが眠っていた為、作業記録として放出します。
環境/背景
- NodeJS[AdonisJS] + AWS
- AWS EC2
xx.xxx.xxx.xx=AWSのEC2IPアドレス
まえおき
デプロイで丸1日かかったが...
そろそろNodeJSのWebアプリを勉強したいなあと思い、Nodeでサイトをホストしようとしている時の話。
- 手ごろに見つけてきた「AdonisJS」NodeJsフレームワーク
NodeはロリポップとかXServerとかの、普通のレンタルサーバーでは動かせないので、ずっと足踏みしていたというのもあるのだが(簡単な奴はherokuでアップしたことあるけど)、まあここでAWSの勉強でもしておくかと入門を決意。
使った分だけと言われている料金体系も気になるし。
AWSページ自体は以前から何回かチラ見していて、「それはもう煩雑である」ということは分かっていた...。
アカウントだけ作って足踏みすることおよそ1か月...ようやく涼しくなってやる気も沸いてきた。
AWSへのアクセス
- / インスタンス起動、料金アラート設定(昔怖いブログを読んだ)、EC2へのSSH接続設定、、、
SSH接続
key設定やらなにやら
私の場合はSFTP使いましてビルド後のフォルダをEC2にアップロード。
EC2にNodeを入れるまではこちらを参考
1. 実行①
とりあえず.envをそれっぽく設定する
HOST=xx.xxx.xxx.xx
PORT=8888
APP_NAME...
...
んで、AdonisJS公式の言う通りに動かしてみると。
> node server.js
[08:59:43.533] ERROR (app-name/11529): listen EADDRNOTAVAIL: address not available xx.xxx.xxx.xx:8888
Error: listen EADDRNOTAVAIL: address not available xx.xxx.xxx.xx:8888
at Server.setupListenHandle [as _listen2] (node:net:1800:21)
at listenInCluster (node:net:1865:12)
at doListen (node:net:2014:7)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
Nodeは動かない。
2. 実行2
エラー文は、なにやらIPが見つからないよ的なことを言ってる。
ん?そもそもAWSのIPってどれ?(あれこれ設定しながら30分悩む。)
あ、確か昔読んだ本にはEC2は仮想マシンだから日によってIPが変動するみたいなことが書いてあったような....
ネット君「AWSのElastic IPを使うと変動するIPを外向けには一つのIPに固定できるよ!!」
わい「おかのした」
ElasticIPについてはこちら
ネット君「動かそうとしているポート番号がすでに使われてるんじゃない?」
わい「netstatも見たしいろいろポート変えてみたけど全滅...」
それでも同じエラーで、Nodeは動かない。
0.0.0.0にすればいいのか.......?
3. 実行3
あれ?ポートを設定していない?
たしかHTTP通信なら80番ポートに通信が行くはず...
ネット君「nginxのポート設定は、/etc/nginx/のconf的なものを調べれば何とかなるで!」
わい「おかのした」
わい「/etc配下に/nginxなんてディレクトリないで...」
_人人人人人人人人人人人人人人人人人_
> nginxインストールしてなかった <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
4.ウェブサーバーソフトウェアとは
よく考えればEC2だって普通にPCでありマシン(に見えてるだけだけどここはいいとして)。
自分ちにあるPCだってインターネットからアクセスできるわけじゃない。
ウェブサーバーってものを当たり前に使いすぎていて、マシンとウェブサーバー機能をごっちゃにしてしまっていた。
聞き慣れない単語は聞き逃してしまいがちだけど
-
Linux・Windows・macなどが「OS」 -
Apache・nginxなどが「ウェブサーバーソフトウェア」。
わい「つまり、マシンでウェブサーバーソフトが動いてることによって、そこで初めて外界とHTTP通信ができるようになるんやな。」
>EC2にnginxをインストールした!!
それでもNodeは動かない。
AWSのポート開放
AWSはセキュリティグループというのを使ってポートを外向けに開放しなければ使えないらしい。
>AWSのセキュリティグループを作成、EC2にアタッチしてポートを開放した!!
アクセスすると確かにnginxの初期ページが表示された!!
ドキュメントルート変更
nginxをインストールしたところで今度こそ/etc/nginx配下を見てみる。
....
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
....
ここのrootの行がドキュメントルート。つまり80番ポートにアクセスしてる場合は/usr/share/nginx/htmlのディレクトリを見る=ファイルでなく、ディレクトリ指定ならindex.htmlを探して返す。
余談だが、nginxウェブサーバーでの公開ファイルは/var/www/html/${mysite}以下に置くことがほとんどらしい。特に強制というわけでもなく、慣習みたいなものらしい。
とりあえずドキュメントルートを変更し、アプリディレクトリもそこに移動させてみる。
#root /usr/share/nginx/html;
root /var/www/html/app_dir;
ここでnginxをリスタートさせ、アクセスすると404ページが表示されてしまった。
どういうことか?
ここで、エラーログを見ることに思い至る。
nginxエラーログの見方
nginxのエラーログは/var/log/nginx/error.logにある。
権限設定が強い為か、/var/log/nginx以下はターミナルの補完(Tabキー)が効かないが、sudo lsで見れば存在を確認できる。
他プロジェクトの際もerror.logを見ようとしてcatコマンドを使い、重すぎてctrl+C...みたいなことを何度もしていたのだが、こういう重いファイルを閲覧する際はlessやtailコマンドを使うといいらしい。
今回もsudo lessコマンドでerror.logファイルを確認できた。
※ lessでの閲覧モードはqで抜けられる。
2023/09/23 06:39:30 [error] 6058#6058: *1 "/var/www/html/app_dir/index.html" is not found (2: No such file or directory), client: 自分のIPアドレス, server: _, request: "GET / HTTP/1.1", host: "xx.xxx.xxx.xx"
2023/09/23 06:39:30 [error] 6058#6058: *1 open() "/var/www/html/app_dir/404.html" failed (2: No such file or directory), client: 自分のIPアドレス, server: _, request: "GET / HTTP/1.1", host: "xx.xxx.xxx.xx"
/var/www/html/app_dirにあるはずのindex.htmlを探して彷徨っている。ついでに404.htmlも。
いや自分のアプリにはhtmlファイルがそもそも入ってないのだが....。
いやまて、そうなるとどうやったらnodeアプリのページを表示できるんだ?index.htmlじゃなくてserver.jsを指定する?いやphpじゃあるまいし、そもそもサーバ開始のコマンドで指定するファイルだろそれは....
HOST=xx.xxx.xxx.xx
PORT=80
APP_NAME...
...
> node /var/www/site/server.js
[08:59:43.533] ERROR (app-name/11529): listen EADDRNOTAVAIL: address not available xx.xxx.xxx.xx:8888
Error: listen EADDRNOTAVAIL: address not available xx.xxx.xxx.xx:8888
at Server.setupListenHandle [as _listen2] (node:net:1800:21)
at listenInCluster (node:net:1865:12)
at doListen (node:net:2014:7)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
結論
そもそもNodeはスクリプト言語であり、そのPCの中からしか見れないものである。
それをnginxのリバースプロキシで外界に見えるようにしてあげてるだけ。
つまり、Node起動の際のポート設定を8000番とかにしておく。=>リバースプロキシで、外界から80ポートにアクセスされた場合に内部の8000番ページを返す=>Nodeがみれるというわけ。
よく見たらめちゃめちゃまとまってるサイトあった