#author("2020-04-29T03:30:07+00:00","default:wikiwriter","wikiwriter")
&tag(Capistrano3);
*目次 [#h2c8944f]
#contents
*関連ページ [#p990e6ae]
-[[Capistrano]]
-[[./アップグレード]]
-[[./基本]]
-[[capistrano-git-copy]]
-[[./deploy_via_copyする]]
-[[./Tips]]
-[[./トラブルシューティング]]

*参考情報 [#i3b863a7]
-[[capistrano/CHANGELOG.md at master · capistrano/capistrano:https://github.com/capistrano/capistrano/blob/master/CHANGELOG.md]]
-[[Upgrading from v2.x.x:http://capistranorb.com/documentation/upgrading/]]
-[[capistrano 3.x系を使ってrailsをデプロイ | iii ThreeTreesLight:http://threetreeslight.com/post/68344998681/capistrano-3-x-rails]]
-[[capistrano をバージョン 3 にアップデートして時代の流れに乗る - けんごのお屋敷:http://tkengo.github.io/blog/2013/12/12/version-up-capistrano-v3/]] … v2との違いなど
-[[入門 Capistrano 3 ~ 全ての手作業を生まれる前に消し去りたい | GREE Engineers' Blog:http://labs.gree.jp/blog/2013/12/10084/]] … 丁寧な解説。
-Rails用のデプロイツールとしてminaというものもある。しかし依然としてCapistrano3のほうがメジャーな模様。
*基本的な使用方法[#v40b5c7b]

以下bundle経由で使用する方法を説明する。

**V2からの移行 [#bbc60870]
-互換性がないので作りなおさないといけない。
-GemfileをCapistrano3用に変更し、
-Capfile、config/deploy.rbを削除し、
-以下のインストール移行の手順を実行する。

**設定値の違い [#sdbc9dc6]
-:repositoryが:repo_urlに。
-ssh_optionsの指定方法が。

** インストール [#tebcad30]
-Gemfileを編集し以下を追加。基本は"capistrano"だけだが、railsの処理を行ったり、rbenvの処理を行ったり、bundleを実行したりする場合追加のgemが必要となる。
#pre{{
group :deployment do
  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
end
}}
-gemのインストール
 bundle install --path vendor/bundle

**設定ファイルの作成 [#adc54f37]
-プロジェクトフォルダに移動し、「cap install」を実行
#pre{{
 $ cd myproject
 $ bundle exec cap install
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
Capified
}}
**設定ファイルの編集 [#d28259dc]

***Capfile [#sb5ee752]
-Capfileでは使用するモジュールをrequireする。他のファイルでrequireしてもうまくいかなかったりするの注意。
#pre{{
# Load DSL and Setup Up Stages
require 'capistrano/setup'

# Includes default deployment tasks
require 'capistrano/deploy'

# Includes tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
#   https://github.com/capistrano/rvm
#   https://github.com/capistrano/rbenv
#   https://github.com/capistrano/chruby
#   https://github.com/capistrano/bundler
#   https://github.com/capistrano/rails
#
# require 'capistrano/rvm'
require 'capistrano/rbenv'
# 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/*.rake').each { |r| import r }
}}

***config/deploy/staging.rbの編集 [#m5ee541e]
-いきなり本番サーバーにdeployするのは危険性が高い。テスト用の環境にデプロイするためstaging.rbを準備する。
#pre{{
server 'centos6vm', user: 'tanaka', roles: %w{app db web}, my_property: :my_value

role :app, %w{tanaka@centos6vm}
role :web, %w{tanaka@centos6vm}
role :db,  %w{tanaka@centos6vm}

}}
***config/deploy/production.rbの編集 [#s166c17f]
-production環境に関する設定を行う。role、server、ssh_optionsの設定あたり。



***config/deploy.rbの編集 [#mb74ff23]
-デプロイに関する共通設定を記述する。以下は後述するcopy_to_deployを実行する設定。
-デプロイだけだとデバッグが大変なのでリモートで"ls"を実行する「list」タスクを定義しておくと便利。
#pre{{
set :application, 'demoapp'
set :rbenv_ruby, File.read('.ruby-version').strip
set :scm, :copy
set :tar_roles, :web
set :exclude_dir, ['vendor/bundle']
set :bundle_flags, '--quiet'

task :list  do
  on roles(:web) do
    execute "ls"
  end
end

namespace :deploy do
  namespace :deploy do
    after :restart, :restart_passenger do
      on roles(:web), in: :groups, limit: 3, wait: 10 do
	within release_path do
          execute :touch, 'tmp/restart.txt'
	end
      end
    end
    after :finishing, 'deploy:restart_passenger'
  end
end

}}

** 使用する [#r43bb852]
**listタスクの実行 [#l2ce8f89]
-サーバー上で"ls"を実行するlistタスクを実行してみる
 bundle exec cap staging list

**deployタスクの実行 [#u1750759]
-サーバー上にdeployする
 bundle exec cap staging deploy

**古いリリースの削除 [#i1ccd13e]
-手動で削除する
 bundle exec cap deploy:cleanup -s keep_releases=3
-デプロイ後自動で削除する
-deploy.rbに追加
#pre{{
set :keep_releases, 3
after :finishing, 'deploy:restart_passenger', 'deploy:cleanup'
}}
*Tips [#b1c4e757]

**passengerを再起動したい [#kc27af13]
-apache passengerはtmp/restart.txtを見て再起動してくれる。
-そこで以下のような設定をdeploy.rbに追加しておくといいらしい。
#pre{{
  namespace :deploy do
    after :restart, :restart_passenger do
      on roles(:web), in: :groups, limit: 3, wait: 10 do
	within release_path do
          execute :touch, 'tmp/restart.txt'
	end
      end
    end
    after :finishing, 'deploy:restart_passenger'
  end
end
}}
-passengerは再起動したあとtmp/restart.txtを削除するという説としないという説がある。
-再起動したかどうかログにも書き出されずよくわからない。

**deploy_via:copyしたい(自作gem編) [#a88c0fbe]
TODO:

-capistrano-scm-copyはtarコマンドを使っているのがちょっと嫌。
-できれば自作gemと置き換えたい。構造は単純でcopy.rakeファイルを該当するLOAD_PATHに設置したgemを作るだけでよいっぽい。
-該当するTar/Zip gemを使いtarコマンドを使わないようにする。
-FileListのexcludeを利用する。


**deploy_via:copyしたい(capistrano-scm-copy編) [#u725bdde]
-[[wercker/capistrano-scm-copy:https://github.com/wercker/capistrano-scm-copy]]を使う方法。

***設定 [#fddf8ec0]
-Gemfileに以下を追加する
 gem "capistrano-scm-copy"
-config/deploy.rbの:scmを変更。exclude_dirに指定したディレクトリは無視される。
 set :scm, :copy
 set :exclude_dir, ['vendor/bundle']
-staging.rb、production.rbの変更
-deploy_toでdeploy先ディレクトリを指定する。staging、production環境で異なる場合deploy.rbではなくstaging.rbかproduction.rbで変更しないといけない。
#pre{{
 set :deploy_to, '/home/tanaka/www/demoapp'
}}

-公式ドキュメントによろと、Capfileに以下を追加する必要がある。
 require 'capistrano/copy'
-しかし、[[Appears to try to upload archive file 2x · Issue #17 · wercker/capistrano-scm-copy:https://github.com/wercker/capistrano-scm-copy/issues/17]]によると、処理が2回走ってしまうためrequireしてはならない。
#pre{{
I had the same problem but could find a proper solution; remove require 'capistrano/copy' anywhere!

This problem occurs when we use this module with capistrano/setup because capistrano/setup loads a scm module with the :scm value.
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/setup.rb#L18

Good luck!
}}
**deploy_via:copyしたい(自作編) [#n43b9a84]
-デフォルトではできなくなっているので、[[Capistrano3 で deploy_via :copy する - Qiita:http://qiita.com/hidakatsuya/items/4d097416516afc229199]]を参考にする。
-Gemfileにrubyzipを追加。
#pre{{
group :deployment do
  gem 'capistrano', '~> 3.0', require: false
  gem 'rubyzip', require: false
end
}}
-lib/capistrano/tasks/copy.rakeを作成。上記リンクからちょっとカスタマイズ。
#pre{{
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 :set_current_revision 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
}}
-deploy.rbを編集して完了。
#pre{{
set :scm, 'copy'
set :copy_dir, '.'
set :tmp_dir, '/tmp'
set :copy_exclude, [ /\.log$/, %r!^files/.+! ]
}}
-copy_excludeのパターンは、 Rake::FileListの、excludeで指定できるパターン。[[class Rake::FileList:http://docs.ruby-lang.org/ja/2.0.0/class/Rake=3a=3aFileList.html#I_EXCLUDE]]。パターンとして正規表現、グロブパターン、文字列が使用可能。
-FileList['**/*']はプロジェクトルートからの相対パスを返してくるので、例えば railsプロジェクトの、logs、vendor以下を除外したい場合、以下のように指定するとよさそう。
#pre{{
  set :copy_exclude, [ 
                      /^logs/,
                      /^tmp/,
                      /^vendor/
                     ]
}}
-ドットファイル(.で始まるファイル)がコピーされないけど、それはそれでいいのか?(特にruby-versionとか)。

**staging環境で使用したい [#i1307ad0]
-staging環境にdeployしたい場合、config/deploy/staging.rbを指定するだけではだめで、Rails側でstaging環境を設定しておかないといけない。[[Capistrano3を最後にもう一度だけ懇切丁寧にまとめてみる - そのねこが学ぶとき:http://chroju89.hatenablog.jp/entry/2014/04/12/215628]]
-database.ymlにstaging環境を作成する。
-config/environments/staging.rbを作成。production.rbをコピーして作成。
-Gemfileにgroup:stagingを作成。

**sharedへのリンク [#mc134145]
-deploy.rbでコメントアウトされているlinkd_dirsをコメントアウトする。
 set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/uploads')
*FAQ [#v91a0669]
**ロールってなに? [#p9dcdd23]
-サーバーごとに役割を設定するもの。[[Rails - はじめてのCapistrano - Qiita:http://qiita.com/mosson/items/1a4cfd01cb538f2d8f0e]]の説明がわかりやすいかも。Capistrano3もCapistrano2も考え方に大差はない。
-Capistranoではタスクは、デフォルトでは全ロール、全サーバーに対して実行できる。タスクに対し例えばwebロールを割り当てると、webロールのサーバーに対してしか処理が行われなくなる。

**設定ファイルの、role、serverの意味ってなに? [#j2801aa6]
-cap installで以下のような設定ファイルが作成される。
#pre{{
role :app, %w{deploy@example.com}
role :web, %w{deploy@example.com}
role :db,  %w{deploy@example.com}


# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server definition into the
# server list. The second argument is a, or duck-types, Hash and is
# used to set extended properties on the server.

server 'example.com', user: 'deploy', roles: %w{web app}, my_property: :my_value

}}
-コメントによると、roleは、ロールとサーバーの簡易同時設定。serverはサーバーの詳細設定(既存ロール使用)といったイメージか。

*トラブルシューティング [#h9a9b424]
**デプロイ後にassetsがプリコンパイルされない [#ce91609e]
-Capfileでrequire 'capistrano/rails/assets'が有効になっているかどうか確認する。

**デプロイ後ExecJS and could not find a JavaScript runtimeエラーが発生 [#ta14004a]
-[[ruby on rails 3.1 - ExecJS and could not find a JavaScript runtime - Stack Overflow:http://stackoverflow.com/questions/6282307/execjs-and-could-not-find-a-javascript-runtime]]によると、サーバー環境にNode.jsをインストールする。
#pre{{
sudo apt-get install nodejs
sudo yum install nodejs
}}

**デプロイ後「fatal: Not a git repository (or any of the parent directories): .git」と言われてしまう [#e2931787]
-Gemfileにローカルフォルダで管理しているgemファイルを追加していて、そのgemspecで以下のようにgitを使っているから。
 gem.files         = `git ls-files`.split($\)
-deploy先に.gitフォルダが存在しないためこのような減少が発生する模様。
-ローカルフォルダでgemを管理するのはやめたほうが良いかもしれない。
-もしくはgemspecでgit ls-filesを使わないようにするか。 [[`git ls-files` in gemspec template is bad practice. · Issue #2287 · bundler/bundler:https://github.com/bundler/bundler/issues/2287]]

**「Command: [ -d /var/www/myapp/releases/20140211033611/public/assets ]」のようなわけのわからないエラーが発生 [#ve91d55a]
-[[ruby on rails - Capistrano 3 process failing - Stack Overflow:http://stackoverflow.com/questions/21692601/capistrano-3-process-failing]]によるととりあえず気にしなくても良いのだろうか。


**「Command : [ -L ...]」が exit status 1 (failed).で失敗する [#te9478f2]
-[[ruby - Capistrano 3 deploy failed messages - exit status 1 (failed) - Stack Overflow:http://stackoverflow.com/questions/33128623/capistrano-3-deploy-failed-messages-exit-status-1-failed]]
-致命的エラーならばCapistranoが止まるはずなので気にしなくてよい(のか?)
** Too many authentication failuresが発生 [#af93b281]
-sshをコマンドラインから使うと問題ない。SSHKitの問題?とりあえず以下で一時的に解決できる
 ssh-add -D


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS