このHPの動作環境をLambdaからECS Fargateに移行

2020年04月27日

M2末永です。

このHPは今までServerless Frameworkを使ってLambdaにデプロイしていたのですが、しばらくアクセスがない状態からのCold Start時のページ表示にかなりの時間を要する(10秒以上)のが気になっていたのでECS Fargateに移行しました。

ECSの構成管理はTerraformで行い、デプロイ自体はCircleCIがmasterブランチへのマージ時に行います。

アプリケーションはnuxt.jsのSSRモードが動いています。

ALBが502 Bad Gateway

ヘルスチェックが通らなくて半日くらい詰まってました。502エラーが出た場合は真っ先にALBがTarget Groupに通信できているか確認しましょう。

以下実際に確認したこと。

  • (1) CloudWatchにログを吐くようにする
  • (2) ヘルスチェックのURLを確認する
  • (3) ヘルスチェック時にログを吐くようにする
  • (4) コンテナをECRからpullしてローカルで試す
  • (5) 同じポートを使う別のイメージで試す

(1) CloudWatchにログを吐くようにする

CloudWatchに適当なロググループを作成して、taskDefinitionにログをここに吐き出す設定を書けば簡単にアプリケーションの標準出力が吐き出されるようになります。こんな感じです。

"logConfiguration": {
   "logDriver": "awslogs",
   "options": {
     "awslogs-group": "morioka-lab-frontend",
     "awslogs-region": "ap-northeast-1",
     "awslogs-stream-prefix": "morioka-lab-frontend-log"
   }
}

(2) ヘルスチェックのURLを確認する

アプリケーション側のヘルスチェックのURLが間違っている場合もままあるのでローカルで期待通り動くことを確認します。

(3) ヘルスチェック時にログを吐くようにする

ひとまずヘルスチェックのURLにアクセスがあった場合に何か適当に出力してやるようにします。

(4) コンテナをECRからpullしてローカルで試す

awsコマンドでログインして該当イメージをpullし、実行します。

> $(aws ecr get-login --region ap-northeast-1 --no-include-email)
> docker pull 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/morioka-lab-frontend:<SHA1-HASH>
> docker run --rm -it <image id>

(5) 同じポートを使う別のイメージで試す

taskDefinitionのimageの部分を別のイメージにして試します。これで動いた場合はデプロイしたイメージ(つまりアプリケーション)が間違っています。

解決: nuxt.jsをデプロイするときは--host 0.0.0.0を渡そう

https://nuxtjs.org/faq/host-port によると

Host 0.0.0.0 is designated to tell Nuxt to resolve a host address, which is accessible to connections outside of the host machine (e.g. LAN).Host 0.0.0.0 is designated to tell Nuxt to resolve a host address, which is accessible to connections outside of the host machine (e.g. LAN).Host 0.0.0.0 is designated to tell Nuxt to resolve a host address, which is accessible to connections outside of the host machine (e.g. LAN).Host 0.0.0.0 is designated to tell Nuxt to resolve a host address, which is accessible to connections outside of the host machine (e.g. LAN).

らしいです。簡単に言うと「LANなど外部からアクセスされる場合はHostに0.0.0.0を指定してね」と書かれています。ここを修正したら正しくヘルスチェックが通るようになって無事ECSへの移行が完了しました。