ElasticBeanstalk でのトラブルシューティング


備忘録も兼ねて、トラブルシューティング的に記録。
主に Rails アプリをデプロイした際の対処方法が多くなると思います。

## よく見るログファイル

* /var/log/cfn-init.log
    * Elastic Beanstalk でログを追う場合の基本の”き”
    * 何かしらの命令をしてから実行されるコマンドが順次出力されます
* /var/log/directory-hooks-executor.log
    * デプロイ時の Hook 処理に関するログ

## bundle install が失敗

```Events
Script /opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh failed with returncode 1
Command failed on instance. Return code: 1 Output: Error occurred during build: Command hooks failed .
```

#### 原因: 自前のコードを gem として取り込む際に git checkout が失敗している

Gemfile にこんな感じの設定を書いてる場合に失敗します。

```
gem 'hoge', :git => "git://github.com/lassy/hoge.git"
```

directory-hooks-executor.log を見てみると Bunler::GitError がバッチリと。

```
Bundler::GitError: git://github.com/lassy/hoge.git (at master) is not checked out. Please run `bundle install`
```

どうも [Passenger が原因](http://stackoverflow.com/questions/6648870/is-not-checked-out-bundle-install-does-not-fix-help)のようです。

#### 対応: --development オプションを追加する

```
$ bundle install
```

で実行してたコマンドを

```
$ bundle install --deployment
```

に変更して対処をするが、Elastic Beanstalk の場合は Hook 処理を書き換えるため、
以下のようなファイルをプロジェクト直下に作って環境をカスタマイズします。
Elastic Beanstalk の拡張については[公式ドキュメント](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/customize-containers.html)を参考に。

```$APP_HOME/.ebextentions/01_rails.config
commands:
  # Run rake with bundle exec to be sure you get the right version
  add_bundle_exec:
    test: test ! -f /opt/elasticbeanstalk/containerfiles/.post-provisioning-complete
    cwd: /opt/elasticbeanstalk/hooks/appdeploy/pre
    command: perl -pi -e 's/(rake)/bundle exec $1/' 11_asset_compilation.sh 12_db_migration.sh
  # Bundle with --deployment as recommended by bundler docs
  #   cf. http://gembundler.com/v1.2/rationale.html under Deploying Your Application
  add_deployment_flag:
    test: test ! -f /opt/elasticbeanstalk/containerfiles/.post-provisioning-complete
    cwd: /opt/elasticbeanstalk/hooks/appdeploy/pre
    command: perl -pi -e 's/(bundle install)/$1 --deployment/' 10_bundle_install.sh
  # Vendor gems to a persistent directory for speedy subsequent bundling
  make_vendor_bundle_dir:
    test: test ! -f /opt/elasticbeanstalk/containerfiles/.post-provisioning-complete
    command: mkdir /var/app/containerfiles/vendor_bundle
  # Store the location of vendored gems in a handy env var
  set_vendor_bundle_var:
    test: test ! -f /opt/elasticbeanstalk/containerfiles/.post-provisioning-complete
    cwd: /opt/elasticbeanstalk/containerfiles
    command: sed -i '12iexport EB_CONFIG_APP_VENDOR_BUNDLE=$EB_CONFIG_APP_SUPPORT/vendor_bundle' envvars
  # The --deployment flag tells bundler to install gems to vendor/bundle/, so
  # symlink that to the persistent directory
  symlink_vendor_bundle:
    test: test ! -f /opt/elasticbeanstalk/containerfiles/.post-provisioning-complete
    cwd: /opt/elasticbeanstalk/hooks/appdeploy/pre
    command: sed -i '6iln -s $EB_CONFIG_APP_VENDOR_BUNDLE ./vendor/bundle' 10_bundle_install.sh
  # Don't run the above commands again on this instance
  #   cf. http://stackoverflow.com/a/16846429/283398
  z_write_post_provisioning_complete_file:
    cwd: /opt/elasticbeanstalk/containerfiles
    command: touch .post-provisioning-complete
```

ぶっちゃけ、[こちら](https://github.com/alienfast/elastic-beanstalk/blob/master/samples/real-world.yml)を参考にさせて頂きました。

## ファイルアップロードに失敗する

```/var/log/nginx/error.log
2014/06/26 05:16:04 [error] 30628#0: *20 client intended to send too large body: 1098467 bytes, client: 192.168.0.1, server: _, request: "POST /foo HTTP/1.1", host: "www.hogehoge.com", referrer: "http://www.hogehoge.com/foo/edit"
```

#### 原因: Nginx では標準でのアップロード上限は1MBのため

nginx では POST の最大サイズを標準で1MBに設定されているためです。
[公式ドキュメント](http://wiki.nginx.org/HttpCoreModule#client_max_body_size)より。

#### 対応: client_max_body_size を設定する

上記と同じく、Elastic Beanstalk の拡張ファイルを作成します。

```$APP_HOME/.ebextentions/01_nginx.config
files:
  "/etc/nginx/conf.d/proxy.conf" :
    mode: "000644"
    owner: root
    owner: root
    content: |
      client_max_body_size 5M;
commands:
  restart_nginx:
    command: /etc/init.d/nginx restart
```

[こちら](http://stackoverflow.com/questions/18908426/increasing-client-max-body-size-in-nginx-conf-on-aws-elastic-beanstalk)を参考にさせて頂きました。