概要
今携わっている案件では、rails + react-rails + browserify-railsを用いて開発しています。browserify-railsはSporoketsでもCommonJSなモジュールを動かせるようになる便利なgemですが、Elastic Beanstalkのdeployで少しハマったのでやったことを記します。
前提
Sporoketsを使うということは、assets:precompileをする必要がありますが、そのタイミングより前にnpm installをして、node_modules/にモジュール群が入っている必要があります。
対応方法
結論としては、.ebextensionsに下記のようなconfigを追加してdeployして解決しました。
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/07_install_node_modules.sh" :
mode: "000744"
owner: root
group: root
content: |
#!/usr/bin/env bash
set -xe
EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
cd $EB_APP_STAGING_DIR
npm install
詳細
ebextensionsのconfig
Elastic Beanstalkではデプロイのためのコマンドは.ebextensions配下か、あるいはデプロイ先の環境にconfigを設置しておくと実行されます。
今回は、.ebextensions配下に設定を記述しており、files:で指定しているファイル名/opt/elasticbeanstalk/hooks/appdeploy/pre/07_install_node_modules.shで実行順序を指定しています。
まず、preと書くとタイミング的にはデプロイの前処理段階になります。pre(前処理) -> enact(バージョン切替時) -> post(後処理)という順序で実行されるようです。(詳細)
また、07_install_node_modules.shの先頭の07で実行順を指定しています。数値が小さいほど実行順序が優先されます。(私の環境ではassetのプリコンパイルより早く実行される07としていますが、順番は環境に合わせてください)
落とし穴
Elastic Beanstalkデプロイ先は/var/app/currentですが、デプロイ中のワーキングディレクトリは別なようです。ワーキングディレクトリ自体は記述にあるように、EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)という風にやれば取得できます。最初はこれに気づかず、npm installしようとしてもpackage.jsonがない、というエラーが発生してデプロイに失敗していました。
エラーが出た時は
eb logs <環境名>でログを参照できます。