やりたかったこと
-
Capistrano3
でCapistrano2
までのdeploy_via :copy
なデプロイがしたい(タイトルそのまま) -
Capistrano3
ではdeploy_via :copy
の概念は導入されず
動作確認環境
- クライアント
- Mac OSX 10.9/Windows 7 (32bit)
- Ruby 1.9.3-p484
- リモート
- CentOS 6.4/RedHat EL6.4
依存ライブラリ
Capistrano 3+
rubyzip
手順
インストール
Capistrano
に加えて rubyzip
をインストールして下さい。
Gemfile
group :deployment do
gem 'capistrano', '~> 3.0', require: false
gem 'rubyzip', require: false
end
セットアップ
cap install
すると、以下のような構造になると思います。
config/
deploy/
production.rb
staging.rb
deploy.rb
lib/
capistrano/
tasks/
Capifile
で、 lib/capistrano/copy.rb
を以下の内容で作成。
lib/capistrano/copy.rb
require 'zip'
Zip.setup do |c|
c.unicode_names = true
c.on_exists_proc = true
c.continue_on_exists_proc = true
end
namespace :copy do
task :check do
end
task create_release: 'release.zip' do |t|
file = t.prerequisites.first
on roles(:app) do
execute :mkdir, '-p', fetch(:tmp_dir)
upload! file, fetch(:tmp_dir)
execute :unzip, '-o', "#{fetch(:tmp_dir)}/release.zip", '-d', release_path
end
File.delete file if File.exists?(file)
end
file 'release.zip' do |t|
release_filename = File.join(Dir.pwd, t.name)
Dir.chdir fetch(:copy_dir) do
Zip::File.open(release_filename, Zip::File::CREATE) do |zipfile|
files = FileList['**/*']
files.exclude(*fetch(:copy_exclude)).each do |file|
zipfile.add(file, file)
end
end
end
end
end
つまり、このように配置します。
config/
deploy/
production.rb
staging.rb
deploy.rb
lib/
capistrano/
tasks/
copy.rb << Add to here!
Capifile
さらに Capifile
の先頭に以下のように追記します。
Capifile
$:.unshift File.expand_path(File.dirname(__FILE__) + '/lib') # << 必ず先頭に追加
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
# :
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
以上で準備が完了です。
使い方
deploy.rb
とか deploy/production.rb
とかで以下のように設定すれば OK。
config/deploy.rb
set :scm, 'copy'
set :copy_dir, '.'
set :tmp_dir, '/tmp'
set :copy_exclude, [ /\.log$/, %r!^files/.+! ]
これで cap production deploy
とかすると、
-
Capifile
のあるディレクトリを基準に:copy_dir
で指定したディレクトリ全体から、 -
:copy_exclude
を 除いた ファイル・ディレクトリが<Capifile のあるディレクトリ>/release.zip
としてアーカイブされて、 - リモートの
:tmp_dir
に送信され、 - あとはいつも通り
Capistrano
さんが良きに計らってくださり、
デプロイ完了。
ちなみに、 :copy_dir
と :tmp_dir
は必須です。
既知の問題
-
:copy_exclude
の指定方法がわかりにくい - ファイル名に日本語が使われていると、名前によってはアーカイブで失敗する場合がある
以上です。
gem にしようかと思ってました(思ってます)が、いつになるか分からないので
まとめておくことにしました。参考になれば幸いです。