Rails4のデプロイでCapistrano3の基本的な使い方を把握する
[履歴] [最終更新] (2016/07/04 01:43:17)
1
作品
331
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のための作品販売プラットフォーム

ハードウェア技術を作品にして販売してみませんか?
新着作品

概要

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 経由で操作する』をご参照ください。