AWS Elastic Beanstalk(以下EB)を使ってNode.jsアプリをデプロイしようとしてつまづいたので、備忘録として残しておく。
アプリケーションの概要
- Typescript+Expressで書かれたNode.jsアプリケーション。
- ローカルでは
ts-node
を使って起動している。
デプロイしようとして失敗
Procfile を指定しない場合、package.json ファイルを指定すると Elastic Beanstalk は npm start を実行します。これを指定しない場合、Elastic Beanstalk は app.js または server.js をこの順序で探し、実行します。
と記載されていたので、特に何もしなくてもnpm start
が実行されて、ts-node
でサーバが起動すると思っていた。
が、実際デプロイしてみるとヘルスは「低下」、アクセスしてみると502 Bad Gateway。
ログを見ても特にエラー内容が見当たらず、なぜ動作していないのかがよく分からなかった。
参考になりそうな記事を発見
似たような事例がないかを探していたところ、参考になりそうな記事を発見した。
Deploying a TypeScript, ExpressJS app into ElasticBeanstalk NodeJS server | by Viet Hoang Le | Medium
要約すると、.ebextensions
を使って起動前にtsファイルをコンパイルすると良いとのこと。
.ebextensionsとProcfileを追加
.ebextensions
記事に書かれているとおりに.ebextensions/source_compile.config
を追加した。
ただし、そのままだとnode_modules
内のtsc
を実行するところでエラーになってしまったので、下記のように修正した。(指定の場所にtscがあるのは確認済み。原因不明。)
container_commands:
compile:
command: "tsc -p tsconfig.json"
env:
PATH: /opt/elasticbeanstalk/node-install/node-v14.17.3-linux-x64/bin/
/opt/elasticbeanstalk/node-install/node-v14.17.3-linux-x64/bin/
下のtscを使ってコンパイルを行うようにしたが、デフォルトの状態ではtscがインストールされていない。
EBによって立ち上がっているEC2にsshで接続し、npm install -g typescript
を実行する必要がある。
Procfile
前述のとおり、package.json
にはnpm start
でts-node
を実行するように書いているので、Procfile
を追加しEBではnode
を実行するようにした。
web: node app.js
コンパイルしたファイルを実行するように記述するだけ。
これでデプロイしてサーバが動作するようになった。
余談
環境変数をマネジメントコンソールや.ebextensions
で指定したのに、sshで接続してexport
コマンドやenv
コマンドで確認しても全然反映されなくて困ったけど、そういうものだった。(実際特に問題なく動作していた。)
Elastic Beanstalk 環境から Linux および Windows インスタンスに変数を渡す
PHP を実行するスタック以外では、環境プロパティがインスタンスに存在していたとしても、それらがシェルに自動的にエクスポートされることはありません。その代わりに、環境プロパティは、使用されているプラットフォームに基づいて、アプリケーションが実行されているスタックを通じてアプリケーションに提供されます。