デプロイ

Bundleされたアプリケーションのデプロイ

Bundlerを使用したアプリケーションをデプロイする前に、 ソースコードのバージョン管理システムへGemfileGemfile.lockを追加してください。 ただし、各マシンの.bundleフォルダは無視されるように設定を行ってください。

$ echo ".bundle\n" >> .gitignore
$ git add Gemfile Gemfile.lock .gitignore
$ git commit -m "Add Bundler support"

これを行うと、Bundlerを使用した手動または自動の、2種類のデプロイ方法が出来るようになります。

手動デプロイ

最新のコードへの更新後に、デプロイのスクリプトの中で、 vendor/bundleディレクトリへBundleしたものをインストールし、 全ての依存性が揃うようにして下さい。

$ bundle install --deployment

通常通りアプリケーションのサーバーを起動すれば、 アプリケーションは開発環境と全く同じGemがバンドル(一包に)された環境を使用するでしょう。

bundle packageを実行している場合、 キャッシュされたGemが自動的に使用されます。

Bundlerのパッキング(bundle package)の詳細

Capistranoを使用した自動デプロイ

Bundler Capタスクをプル(pull)するために、deploy.rbファイルに下記を追加します。

require 'bundler/capistrano'

これだけです! cap deployを実行すると、デプロイ向けのオプションを使用して、 リモートサーバー上で自動的にbundle installを実行するようになります。 変更可能なオプションのリストは、Capタスク用のヘルプで確認することが出来ます。 cap -e bundle:installを実行して、確認してみましょう。

Vladを使用した自動デプロイ

デフォルトでVladタスクが利用可能です。 利用するためには、Vladのdeploy.rbに下記の行を追加します。

これを行うと、vlad:bundle:installタスクが利用可能になります。 デプロイの一部として実行されていることを確認してください。 例えば、

task "vlad:deploy" => %w[ vlad:update vlad:bundle:install vlad:start_app vlad:cleanup ]

デプロイ後について

バンドルしたGemの中から、実行ファイルに対してbundle execを使用した実行を確認してください。

$ bundle exec rake db:setup

あるいは、bundle execの代わりに、 インストールコマンド上で--binstubsオプションを使用することで、 実行(バイナリ)ファイルを生成する事が可能です。

Rails4での--binstubsの取り扱いには注意が必要です。詳細については下記のリンク先を参照して下さい。

Bundlerの実行(bundle exec)の詳細

Heroku

Herokuへデプロイする際には、Gemfileが提供されていれば自動的にBundlerが実行されます。 Gemfile.lockをチェックインすると、Herokuはbundle install --deploymentを実行します。 もし--withoutオプションを使用して特定のグループを除きたい場合は、 heroku configを使用する必要があります。

$ heroku config:add BUNDLE_WITHOUT="test development" --app app_name

Heroku Bundler Documentation

アプリケーションのデプロイについて

bundle installを実行すると、Bundlerは(デフォルトで)、 あなたのGemのシステム(system)格納場所にGemをインストールします。 これは、Gemのリストにこれらが追加されることを意味します。 加えて、もし複数のアプリケーションがデプロイされている場合、 各アプリケーションで共通するGemをダウンロード、インストールする必要はありません。 これは開発環境にとっては良いことかもしれませんが、デプロイ環境(製品版の環境等)では少々問題があります。

デプロイの場面では、デプロイを行うあなたのUnixユーザーは、 システムへGemをインストールするためのアクセス権を持っていないかもしれません。 例えそれを行うユーザー(またはsudoを使用)であっても、 そのユーザーはアプリケーション起動へのアクセス権が無いかもしれません。 例えば、Passengerはある程度制限されるnobodyユーザーで、そのRubyのサブプロセスを実行します。 デプロイ環境でのトレードオフになりますが、より強く権限を分離することが推奨されています。 (サードパーティ製の依存関係の変更があった際に、bundle installに掛かるデプロイ時間を多少犠牲にしても)

結果として、--deploymentフラグを付けてカプセル化を行うことは、 デプロイ環境でBundlerを使用する際のベストプラクティスと言えます。 これらのプラクティスは、多くのバグレポートと同様に、 Bundlerの開発中に私達が受け取った重要なフィードバックが基になっています。 デプロイ時にBundlerをどのように設定するのがベストなのか、誤解を解くためのものが主に反映されています。 --deploymentフラグは、デフォルトで下記の処理を加えます。

  • システム(system)の場所へGemをインストールする代わりに、 Bundlerはアプリケーション内のvendor/bundleへGemをインストールします。 Bundlerはアプリケーション内部でこれを実行した際に、実行したユーザーに意識させることなく、この場所を記憶します。 (Bundler.setupBundler.requireを使用して)
  • Bundlerはシステムに既にインストールされているGemが存在していたとしても、それを使用しません。
  • もし、bundle packを実行すると、Bundlerはvendor/cacheディレクトリと、 何らかのGitのGemが無いことを調べ、bundleのインストール中にインターネットへ接続しないようにします。
  • BundlerはGemとそのバージョンのスナップショットであるGemfile.lockを必要とするため、 それが提供されない場合、その処理は失敗します。
  • BundlerはGemfileの指定の範囲外であったとしても、 Gemfile.lockの更新を行いません。

もしCapistranoを使用しているのであれば、 vendor/bundleからshared/vendor_bundleへのシンボリックリンクを張ることで、 Bundlerはデプロイ環境間のインストールGemを共有しますが、 他のアプリケーションから切り離す利点は依然として享受することが出来ます。

デフォルトの挙動により、デプロイ処理の一環としてbundleのディレクトリであるvendor/bundleに、 バンドル指定されたものがインストールされるため、 アプリケーションをチェックアウトした同じUnixユーザーで、 アプリケーションが必要とするサードパーティ製のコードを確認することが出来るようになります。 これは、もしPassenger(またはUnicorn)がアプリケーションを参照することが出来れば、 それに依存するもの(サードパーティ製のGem等)も同様に参照可能であることを意味します。

--deploymentフラグは、 製品版へ反映するためのコードとしてテストが完了されている(開発環境developmentとステージングで)事を確定するために、 最新のGemfile.lockを必要とします。 bundle checkを実行することで、デプロイ前にGemfile.lockが最新であることを確認することが出来ます。 もし、最後にGemfileを変更してからbundle installを実行し、 アプリケーションが正常に起動したのであれば、それが常に最新になることに注意して下さい。

 Back to top

© 2010 - 2017 STUDIO KINGDOM