トップ «前の日記(2014-05-08) 最新 次の日記(2014-05-14)» 編集

Route 477



2014-05-13

[ruby] Capistrano3でbitbucketからさくらVPSにデプロイする

Capistrano3はRails界隈でよく使われるデプロイツールであるCapistrano2、を一から書き直したプロジェクトである。互換性はない。まあ「Cap2で運用できてるなら無理に上げる必要はない」と公式のどっかにも書いてあったと思うので、当面はCap2の方がおすすめ。 大きな非互換としては、copy strategyが無くなっている。サーバからリポジトリが直接見えない環境、けっこうありそうな気がするけど、そうでもないんだろうか。

ともかくひと通り動かしてみたのでメモ。

環境

  • 開発は手元のMacBook
  • リポジトリはbitbucketのprivateリポジトリ (=git pullには何らかの認証が必要)
  • サーバはさくらVPS(とタイトルには書いてみたけど、特に固有の事情とかはない。Rubyはrbenvで入れている)

インストール

Gemfileに以下を追加

gem 'capistrano', '>= 3'
gem 'capistrano-bundler'
gem 'capistrano-rbenv'
$ bundle install
$ bundle exec cap install

今回はSinatraアプリなんで関係ないけど、Railsの場合はcapistrano-railsとかも要ると思う。

サーバ設定

config/deploy/production.rbを以下のように書く。 ここではサーバを1台だけ登録し、web/app/dbすべての役割を担当させている。SSHのポートを22以外にしてるのでssh_optionsを指定している。

server 'sakura',
 user: 'yhara',
 roles: %w{web app db},
 ssh_options: {
   port: 12345,
   forward_agent: false,
   auth_methods: %w(publickey)
 }

デプロイ設定

config/deploy.rbを適宜編集する。今回は以下の箇所を変更した。

set :application, 'app1'
set :repo_url, 'git@bitbucket.org:yhara/app1.git'
set :deploy_to, '/home/yhara/service/app1'
set :linked_dirs, %w{db tmp}   # ./dbというディレクトリをリリース間で共有したかったので指定している

SSHの設定

サーバからbitbucketにSSHでアクセスできる必要がある。

  • bitbucketにSSH鍵を登録
  • ~/.ssh/config というファイルを作成し、chmod 600する
Host bitbucket.org
  IdentityFile ~/.ssh/id_rsa_bitbucket

サーバ上で git ls-remote git@bitbucket.org:yhara/app1.git とかやってみてエラーがでなければOK。

Cap3 + bundler

このままだとデプロイしてもbundle installしてくれないので、capistrano-bundlerを有効化する

Capfileに require 'capistrano/bundler' を追加すると、デプロイ時にbundle installするようになる。

設定はとくに要らないけど、いくつか項目はある(README参照)。例えばデフォルトだと./shared/bundleにgemがインストールされるが、Rubyのgemsディレクトリに直接インストールしたい場合は以下のようにする。

set :bundle_binstubs, nil
set :bundle_path, nil

Cap3 + rbenv

サーバでrbenvを使っているためか、/usr/bin/env bundleが実行できないというエラーが出た。capistrano-rbenvも有効化してみる。

  • Capfileに require 'capistrano/rbenv' を追加
  • config/deploy.rbに以下を追加
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.1.1'
#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

これでbundle installが動くようになり、サーバ上にcurrentディレクトリが無事生成された。

デプロイ

$ bundle exec cap production deploy:check
$ bundle exec cap production deploy

これでいけた。