19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails 4 へ移行して Capistrano でのデプロイに失敗したまとめ

Last updated at Posted at 2015-06-23

Rails 3.2 からRails 4.2 に移行した際に、Capistrano 3 でのデプロイにハマった件。

環境

Ruby 2.1.4
Rails 4.2.1
Capistrano は、Rails 3.2 のものをそのまま使用した。

Gemfile
  gem 'capistrano', '~> 3.0.1'
  gem 'capistrano-rails', '~> 1.1'
  gem 'capistrano-rbenv', '~> 2.0'
  gem 'capistrano-bundler'

デプロイコマンド

bundle exec cap production deploy

ブランチが既に存在する旨のエラーメッセージ

INFO [9d4092d6] Running /usr/bin/env git branch issues/123-some-fixes origin/issues/123-some-fixes as yamy@localhost
cap aborted!
SSHKit::Command::Failed: git exit status: 32768
git stdout: Nothing written
git stderr: fatal: A branch named 'issues/123-some-fixes' already exists.
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/command.rb:95:in `exit_status='
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/backends/local.rb:85:in `block (2 levels) in _execute'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/backends/local.rb:63:in `block in _execute'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/backends/local.rb:58:in `tap'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/backends/local.rb:58:in `_execute'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.7.1/lib/sshkit/backends/local.rb:27:in `execute'
/path/to/project/lib/capistrano/tasks/git.cap:25:in `block (4 levels) in <top (required)>'

以下にエラーメッセージの該当箇所があった。

lib/capistrano/tasks/git.cap
    desc 'override git.rake taske update for repository'
    task :update do
      run_locally do
        execute :git, :fetch, :origin
        current_dir = capture "pwd"
        if test " [ -f #{current_dir}/.git/refs/heads/#{fetch(:branch)} ] "
          info "the branch #{fetch(:branch)} already exists at local"
        else
          execute :git, :branch, "#{fetch(:branch)}", "origin/#{fetch(:branch)}"
        end
      end
    end

ロガーを追加して実行。

正常系(Rails 3.2)

INFO [18a14868] Running /usr/bin/env git fetch origin on
INFO [18a14868] Finished in 2.780 seconds with exit status 0 (successful).
INFO @@
INFO /path/to/project/.git/refs/heads/issues/100-some-fixes

失敗(Rails 4.2)

INFO [53acc449] Running /usr/bin/env git fetch origin as yamy@localhost
INFO [53acc449] Finished in 2.923 seconds with exit status 0 (successful).
INFO @@
INFO /path/to/project
/.git/refs/heads/issues/123-some-fixes

プロジェクトルート以降で改行されているため、先の判定処理で false になっているようだ。
さらに見ると、以下で改行が付加されていることが分かった。

lib/capistrano/tasks/git.cap
current_dir = capture "pwd"

capturegem 'sshkit' のメソッドで、移行作業の影響で capistrano と依存関係の gem のバージョンが更新されていることに気付いた。(sshkit 1.7.1)

Gemfile.lock を見て、他の gem との依存関係も問題なさそうなので、前のバージョンに戻した。もともと明示的には Gemfile に追加していなかった。

Gemfile
  gem 'sshkit', '1.4.0'

これで、先のエラーは解消した。

rake assets:precompile が失敗する

 INFO [c7d908ef] Running RBENV_ROOT=/usr/local/rbenv RBENV_VERSION=2.1.4 /usr/local/rbenv/bin/rbenv exec bundle exec rake assets:precompile on some-production-server
cap aborted!
SSHKit::Command::Failed: rake exit status: 1
rake stdout: Nothing written
rake stderr: Nothing written
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.4.0/lib/sshkit/command.rb:98:in `exit_status='
/path/to/project/vendor/bundle/ruby/2.1.0/gems/sshkit-1.4.0/lib/sshkit/backends/netssh.rb:142:in `block (4 levels) in _execute'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/net-ssh-2.9.2/lib/net/ssh/connection/channel.rb:551:in `call'
/path/to/project/vendor/bundle/ruby/2.1.0/gems/net-ssh-2.9.2/lib/net/ssh/connection/channel.rb:551:in `do_request'

しばらくこの情報をもとに調べていたが一向に解決せず、ふと Capistrano の Log level の存在を思い出し、 debug に設定して確認。

config/deploy.rb
#set :log_level, :info
set :log_level, :debug
DEBUG [dfb6c8fe]        rake aborted!
DEBUG [dfb6c8fe]        NameError: uninitialized constant ActiveRecord::Observer
DEBUG [dfb6c8fe]        /path/to/project/shared/bundle/ruby/2.1.0/gems/multi_db-0.3.1/lib/multi_db/connection_proxy.rb:57:in `setup!'
DEBUG [dfb6c8fe]        /ebs01/path/to/project/releases/20150623083226/config/environments/production.rb:71:in `block (2 levels) in <top (required)>'
DEBUG [dfb6c8fe]        /path/to/project/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/lazy_load_hooks.rb:36:in `call'

しっかりエラーが表示されていた。

どうやら、Rails 4.0 から Observer が削除されたらしく、以下をGemfileに追加してリポジトリにpush。

Gemfile
gem "rails-observers"

参照: https://github.com/rails/rails-observers

devise のパラメタ不足

DEBUG [3b3ed770]        rake aborted!
DEBUG [3b3ed770]        Devise.secret_key was not set. Please add the following to your Devise initializer:
DEBUG [3b3ed770]
DEBUG [3b3ed770]          config.secret_key = '***'
DEBUG [3b3ed770]
DEBUG [3b3ed770]        Please ensure you restarted your application after installing Devise or setting the key.
DEBUG [3b3ed770]        /path/to/project/shared/bundle/ruby/2.1.0/gems/devise-3.5.1/lib/devise/rails/routes.rb:480:in `raise_no_secret_key'
DEBUG [3b3ed770]        /path/to/project/shared/bundle/ruby/2.1.0/gems/devise-3.5.1/lib/devise/rails/routes.rb:209:in `devise_for'
DEBUG [3b3ed770]        /ebs01/path/to/project/releases/20150623094342/config/routes.rb:9:in `block in <top (required)>'

config/initializers/devise.rbに追加。

config/initializers/devise.rb
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
  # The secret key used by Devise. Devise uses this key to generate
  # random tokens. Changing this key will render invalid all existing
  # confirmation, reset password and unlock tokens in the database.
  config.secret_key = '***'

assets compile の設定が一部変更されている

DEBUG [9b394669]        rake aborted!
DEBUG [9b394669]        NoMethodError: undefined method `new' for true:TrueClass
DEBUG [9b394669]          (in /ebs01/path/to/project/releases/20150623095211/app/assets/javascripts/application.js)
DEBUG [9b394669]        /path/to/project/shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/context.rb:196:in `block in evaluate'
DEBUG [9b394669]        /path/to/project/shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/context.rb:194:in `each'
DEBUG [9b394669]        /path/to/project/shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/context.rb:194:in `evaluate'
DEBUG [9b394669]        /path/to/project/shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/bundled_asset.rb:25:in `initialize'
DEBUG [9b394669]        /path/to/project/shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:377:in `new'

以下の記事を元に、config/environments/production.rbを修正。

config/environments/production.rb
   # Compress JavaScripts and CSS
-  config.assets.js_compressor = true
+  config.assets.js_compressor = :uglifier

参照: http://stackoverflow.com/questions/21047556/undefined-method-new-for-truetrueclass-when-precompiling-assets

assets のバックアップまわりで変更があった

DEBUG [6a19f5e1]        cp:
DEBUG [6a19f5e1]        target `/path/to/project/releases/20150623102330/assets_manifest_backup' is not a directory

以下の記事を参考に Capistrano 関連の gem のバージョンを調整。
最新版の Capistrano 3.4.0 ~ 3.2.0 までダウングレードした結果、3.1.0 でエラーがなくなった。

Gemfile
-  gem 'capistrano', '~> 3.0.1'
-  gem 'capistrano-rails', '~> 1.1'
+  gem 'capistrano', '3.1.0'
+  gem 'capistrano-rails', '~> 1.1.3'

参照: http://stackoverflow.com/questions/29617239/capistrano-3-sprockets-3-rails-4-2-1-wont-deploy

以上で、ようやく正常にデプロイされた。

まとめ

Capistrano は依存関係にある gem のバージョンにかなりシビアであることを再認識した。Rails 4 への移行の際、意図せず依存関係の gem が更新されていないか、事前に確認しておくと良さそうです。

19
15
0

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
19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?