Rails4のデプロイでCapistrano3の基本的な使い方を把握する
[履歴] [最終更新] (2016/07/04 01:43:17)
最近の投稿
注目の記事

概要

Capistranoはサーバの遠隔操作を自動化する多目的なツールです。以下では特に Rails4 を Capistrano3 でデプロイする基本的な方法をまとめます。Rails の場合は Capistrano の設定が gem で提供されているため、Capistrano の知識がなくても基本的なデプロイはできます。独自にカスタマイズしたい場合など、本ページの内容を越えるものは公式ページを参照してみてください。また、Capistranoは v3 と v2 の違いが大きく、v3 を対象とした以下の内容は v2 には適用できないことに注意してください。

サンプルアプリケーションの準備

デプロイするRailsアプリケーションを、こちらのページを参考に用意しましょう。ここではbundlerの使用を前提にしています。ご存知でない方はこちらを参照してみてください。

RailsのGemパッケージをbundlerで用意

$ bundle init
$ vi Gemfile
gem "rails", "4.1.8"
$ bundle install --path vendor/bundle

Railsアプリの雛形を用意

$ bundle exec rails new myApp --skip-bundle

不要になったのでGemパッケージを削除

$ rm -f Gemfile
$ rm -f Gemfile.lock
$ rm -rf .bundle
$ rm -rf vendor/bundle

Railsアプリ内で必要なGemパッケージをインストール

$ cd myApp
$ vi Gemfile
gem 'therubyracer', platforms: :ruby
$ bundle install --path vendor/bundle

インストールしたGemをローカルに保存 (任意)

$ bundle package

./vendor/cache/*.gem に保存されます。利点は、誰かがプロジェクトに新規に参加した場合に...

  • WebからGemが消失した場合に備える
  • 高速にbundle installできる
  • オフラインでもbundle installできる

保存したGemを用いてのインストール方法は以下の通りです。

$ bundle install --path vendor/bundle --local

Scaffoldで簡易なアプリを作成してアクセス

$ 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 を用いて、上記手順で用意したアプリケーションをリモートサーバにデプロイしてみましょう。まずはローカルマシンの設定です。

GitHubへのアップロード

Capistrano v3 は SCM (source code management) の存在を前提としています。デプロイを行う際、直接ローカルマシンからアップロードするのではなく、リモートサーバでSCMレポジトリからソースコードを取得するためです。ここではSCMの中でもGitを採用します。GitHub, Bitbucket, 社内GitLabなど適当な場所にアップロードします。ここでは GitHub/harubot/capistrano_sample にアップロードしました。

database.yml は管理から除外するためコピー

$ cp config/database.yml config/database.yml.example

SSH鍵の生成

$ ssh-keygen

Gitレポジトリへのアップロード

$ 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

Railsアプリ内にCapistranoをインストール

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

capistrano-withrsync について (参考情報)

例えば社内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しないようにする設定です。

Capistranoの設定ファイルを準備

以下のコマンドで設定ファイルの雛形を生成します。

$ 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/deploy/staging.rb : ステージング環境に特化したデプロイ設定
  • config/deploy/production.rb : 本番環境に特化したデプロイ設定

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

各種RPMパッケージのインストール

インストール済みであれば本作業は不要です。

$ sudo yum install gcc
$ sudo yum install gcc-c++
$ sudo yum install openssl-devel
$ sudo yum install sqlite-devel
$ sudo yum install httpd

rbenvのインストール

インストール済みであれば本作業は不要です。rbenvを /usr/local/rbenv にシステムインストールする手順を記載します。ユーザローカルにインストールする方法はこちらを参照してください。

インストール先のディレクトリを作成

$ sudo mkdir /usr/local/rbenv
$ sudo chmod 775 /usr/local/rbenv

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 -)"

rubyおよびbundlerのインストール

$ 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

SSH鍵の作成

以下の手順で生成した鍵をGithubに登録しましょう。

$ sudo su -l capcap
$ ssh-keygen
$ exit

「linked_files」で指定したファイルの設置 ← はまりポイントです。重要です

パスワード情報が記載されている等の理由で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 経由で操作する』をご参照ください。

関連ページ
    概要 SSH関連で活用できると便利な以下の二つの事項についてまとめます。 SSH接続の設定ファイル「~/.ssh/config」によく記述する内容 SSH接続時に秘密鍵のパスワード入力を省略する ssh-agent の利用方法 SSH config 踏み台サーバ step を経由して internal-0001 にアクセスする設定ファイルの例を記載します。設定項目の意味については「ma
    概要 「rbenv および bundler の基本的な使用方法」の perl 版です。 plenv の基本 インストール GitHub からダウンロードしてインストールします。 git clone https://github.com/tokuhirom/plenv.git ~/.plenv git clone https://github.com/tokuhirom/Perl-B
    概要 Puma は Ruby/Rack アプリケーションのための HTTP サーバです。Rails の場合に関する使用方法をまとめます。 事前準備 JRuby のインストール こちらのページを参考にして rbenv による ruby インストールを行います。公式ページによると、パフォーマンスを最大限に引き出すためには正式にスレッドをサポートしている Rubinius または
    概要 sbt は Scala および Java を主な対象としたビルドツールです。Scala Build Tool の略ではありませんが、Simple Build Tool という明示的な記述も公式ドキュメントなどには見当りません。以下 sbt の基本的な使用例をまとめます。使用した sbt のバージョンは 0.13 です。
    概要 Capistrano は複数のサーバーに ssh して何らかの処理を実行するための汎用ツールです。こちらのページでは Rails のデプロイツールとしての Capistrano 3 の使用方法をまとめました。Rails のデプロイに関しては Capistrano の設定が gem で提供されているため、独自に Capistrano の設定をする必要はありませんでした。ここでは Rails
    概要 rubyは他の言語と比較してバージョンによる差異が大きく、異なるバージョンのrubyを使用している複数のプロジェクト業務をあるPCで行う場合に、プロジェクト毎に適切なバージョンのrubyを有効化および実行する必要が発生します。この要求はrbenvというツールを使用することで満たすことができます。つまり、rbenvは複数バージョンのrubyが同一システム内に共存することを可能にします。