はじめに
capistrano3を使ってデプロイしようとした時にエラーがでて詰まった話。
capistranoは3.10.1。CentOS6.10。
# cap --version
Capistrano Version: 3.10.1 (Rake Version: 12.3.0)
エラー
bundle exec cap staging deploy
を実行したら以下エラーが発生しました。
bundle stdout: Nothing written
bundle stderr: /usr/bin/env: bundle: No such file or directory
原因
上記エラーを私なりに解釈するとbundle
コマンドが無い!らしい・、な、なるほど!原因は単純でデプロイ先のサーバでbundle
コマンドが見つからないよ!ということです。ウーん、なぜみつからないの?
bundleどこ
bundle exec cap staging deploy
を実行している環境のbundle コマンドの所在を確認してみました。
# which bundle
/root/.rbenv/shims/bundle
u~n、なるほど!
まず、rootユーザにrbenvをインストールしています。rubyのバージョンを管理できるあれですね!そして# gem install bundler
を実行してbundleコマンドをインストールしていました。よってrbenv配下の/root/.rbenv/shims/bundle
に存在するわけですね。
ちなみにgemコマンドどこ
rubyもrbenvで管理しているのでgemもそのrbenvの管理に置かれます。
which gem
/root/.rbenv/shims/gem
どうすればよい
まとめるとデプロイ先のサーバでbundleコマンドを使えるようにするために、デプロイ先のサーバでも(同じ様に)rbenv環境を構築してcapistranoからそのrbenv配下のbundleコマンドを利用出来るようにすれば上手くいくはずです!
(またはrbenvを使わずともbundleコマンドを使えるようにすればよいと思いますが、例えばシステムにrubyを入れてパスを通すみたいな、ですが、rbenvがスマートなやり方なのでrbenvを使った方法にします。)
対応
デプロイ先
デプロイユーザでrbenvを使う設定をいれてrubyを使えるようにして+ gem install bundler
ローカル環境
デプロイ先サーバのデプロイユーザでrbenvのbundleを使う設定。capistrano-rbenvを使う。
Gemfile
gem 'capistrano-rbenv'
Capfile
require "capistrano/rbenv"
deploy.rb
set :rbenv_ruby_version, '2.5.1p57'
set :rbenv_path, '/home/deploy/.rbenv' #指定するとこのパスは以下のbundleが、指定しないと$HOME配下のbundleが実行された
set :bundle_path, './vendor/bundle'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} #{fetch(:rbenv_path)}/bin/rbenv exec"
実行結果
set: rbenv_pah ある場合
00:09 bundler:install
01 RBENV_ROOT=/home/deploy/.rbenv RBENV_VERSION= /home/deploy/.rbenv/bin/rbenv exec bundle install --path ./vendor/bundle --without development test --deployment --quiet
set: rbenv_pah がない場合
00:08 bundler:install
01 RBENV_ROOT=$HOME/.rbenv RBENV_VERSION= $HOME/.rbenv/bin/rbenv exec bundle install --path ./vendor/bundle --without development test --deployment --quiet
参考
# Capfile
require 'capistrano/rbenv'
# config/deploy.rb
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.4.2'
# in case you want to set ruby version from the file:
# set :rbenv_ruby, File.read('.ruby-version').strip
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all # default value