Capistranoはサーバの遠隔操作を自動化する多目的なツールです。以下では特に Rails4 を Capistrano3 でデプロイする基本的な方法をまとめます。Rails の場合は Capistrano の設定が gem で提供されているため、Capistrano の知識がなくても基本的なデプロイはできます。独自にカスタマイズしたい場合など、本ページの内容を越えるものは公式ページを参照してみてください。また、Capistranoは v3 と v2 の違いが大きく、v3 を対象とした以下の内容は v2 には適用できないことに注意してください。
デプロイするRailsアプリケーションを、こちらのページを参考に用意しましょう。ここではbundlerの使用を前提にしています。ご存知でない方はこちらを参照してみてください。
$ bundle init
$ vi Gemfile
gem "rails", "4.1.8"
$ bundle install --path vendor/bundle
$ bundle exec rails new myApp --skip-bundle
$ rm -f Gemfile
$ rm -f Gemfile.lock
$ rm -rf .bundle
$ rm -rf vendor/bundle
$ cd myApp
$ vi Gemfile
gem 'therubyracer', platforms: :ruby
$ bundle install --path vendor/bundle
$ bundle package
./vendor/cache/*.gem に保存されます。利点は、誰かがプロジェクトに新規に参加した場合に...
保存したGemを用いてのインストール方法は以下の通りです。
$ bundle install --path vendor/bundle --local
$ bundle exec rails generate scaffold myModel field1:string field2:integer field3:date field4:boolean
$ bundle exec rake db:migrate
$ bundle exec rails server
アクセスしてみましょう: http://localhost:3000/my_models
Capistrano v3 を用いて、上記手順で用意したアプリケーションをリモートサーバにデプロイしてみましょう。まずはローカルマシンの設定です。
Capistrano v3 は SCM (source code management) の存在を前提としています。デプロイを行う際、直接ローカルマシンからアップロードするのではなく、リモートサーバでSCMレポジトリからソースコードを取得するためです。ここではSCMの中でもGitを採用します。GitHub, Bitbucket, 社内GitLabなど適当な場所にアップロードします。ここでは GitHub/harubot/capistrano_sample にアップロードしました。
$ cp config/database.yml config/database.yml.example
$ ssh-keygen
$ git init
$ vi .gitignore
/vendor/bundle ← 追記
/config/database.yml ← 追記
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:harubot/capistrano_sample.git
$ git push -u origin master
Capistrano v3 本体に加えて、各種拡張用のGemを rails の Gemfile に追記します。ここでは、rbenv, bundler, passenger の使用を前提にしています。rbenvおよびbundlerについてご存知でない方はこちらを参照してみてください。
また "capistrano-passenger" はこちらの公式ページで紹介されている、デプロイ時にPassengerを再起動するためのツールです。使用方法は、後述のCapfileで「require 'capistrano/passenger'」するだけです。"passenger + apache" ではなく "nginx + unicorn" をHTTPサーバに採用している場合などは不要です。更に "capistrano-withrsync" はリモートサーバからGitレポジトリに直接アクセスできない場合に重宝するGemパッケージです。これについては後述します。
$ vi Gemfile
...
gem 'capistrano', '3.2.1'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'capistrano-rbenv'
gem 'capistrano-passenger'
# gem 'capistrano-withrsync', '0.1.0', require: false
$ bundle update
$ bundle package ← 任意です。前述。
$ git add .
$ git commit -m 'add capistrano related gems'
$ git push
例えば社内GitLabにプロジェクトのレポジトリがあり社外サーバにデプロイしなければならない場合、社外サーバから社内のGitLabのレポジトリにアクセスできず、結果としてCapistrano v3 が使用できないという事態が発生します。このような場合の解決策の一つとして capistrano-withrsync があります。これを導入すると、ローカルマシンがGitレポジトリからpullしたものをrsyncでリモートサーバに送ることができるようになります。導入は簡単です。前述の通りRailsのGemfileに以下の一行を追記して
gem 'capistrano-withrsync', '0.1.0', require: false
更に後述のCapfileに以下の一行を追記するだけです。これだけで、特に明示的な設定をすることなく裏で勝手にrsyncしてくれるようになります。
require 'capistrano/withrsync'
なお "require: false" はWEBrickなどでエラーが発生するためautorequireしないようにする設定です。
以下のコマンドで設定ファイルの雛形を生成します。
$ bundle exec cap install
Capfileに必要なGemを追記します。
$ vi Capfile
...
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/passenger'
# require 'capistrano/withrsync' ← 必要に応じて追記 (前述)
デプロイ設定を以下のファイルに記述します。
config/deploy.rb
# config valid only for Capistrano 3.1
lock '3.2.1'
set :application, 'capistrano_sample'
set :repo_url, 'https://github.com/harubot/capistrano_sample.git'
# Default branch is :master
set :branch, 'master'
# Default value for :scm is :git
set :scm, :git
# Default value for :format is :pretty
set :format, :pretty
# Default value for :log_level is :debug
set :log_level, :debug
# Default value for :pty is false
set :pty, true
# Default value for :linked_files is []
set :linked_files, %w{config/database.yml} ← デプロイ対象としたくないファイルを記載
# Default value for linked_dirs is [] ↓ デプロイ対象としたくないディレクトリを記載
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# Default value for default_env is {} (↓rbenvがシステムインストールされている場合の設定)
set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }
# Default value for keep_releases is 5
set :keep_releases, 5
# rbenvの設定 (/usr/local/rbenv に 2.1.3 をインストールすることを想定)
set :rbenv_type, :system
set :rbenv_ruby, '2.1.3'
# bundlerを実行する際の引数
set :bundle_flags, "--deployment --without development test"
#set :bundle_flags, "--deployment --without development test --local"
#↑前述の bundle package を利用する場合
# サーバ設定 (公開鍵認証の場合は "password" の項目は不要です)
set :password, ask('Server password', nil)
server '192.168.56.11', user: 'capcap', port: 22, password: fetch(:password), roles: %w{web app db}
# server '192.168.56.12', user: 'capcap', port: 22, password: fetch(:password), roles: %w{web app db}
# ↑複数サーバーにデプロイする場合
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
# execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
config/deploy/staging.rb
# Default deploy_to directory is /var/www/my_app
set :deploy_to, '/var/www/capistrano_sample/capistrano_sample.staging'
# If the environment differs from the stage name
set :rails_env, 'staging'
config/deploy/production.rb
# Default deploy_to directory is /var/www/my_app
set :deploy_to, '/var/www/capistrano_sample/capistrano_sample.production'
# If the environment differs from the stage name
set :rails_env, 'production'
設定ファイルを作成し終えたらコミットしておきましょう。最終的に追加した内容はこちらです。sequence
, groups
, limit
, wait
の意味については『Capistrano 3 で複数のサーバーを同時に SSH 経由で操作する』をご参照ください。
Capistranoでログインするユーザを作成します。パスワードも設定しましょう。
$ sudo adduser capcap
$ sudo passwd capcap
インストール済みであれば本作業は不要です。
$ sudo yum install gcc
$ sudo yum install gcc-c++
$ sudo yum install openssl-devel
$ sudo yum install sqlite-devel
$ sudo yum install httpd
インストール済みであれば本作業は不要です。rbenvを /usr/local/rbenv にシステムインストールする手順を記載します。ユーザローカルにインストールする方法はこちらを参照してください。
$ sudo mkdir /usr/local/rbenv
$ sudo chmod 775 /usr/local/rbenv
$ sudo git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
$ sudo mkdir /usr/local/rbenv/plugins
$ sudo git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build
$ sudo touch /etc/profile.d/rbenv.sh
$ sudo vi /etc/profile.d/rbenv.sh
export RBENV_ROOT=/usr/local/rbenv
export PATH=$RBENV_ROOT/bin:$PATH
eval "$(rbenv init -)"
$ sudo su -l
# rbenv install 2.1.3
# rbenv rehash
# rbenv global 2.1.3
# rbenv exec gem install bundler
# rbenv rehash
# exit
$ sudo su -l
# mkdir /var/www/capistrano_sample
# chown capcap: /var/www/capistrano_sample
# exit
$ sudo su -l capcap
$ mkdir -p /var/www/capistrano_sample/capistrano_sample.staging/shared/config/
$ mkdir -p /var/www/capistrano_sample/capistrano_sample.production/shared/config/
$ exit
以下の手順で生成した鍵をGithubに登録しましょう。
$ sudo su -l capcap
$ ssh-keygen
$ exit
パスワード情報が記載されている等の理由でGit管理外になっている、デプロイ対象外にしたいファイルが存在しています。具体的にはdatabase.ymlなどです。このようなファイルは前述の通り deploy.rb における linked_files で指定します。指定することによってデプロイ対象ではなくなるため、何らかの手段で予めアップロードしておく必要があります。Chefでリモートサーバの構成管理をしているのであればレシピに含めておくのが理想的です。そうでない場合、例えばローカルマシンで以下のコマンドを実行して設置しましょう。
$ scp config/database.yml capcap@192.168.56.11:/var/www/capistrano_sample/capistrano_sample.staging/shared/config/
$ scp config/database.yml capcap@192.168.56.11:/var/www/capistrano_sample/capistrano_sample.production/shared/config/
以下のコマンドでリモートサーバにRailsアプリケーションを設置できます。それぞれステージング環境および本番環境へのデプロイコマンドです。Passengerの再起動もなされます。
$ bundle exec cap staging deploy
$ bundle exec cap production deploy
以上の基本形に加えてプロジェクトコードのデプロイ時の挙動をカスタマイズするためには、以下のサイトを参考に deploy.rb 等を作り込めばよいです。『Capistrano 3 で複数のサーバーを同時に SSH 経由で操作する』をご参照ください。