デプロイ
Bundleされたアプリケーションのデプロイ
Bundlerを使用したアプリケーションをデプロイする前に、
ソースコードのバージョン管理システムへGemfileとGemfile.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オプションを使用することで、
実行(バイナリ)ファイルを生成する事が可能です。
Heroku
Herokuへデプロイする際には、Gemfileが提供されていれば自動的にBundlerが実行されます。
Gemfile.lockをチェックインすると、Herokuはbundle install --deploymentを実行します。
もし--withoutオプションを使用して特定のグループを除きたい場合は、
heroku configを使用する必要があります。
$ heroku config:add BUNDLE_WITHOUT="test development" --app app_name
アプリケーションのデプロイについて
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.setupとBundler.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を実行し、
アプリケーションが正常に起動したのであれば、それが常に最新になることに注意して下さい。
© 2010 - 2017 STUDIO KINGDOM