編集リクエスト求む。
発端
- Ruby アプリケーションを EC2 上で動かしたい。AutoScaling でスケールもしたい。
- AMI を作れば起動が早いけど AMI の運用したくない。
- 素の Amazon Linux から環境構築しても起動が早くなればいい。
- bundle package 使ってみよう。
手順
前提として /home/ec2-user/app/
以下で作業を行っている。
また、bundler 1.7.6 がインストール済み。
gemをアプリケーションに含める
1. 使用する gem のバージョンを決め Gemfile にその旨を記述する
source "https://rubygems.org"
gem "aws-sdk-core", "~> 2.0.9"
:
2. gem のインストール先を設定する
$ bundle config --local path vendor/bundle
$ bundle config
Settings are listed in order of priority. The top value will be used.
path
Set for your local app (/home/ec2-user/app/.bundle/config): "vendor/bundle"
$ cat .bundle/config
---
BUNDLE_PATH: vendor/bundle
3. bundle package
する
vendor/bundle
にgemがインストール され vendor/cache
に .gem ファイルがキャッシュされる。
Gemfileに :gem, :path, .gem が記述してある場合に、それも対象にするため --all
を付けている。 bundler2.0 からはデフォルト。
$ bundle package --all
Fetching gem metadata from https://rubygems.org/............
Resolving dependencies...
:
Installing aws-sdk-core 2.0.9
:
Using bundler 1.7.6
Your bundle is complete!
It was installed into ./vendor/bundle
Updating files in vendor/cache
:
* aws-sdk-core-2.0.9.gem
:
4. vendor/cache
ディレクトリと .bundle/config
ファイルをバージョン管理対象とする
vendor/bundle
はいらないので管理対象外。
/vendor/bundle/
!/vendor/cache/*.gem
パッケージした gem を更新する
「パッケージした」って日本語どうなのか・・・
ここでは aws-sdk-core 2.0.5 がインストールされている状態で 2.0.9 にアップデートする。
.bundle/config
は設定済みの体。
1. bundle update
する
vendor/bundle
を更新した後 vendor/cache
の .gem ファイルも更新。不要になった .gem が削除される。
$ bundle update
Fetching gem metadata from https://rubygems.org/...
Resolving dependencies...
Using builder 3.2.2
:
Installing jmespath 1.0.1
:
Installing aws-sdk-core 2.0.9 (was 2.0.5)
Using bundler 1.7.6
Updating files in vendor/cache
* jmespath-1.0.1.gem
* aws-sdk-core-2.0.9.gem
Removing outdated .gem files from vendor/cache
* jamespath-0.5.1.gem
* aws-sdk-core-2.0.5.gem
Your bundle is updated!
2. commit する
バージョン管理しているならコミットする。
gemをインストールする
gem をパッケージしたアプリケーションを利用する時に gem をインストールする手順。
1. bundle install
する
--local
を付けると rubygems.org へのアクセスもなくなりインストール自体はとても早くなる。
$ time bundle install --local
Resolving dependencies...
Installing builder 3.2.2
Installing multi_json 1.10.1
Installing jmespath 1.0.1
Installing multi_xml 0.5.5
Installing aws-sdk-core 2.0.9
Using bundler 1.7.6
Updating files in vendor/cache
Your bundle is complete!
It was installed into ./vendor/bundle
real 0m0.440s
user 0m0.348s
sys 0m0.064s
ただし、
$ bundle help install
... Note that if a more appropriate platform-specific gem exists on rubygems.org, it will not be found.
らしいので注意。パッケージした環境と利用する環境が同じなら問題ないと思う。
問題点
native extension の問題
nokogiri のようなネイティブエクステンションをパッケージしてもインストール時に結局ビルドが必要になるので遅い。
完全に環境を固定できるなら vendor/bundle
ごとバージョン管理したほうがいいんだろうか。
platform の問題
bundle help package
を見ると nokogiri を例に説明がある。
ruby プラットフォーム (C Ruby) じゃなくて java プラットフォーム (JRuby) だったら bundler は rubygems.org チェックしちゃうよ。
--local
付ければチェックはスキップするけど動かないよ。ということ、だと、思う。