今やデプロイツールのデファクトスタンダードとなった『Capistrano3 』。stagingやproductionといった複数環境へのデプロイを標準で対応していたり、bundleやmigration、unicornとの連携なども抜群です。
かなり乗り遅れてしまいましたが、最近ようやくRails4.1をcapistrano3系でデプロイしました。ずっとHerokuやPaaSにばっかり頼っていたのでちょこちょことハマって苦労しました。今後忘れないための忘備録メモっす!
rbenv, rvmの両方に対応しました。オリジナルのcapコマンドの作り方も書きました!
前提条件
今回の環境では次のような環境を想定しています。
# Webサーバ
(1) unicorn
# Rubyのバージョン管理
(2-A) rbenv
(2-B) rvm
# Cron DSL
(3) whenever
rbenv
とrvm
の両方を使う機会があったので忘備録も兼ねて書いておきます。
staging/production環境のデータベースの準備
デプロイ先のDBの接続用ユーザーとデータベースを作成するために、以下のコマンドをstaging環境とproduction環境で実行します。
MySQLの場合
こちらはMySQLを使う場合の手順です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql -u root -p
# 新規ユーザーを作成する場合
GRANT ALL PRIVILEGES ON database_name.* TO user_name@localhost IDENTIFIED BY 'user_password' ;
# 既存のユーザーに権限を追加する場合
GRANT ALL PRIVILEGES ON database_name.* TO user_name@localhost;
CREATE DATABASE database_name;
FLUSH PRIVILEGES;
exit
mysql -u user_name -p
SHOW DATABASES;
> +--------------------------+
> | Database |
> +--------------------------+
> | information_schema |
> | database_name | #<= DBの作成成功
> +--------------------------+
exit
PostgreSQLの場合
こちらは、PostgreSQLを使う場合の手順です。
1
2
3
4
5
6
# postgreユーザーになる
sudo su -
su - postgres
# パスワード付きのユーザーを作成する
createuser -s [ ユーザー名] -P
GitHubまわりの準備
GitHubで管理しているプライベートなリポジトリを使う場合には、ubuntu 12.04にデプロイするときにdeploy keyの設定が必要でした。
# サーバ側でやること
1) GitHubのリポジトリにアクセスするための公開鍵・秘密鍵を生成
cd ~
ssh-keygen -t rsa -C test@example.com
# GitHub側でやること
1) 対象のリポジトリのページへ移動
2) Settingsへ移動
3) Deploy keysへ移動
4) Add Deploy Keysで公開鍵を登録
Gemfileの追加
rbenvを使う場合
Gemfile
に次のGemを追加して、bundle install
を実行。
1
2
3
4
5
6
7
8
9
gem 'whenever' , require : false # cronを使う場合のみ
group :deployment do
gem 'capistrano' , '~> 3.2.1'
gem 'capistrano-rails'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano3-unicorn' # unicornを使っている場合のみ
end
rvmを使う場合
1
2
3
4
5
6
7
8
9
gem 'whenever' , require : false # cronを使う場合のみ
group :deployment do
gem 'capistrano' , '~> 3.2.1'
gem 'capistrano-rails'
gem 'rvm1-capistrano3' , require : false
gem 'capistrano-bundler'
gem 'capistrano3-unicorn' # unicornを使っている場合のみ
end
Capistranoの設定ファイルを生成
以下のコマンドでCapistranoの設定ファイルdeploy.rb
らを生成。
1
bundle exec cap install STAGES = staging,production
Capfileの設定
Capfile
を以下のように変更
rbenvを使う場合
1
2
3
4
5
6
7
8
9
10
11
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano3/unicorn' # unicornを使っている場合のみ
require 'whenever/capistrano' # wheneverを使っている場合のみ
Dir . glob ( 'lib/capistrano/tasks/*.rake' ) . each { | r | import r }
rvmを使う場合
1
2
3
4
5
6
7
8
9
10
11
12
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'rvm1/capistrano3'
require 'capistrano/bundler'
require 'capistrano3/unicorn'
require 'whenever/capistrano'
Dir . glob ( 'lib/capistrano/tasks/*.rake' ) . each { | r | import r }
Capistrano 共通のデプロイ設定
まず、共通のデプロイ情報をdeploy.rb
に記入していきます。
rbenvを使う場合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
lock '3.2.1'
set :application , 'APP_NAME'
set :repo_url , 'git@github.com:xxxx.git'
set :deploy_to , '/server/rails/path/to'
set :keep_releases , 5
set :rbenv_type , :system # :system or :user
set :rbenv_ruby , '2.1.2'
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
set :linked_dirs , %w{bin log tmp/backup tmp/pids tmp/cache tmp/sockets vendor/bundle}
set :unicorn_pid , " #{ shared_path } /tmp/pids/unicorn.pid"
set :bundle_jobs , 4
set :whenever_identifier , -> { " #{ fetch ( :application ) } _ #{ fetch ( :stage ) } " }
after 'deploy:publishing' , 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
rvmを使う場合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
require 'rvm1/capistrano3'
require 'whenever/capistrano'
lock '3.2.1'
set :application , 'APP_NAME'
set :repo_url , 'git@github.com:xxxx.git'
set :deploy_to , '/server/rails/path/to'
set :keep_releases , 5
set :rvm_type , :system
set :rvm1_ruby_version , '2.1.2'
set :linked_dirs , %w{bin log tmp/backup tmp/pids tmp/cache tmp/sockets vendor/bundle}
set :unicorn_pid , " #{ shared_path } /tmp/pids/unicorn.pid"
set :bundle_jobs , 4
set :whenever_identifier , -> { " #{ fetch ( :application ) } _ #{ fetch ( :stage ) } " }
after 'deploy:publishing' , 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
環境別のデプロイ設定
次に環境ごとに異なる設定をconfig/deploy/staging.rb(production.rb)
に記述していきます。
1
2
3
4
5
6
7
8
9
10
11
12
13
set :branch, 'master'
role :app, %w{ USER_NAME@IP_ADDRESS}
role :web, %w{ USER_NAME@IP_ADDRESS}
role :db, %w{ USER_NAME@IP_ADDRESS}
server 'IP_ADDRESS' , user: 'USER_NAME' , roles: %w{ web app db}
set :ssh_options, {
keys: [ File.expand_path( '/key/path/to/' )] ,
forward_agent: true ,
auth_methods: %w( publickey)
}
wheneverの設定
サーバ側のcronの設定をコードで簡単に管理できるwheneverは、『Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.1] 』を参考に設定!
BitBucket/Github(gitリポジトリ)の設定
ここはBitBucket/Githubなどでプライベートなgit リポジトリを使っている場合について書きます。
プライベートなリポジトリを使う方法はいくつかありますが、そのうちの一つの方法として、デプロイ先
のサーバーにid_rsa / id_rsa.pub
を作成して、公開鍵側をBitBucket/Githubに
登録する方法があります。
この方法を使う場合のSSH鍵の作成、登録は、拙著
『SSH認証キーをBitbucket/GitHubに設定しよう! 』
に詳しく書いています!
デプロイ前のチェックリスト・準備
* deploy.rb, staging.rb, production.rbのパラメータをすべて設定したかチェック
* ステージングDB、本番DBの設定をdatabase.ymlに追加しているか?
* デプロイ用Gitリポジトリのブランチが最新の状態か?
上のチェックが完了したら、capコマンドで設定を確認。
(フォルダの生成等も行ってくれます)
1
2
3
4
5
# stagingのチェック
cap staging deploy:check
# productionのチェック
cap production deploy:check
デプロイ手順
デプロイに必要なディレクトリを生成して、デプロイを実行。
1
2
3
4
5
# stagingへのデプロイ
cap staging deploy
# productionへのデプロイ
cap production deploy
オリジナルのcapコマンドの作り方
Capistranoを使うとサーバに入ってちょっとしたコマンドを実行するといったこともcapコマンド化できます。
1
2
3
4
5
6
7
8
9
10
namespace :sample do
desc 'do some rake task'
task :do_some_rake_task do
rvm_prefix = "#{fetch(:rvm1_auto_script_path)}/rvm-auto.sh #{fetch(:rvm1_ruby_version)}"
on roles( :all) do |h|
execute "cd #{current_path} && #{rvm_prefix} bundle exec rake RAILS_ENV=production do_some_rake_task"
end
end
end
end
Apache/Nginxの設定
Apacheのバーチャルホストの設定ファイル(sudo vim /etc/http/conf.d/vhost.conf
など)をApache VirtualHostの設定 を参考に編集。
deploy時にブランチを選択したい場合
set :branck, 'master'
の部分を以下のように書き直し。
1
ask :branch , proc { `git rev-parse --abbrev-ref HEAD` . chomp } . call
unicorn restartがうまくいかない場合
僕は最近100発100中でこれにハマります。あまりに僕が学習能力なくって泣きそうorz…
UnicornにUSR2シグナル送っても無視される(Bundler::GemfileNotFound)
1
2
3
before_fork do | server , worker |
ENV [ 'BUNDLE_GEMFILE' ] = File . expand_path ( 'Gemfile' , ENV [ 'RAILS_ROOT' ] )
end
unicornでBUNDLE_GEMFILE
の場所はちゃんと設定したほうがいいっす!
Special Thanks
capistrano 3.x系を使ってrailsをデプロイ | iii ThreeTreesLight
Capistrano3で快適デプロイ生活!! - Less is Best
変更来歴
(2014-04-25 23:00) 新規作成
(2014-07-08 20:40) rvm対応
(2014-07-10 20:00) wheneverの記述を追記
(2014-11-02 11:55) github/bitbucket周りの設定
(2014-11-22 10:05) オリジナルのcapコマンドの作り方を追加
(2014-12-16 22:10) bundle install のjobsオプションを追加
(2015-01-18 12:20) posgreSQL用の設定手順を追記