Rails アプリ開発していて何かしらファイルを更新したらサーバへアップロードするの今まで手動でやっていたけど、面倒くさいから自動化しようと調べていたら Capistrano を使うのが良さそうだったので使ってみた。以下作業ログをメモ。
http://capistranorb.com/環境はサーバは Ubuntu 14.04, rbenv でバージョン 2.3.0 を使っている。
Capistrano のインストール
Gemfile に以下を記述
gem 'capistrano', '~> 3.0.1'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'capistrano-rbenv'
Gemfile 編集したら bundle install しよう。
Capistrano の設定
必要な Gem をインストールしたら Capistrano の設定に入ろう。まずは cap install コマンドを実行して必要なファイルを生成する。
$ bundle exec cap install
以下のファイル、ディレクトリが生成される。
Capfile
config/deploy.rb
config/deploy/{:stage}.rb
lib/capistrano/tasks/
まず Capfile、ここには使用する ruby やモジュールを指定する。モジュールという言い方で良いのかは不明。
# require 'capistrano/rvm'
require 'capistrano/rbenv'
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.3.0'
# require 'capistrano/chruby'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
:rbenv_ruby で指定する ruby のバージョンはデプロイ先で使っているものを指定する。 capistrano を実行するマシンのバージョンは違っててもかまわない。
ここで指定しておく事で面倒な設定無しに assets:precompile や db:migrate もやってくれるぽい。
次に config/deploy.rb、ここには共通で行う処理や設定を記述する。バージョン管理システムの種類や場所、実行するタスクなどを指定する。
set :application, 'test-capistrano'
set :repo_url, 'ssh://bitbucket/user/example.git'
set :branch, 'master'
set :deploy_to, '/path/to/deploy'
set :scm, :git
set :format, :pretty
set :log_level, :debug
set :pty, true
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:web), in: :sequence, wait: 5 do
sudo 'service apache2 restart'
end
end
:repo_url で指定する URL には .ssh/config で設定したものを記述してある。
最後に deploy 以下にあるステージ別のファイルを設定する。今回は production のみを対象とする。
set :stage, :production
role :web, %w{username@example.com}
server 'example.com', port:10022, user: 'username', roles: %w{web}
set :password, ask('Enter the ssh password:', nil)
set :ssh_options, {
forward_agent: false,
auth_methods: %w(password),
password: fetch(:password)
}
パスワードを設定ファイル内に記述したくないので ask を利用しているのだが、ドキュメントにある文言をコピペしてもパスワードを隠せない。バージョンが違うのか別のミスをしているのかはわからない。とりあえず、上記のようにやればパスワードを入力して、それを利用してサーバへアクセスする事ができる。
複数のサーバを使用するのであれば server の文を増やすか、role 欄にアドレスを記述する。これ多分どっちかあればOKだと思う。自分は server のほうしか指定していない。
ここまで設定したら以下のコマンドでデプロイできる。
bundle exec cap production deploy
whenever を capistrano でアップデートする
whenever を使って crontab を動かしているのであれば、それも capistrano でアップデートしてほしい。といっても数行追加するだけで簡単に実現できる。
まずは Capfile に以下を追加。
require 'whenever/capistrano'
次に config/deploy.rb に以下を追加。
set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" }
set :whenever_roles, ->{ :web }
whenever/capistrano は標準では role が db のみを対象としてアップデートを実行するので、web や app など別の role で whenever を実行したい場合は自分で設定しなければならない。
この状態で cap production deploy とかすると whenever もアップデートしてくれる。