LoginSignup
20

More than 5 years have passed since last update.

bundle packageでgemをアプリケーションに含める

Last updated at Posted at 2014-11-19

編集リクエスト求む。

発端

  1. Ruby アプリケーションを EC2 上で動かしたい。AutoScaling でスケールもしたい。
  2. AMI を作れば起動が早いけど AMI の運用したくない。
  3. 素の Amazon Linux から環境構築しても起動が早くなればいい。
  4. bundle package 使ってみよう。

手順

前提として /home/ec2-user/app/ 以下で作業を行っている。
また、bundler 1.7.6 がインストール済み。

gemをアプリケーションに含める

1. 使用する gem のバージョンを決め Gemfile にその旨を記述する

Gemfile
 source "https://rubygems.org"

 gem "aws-sdk-core", "~> 2.0.9"
     :

2. gem のインストール先を設定する

.bundle/config
 $ 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 はいらないので管理対象外。

.gitignore
 /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 付ければチェックはスキップするけど動かないよ。ということ、だと、思う。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20