capistrano 3.xでrails appをdeployするときにハマったこと
railsアプリをデプロイするときに最近流行のCIってやつに乗ってみるかと思って、普段なら手動デプロイしていたところを自動デプロイすることにした。
調べてみたらどうやらcapistranoという、ほぼデファクトスタンダードになっているgemがあるとのことだったので、使うことにした。
ところがこのcapistrano、2013年8月頃に3.xにメジャーアップデートしたらしい。
しかも、このアップデートで2.x系との互換性を捨ててしまったらしく、3.x向けの情報がやたらと少ない。
ここでおとなしく2.xを使えばよかったものの、新物に目がない僕は3.xを使うという愚行を下してしまったのだった…
というわけで、1日半くらいはハマりました。
この記事で少しでも多くの人がcapistranoを上手く使いこなし、自動デプロイの恩恵に与れることを期待しています。
capistranoの基本的な使い方
僕はこの記事を参考にしました。
Capistrano 3系でRails4.1のデプロイ[rbenv][rvm][ruby2.1] - 酒と泪とRubyとRailsと
ひとまずは、この通りにやってみます。
config/deploy.rb、config/deploy/production.rbあたりを書いて、
bundle exec cap production deploy:check bundle exec cap production deploy
を実行します。
僕の場合は、最後のコマンドを実行するところで大量のエラーが発生しました。
SSHが通らない
SSHKit::Runner::ExecuteError: Exception while executing on host example.com: Authentication failed for user user@example.com
こんなエラーが出ました。これは、SSHの設定が間違っている可能性が高いです。
僕の場合は、config/deploy/production.rbに設定しているssh_options[:key]が間違っていました。
ここに設定するのは、自分のローカルマシンのSSH公開鍵です。
僕は間違えてサーバの公開鍵のパスを指定していました。
サーバ上でリポジトリをcloneできない
executing locally: "git ls-remote git@github.com:myuser/myrepo.git HEAD"
Permission denied (publickey).
fatal: Could not read from remote repository.
こんな感じのエラーです。permission deniedということは、これもSSHの認証周りか?と思いまずはサーバ上で
git ls-remote git@github.com:myuser/myrepo.git HEAD
できるか試してみました。すると、秘密鍵のパスフレーズを要求されました。
パスフレーズを正しく入れると、きちんとエラーなく実行できました。
つまり、capistranoはパスフレーズの入力でこけていたみたいです。
本当はcapistranoがユーザにパスフレーズの入力を促すべきなのでしょうが、現在パスフレーズの入力コンソール周りにバグがあるらしく、エンターを押しても入力が終了しません。
(デフォルトではパスフレーズを聞いてきませんが、config/deploy.rbでset :pty, trueとすると聞いてきます)
仕方ないので、とりあえずパスフレーズ無しの秘密鍵を生成してgithub等に登録します。
rbenv: bundle: command not found
このエラーが出たときは、まずは最初の参考記事の通り、rbenvの設定に問題がないか見てみてください。
set :rbenv_type, :user set :rbenv_ruby, '2.0.0-p451' 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
(参考記事とrubyのバージョンが違います)
その後、サーバ側のrbenvに対応するバージョンのrubyがrbenvでインストールされているか確認してください。
mysql.h missingでmysql2がインストールできない
これは、サーバにmysql-develをインストールすることで解決できます。
ところが、僕の場合は
sudo yum -y install mysql-devel
だけではエラーが出てインストールできませんでした。
sudo yum -y install mysql-devel.x86_64 --enablerepo=remi
でインストールできました。
【参考】mysql2 - sudo yum install mysql-devel でインストール出来ない - Qiita
Could not locate Gemfile
capistranoがGemfileを見つけられないエラーです。
僕の場合はrailsのアプリがgitリポジトリのサブディレクトリに含まれていました。
一応capistrano側でサブディレクトリを指定する方法もあるみたいですが、僕が見つけられたのは2.xで通用する方法ばかりで、3.xで試してもどうもうまくいきませんでした。
gitリポジトリのサブディレクトリを切り出して新しいリポジトリにする方法が紹介されていたので、試してみるといいでしょう。
ちなみに僕の場合は、諸事情があって他の人の未stage済の変更があってgit filter-branchできなかったので、諦めてrailsアプリを丸ごとcpして切り出しました。
なんか上手い方法はないものだろうか…
【参考】capistrano で サブディレクトリ 内の 特定アプリ をデプロイする - てしりこじり
【参考】Gitリポジトリ中のサブディレクトリを別のリポジトリにする - 北海道苫小牧市出身のPGが書くブログ
終わりに
僕がcapistrano側でハマったのはだいたいこれくらいでした。
実は、railsアプリをdeployするのは初めてだったので、capistranoでうまくdeployした後にApache+Passenger+Railsを連携させるところでも少しハマりました。
その部分についてはcapistranoよりは情報が多いと思うので、ここでは割愛させていただきます。