順番おしえてけろ
そういうのないやで。
ふつうにデプロイする時って bundle exec cap production deploy
とかする。これしてもどの Task が走ってるかはよくわかんない。自前で Task とか足すときに最初から入ってる奴らの順番わからないと腹立たしい。
「このタスク実行するとどういう子タスクが走るんや」っての多分あるんだけど、よくわかんなかったので困った。
bundle exec cap production deploy --trace
こうするとまあなんかそれっぽいものが見える。(このままだと deploy 実行してしまうのでいろいろアレだけど)
ちなみに
に普通のやつは全部書いてある。けど手元の設定でどういうアレになるかは手元の設定ファイルが知ってるので、手元の設定ファイルに聞いたほうが良いと思うんだけど、違うんだろうか。
ちゃんと Deploy flow を把握して、更に中のタスクとか Plugin がどのタスクにフックしてるかとか理解していれば要らないと思う。けどぱっと見れれば便利だし、あればいちいちドキュメントを参照する手間も省けるのに。(実はあるのかもしれないけど、そういうコマンドみたいなものはドキュメントには見当たらなかった。コードは読んでない)
config アップロードしろや
config/database.yml
とか最初ないので、困る。あと shared_dir とかもないけど、これは自動で作ってくれるっぽいんだけど、まあそのへんの話。
deploy:check
というのが最初の方に実行されて、この中にある deploy:check:make_linked_dirs
で linked_files に設定されているファイルを配置するディレクトリが shared に作られる。つまり mkdir される。
namespace :deploy do
task :push_config do
next unless any? :linked_files
on release_roles :all do
fetch(:linked_files).each do |file|
unless test "[ -f #{shared_path.join file} ]"
upload! file, "#{shared_path.join file}"
end
end
end
end
before 'deploy:check:linked_files', 'deploy:push_config'
end
これでアップロードしてくれる。shared_path は Pathname のインスタンス。サーバー上にファイルがある時はアップロードしない(と思う)
最初っていつなの
http://capistranorb.com/documentation/getting-started/flow/ 曰く、deploy という処理の流れ (Flow) の一番最初に deploy:starting
という Task が書いてある。
を見る感じ、deploy:starting
が deploy:check
と deploy:set_previous_revision
を実行している。で、deploy:check
内部で linked_dirs が不在の場合は mkdir が走ってる。 linked_files
が不在のときはエラー出す感じになっている。
deploy:starting
-> deploy:check
-> #{scm}:check
-> deploy:check:linked_dirs
-> deploy:check:make_linked_dirs
-> deploy:check:linked_files
こんな感じ。scm ってのは git とかが入る。上で書いた deploy:push_config
は deploy:check:linked_files
の前に実行するアレにしている。なんでかっていうと、deploy:check:linked_files
が linked_files の存在確認をする Task だから、存在確認される前にアップロードしないと「ないやで」っていわれて死ぬ。
素朴な疑問
deploy
ってのは Task じゃないのか。じゃあなんなのか。コードは読んでない。
環境変数
環境変数は敵である。正直未だによくわかってないし、上手いつきあい方がわからない。sudo すると bundle は消えるし、ruby のバージョンは変わる。まあこの辺の問題はなんとなく解決できるし本題じゃないんだけど。
Capistrano でリモートで実行するコマンドに環境変数を渡す場合、:default_environment を使う。んだけど、これ deploy.rb とか deploy/<stage>.rb とかに書く必要がある。両方リポジトリに乗るじゃん!
なのでこんな風にするのを見つけた。http://qiita.com/katryo/items/eea29e8733947a9bbf5a
ENV.update YAML.load(File.read(File.expand_path('../application.yml', __FILE__)))
set :default_environment, {
"AWS_ACCESS_KEY_ID" => ENV["AWS_ACCESS_KEY_ID"],
"AWS_SECRET_ACCESS_KEY" => ENV["AWS_SECRET_ACCESS_KEY"]
}
おおー、なるほど。ローカルの application.yml を環境変数に突っ込んで実行するわけだ。サーバー上にいろいろ置きたくない時は捗るやつだ。あと多分 figaro 使ってんのかも。
いちいちリスト書くのがめんどいのとローカルに環境変数置いとくほうがセキュリティ的に不安な気がしたので、普通に figaro 入れてサーバーに application.yml 配置しました。
systemd
CentOS 7 使ってるので systemd で Unicorn をいろいろアレしてて、最初は EnvironmentFile= を利用していた。これだと .yml は読めない。で、dotenv 使うか悩んだけど、dotenv って README がめっちゃこう、「俺は開発環境用なんだぜ!」って匂いがしているので production で使わない方がいいのかなと思って figaro にした。根本的には一緒なのかもしれない。
ちなみに unicorn を systemd で起動するのは多分あんまりメジャーじゃない。capistrano 使うなら capistrano-unicorn とか使ったほうが丸いんだと思う。
set :pty, true
namespace :unicorn do
task :stop do
on roles(:web) do
execute :sudo, :systemctl, :stop, :unicorn
end
end
task :restart do
on roles(:web) do
if test "[ -f #{shared_path.join('tmp', 'pids', 'unicorn.pid')} ]"
execute :sudo, :systemctl, :restart, :unicorn
else
invoke 'unicorn:start'
end
end
end
task :start do
on roles(:web) do
execute :sudo, :systemctl, :start, :unicorn
end
end
end
PID ファイルのパスは多分なんか設定を読む感じにした方がいいと思う。あとこの restart で本当に restart できるかといわれるとかなり疑問。この辺は restart の具体的な処理の話で Capistrano あんま関係ないので割愛するけど。
Pty ってなんぞ
http://quanon.hateblo.jp/entry/2012/12/27/163537 に書いてあった。
けど、なんでデフォルトで false なのかよくわからない。調べたけど英語の記事読むの辛かった。みんな true にしてるけど、なぜ false なのかを書いてる人あんまいない気がするし俺もよくわかってない。
ちなみにこの辺に絡むらしい。 http://h3poteto.hatenablog.com/entry/2015/05/23/193119
結論
普通に勉強不足ですね。プロセス周りよくわかってないのヤバイと思う。