akishin999の日記

調べた事などを書いて行きます。

Capistrano でローカルに置いてあるアプリケーションをデプロイ

Rails アプリケーション開発中に、ローカル環境で Passenger + production モードの確認を簡単に出来るようにしたかった事もあり、試しに Capistrano でデプロイできるようにしてみました。

ApacheRuby、Passenger 辺りはインストール・設定済みとします。
また、Rails は 3.2.13 で確認しました。


まずはアプリケーションをデプロイする先のルートディレクトリを作成します。
この下にアプリケーション名のディレクトリが作成されます。

% sudo mkdir /var/apps
% sudo chown -R deployuser:deployuser /var/apps

Bundler、Capistrano をインストールします。

% gem install bundler capistrano capistrano_colors

rbenv を使っている場合は rehash を忘れずに。

% rbenv rehash

取りあえずのローカルデプロイ用という事もあり、Rails アプリケーション内に deploy.rb を作りたくなかったため、Capistrano 用に適当なディレクトリを作成しました。

% mkdir -p ~/deploy/exampleapp
% cd ~/deploy/exampleapp

capify を実行します。

% capify .

生成された Capfile を編集。

% vi Capfile

deploy/assets のコメントアウトを外しておきます。

load 'deploy'
load 'deploy/assets'
load 'config/deploy'

次に config/deploy.rb を編集します。

% vi config/deploy.rb 

Git などの SCM で管理されていない Rails アプリケーションをデプロイするため、以下のように設定しました。

require "bundler/capistrano"

set :application, "ExampleApp"

# for rbenv
set :default_environment, {
  'PATH' => "/home/akishin/.rbenv/shims:/home/akishin/.rbenv/bin:$PATH",
}
set :repository,      "/home/akishin/src/ruby/2.0/rails/exampleapp"
set :deploy_to,       "/var/apps/exampleapp"
set :scm,             :none
set :deploy_via,      :copy
# tar ファイルの生成先とコピー先が同じ(デフォルト)だとアーカイブが壊れるようなので /tmp 以外を指定
set :copy_remote_dir, "/var/apps"
set :copy_exclude,    [ "doc", "log", "tmp" ]

set :normalize_asset_timestamps, false
set :keep_releases, 5

set :use_sudo, false
set :user do Capistrano::CLI.ui.ask('SSH User: ') end
set :password do Capistrano::CLI.password_prompt('SSH Password: ') end

# for Bundler
set :bundle_without, [:development, :test]

role :web, "localhost"
role :app, "localhost"
role :db,  "localhost", :primary => true

namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
  end_
end

ポイントは :scm に :none を指定することと、:copy_remote_dir を明示的に指定している辺り。

deploy.rb を保存したら、 deploy:setup を実行してデプロイ先のディレクトリを作成します。

% cap deploy:setup

デプロイを実行します。
ここでは migration は不要だったので、deploy:cold ではなく deploy にしました。

% cap deploy

しばらく待つと :deploy_to で指定したディレクトリにアプリケーションがデプロイされます。
あとは Apachehttpd.conf に設定した場所に current/public のシンボリックリンクを張れば OK です。

これで production モードでの動作を確かめたい時に気軽にローカル環境で確認する事ができるようになりました。

rails s -e production の方が簡単ですが、その場合 config.serve_static_assets を変更したりしないといけなかったりするので、こっちの方が設定変更などが不要でより本番と同じ環境で確認できる、というメリットはあるかと思います。
まぁ、とはいえ余り使う機会もないかも知れませんが・・・。

ちなみにローカルで git init してある場合は以下のような設定でデプロイできます。

require "bundler/capistrano"

set :application, "ExampleApp"

# for rbenv
set :default_environment, {
  'PATH' => "/home/akishin/.rbenv/shims:/home/akishin/.rbenv/bin:$PATH",
}

# local repository
set :repository,        "/home/akishin/src/ruby/2.0/rails/exampleapp"
set :local_repository,  "/home/akishin/src/ruby/2.0/rails/exampleapp"

set :scm, :git
set :deploy_via, :copy
# tar ファイルの生成先とコピー先が同じ(デフォルト)だとアーカイブが壊れるようなので /tmp 以外を指定
set :copy_remote_dir, "/var/apps"
set :deploy_to,       "/var/apps/exampleapp"

set :use_sudo, false
set :user do Capistrano::CLI.ui.ask('SSH User: ') end
set :password do Capistrano::CLI.password_prompt('SSH Password: ') end

# for Bundler
set :bundle_without, [:development, :test]

role :web, "localhost"
role :app, "localhost"
role :db,  "localhost", :primary => true

namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
  end
end

というわけで、余り必要になる事はないかも知れませんが、ローカルにある Rails アプリケーションを Capistrano を使ってデプロイする方法でした。