環境
- Ruby 3.1.2
- capistrano 3.17.1
標準エラーをリダイレクトする
おそらくこれが一番簡単です
-
bundle exec cap production console 2>/dev/null
--suppress-backtrace というオプションがあるが使い方がよくわからない、、
おそらくこれが一番簡単です
--suppress-backtrace というオプションがあるが使い方がよくわからない、、
config/deploy/production.rb などにホストやロールの情報を記載します
インスタンスの情報が毎回変わる場合などは書き換えるのが面倒なのでどこかしらからホスト情報を取得して動的にロールを設定したくなります
今回はそのポイントを紹介します
通常ロールは role メソッドを使って指定します
その際に Array で IP アドレスを複数していします
結論から言うとこの前段で何かしらの方法で取得した IP アドレスの情報を配列の変数にして設定すれば OK です
role :local_mac, %w{192.168.100.1}, my_property: :hello
↓
require './lib/fetch.rb'
f = Fetch.new
targets = f.ip_addresses
role :local_mac, targets, my_property: :hello
fetch.rb は例です
この中で例えば外部サーバに問い合わせてホストの情報を取得したりファイルから読み込んでホストの情報を取得したりすれば OK です
タスク内で対象のIPアドレス一覧を取得してそれらに対してループして exec することもできますがそれだと cap console などが使えないのであまりオススメしません
タスク側でも role メソッドをコールできるのでそうすることもできるのですが role は config/deploy 配下のファイルで実施したほうが良いです
執筆時点では最新の Capistrano3.14 を試してみました
タスクの作成方法から実行までの簡単な流れをまとめています
bundle initvim Gemfilegem "capistrano"
bundle config path vendorbundle installまずは capistrano が動作する環境を作成します
bundle exec cap installmkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified
必要最低限の config ファイルや Capfile と呼ばれる capistrano の管理ファイルが作成されます
またステージ (環境) は STAGES 変数にセットすると必要なファイルを自動で作成してくれます
bundle exec cap install STAGES=local,sandbox,qa,productionとして実行すると config/deploy/local.rb や sandbox.rb, qa.rb なども作成してくれます
なおこの時点で自動である程度のタスクを作成してくれているので
bundle exec cap -Tと実行すると実行可能なタスクの一覧が表示されます
例えば doctor:environment タスクを実行すると capistrano の実行環境が確認できます
bundle exec cap production doctor:environment今回はロールベースでデプロイ対象のサーバを定義します
vim config/deploy/production.rbrole :local_mac, %w{192.168.100.1}, my_property: :hello
とりあえず実行しているローカルの Mac をデプロイ対象のサーバにしています
「ロール名」「対象のサーバ」「プロパティ」という順番で定義します
他にも server という単位でデプロイ対象のサーバを定義できますが基本は 1 台ずつしか定義できないのでロールベースのほうがよく使うかなと思います
ではタスクを定義してみます
タスクは rake ファイル形式で記述する必要があるので .rake で作成します
とりあえず今回はテストなので role で定義したプロパティの値と実行中のホスト名でも表示してみたいと思います
vim lib/capistrano/tasks/test_tasks.rakenamespace :test do
desc 'Show the hostname'
task :echo do
on roles(:local_mac) do |host|
info "Host => #{host.hostname}"
info "Properties => #{host.properties.fetch(:my_property)}"
end
end
end
この時点でタスクは capistrano に登録されているので cap -T で確認するとタスクの一覧に表示されるのが確認できると思います
bundle exec cap -T | grep echocap test:echo # Show the hostname
ちなみに roles + on でロールに含まれているサーバ分ループすることができます
引数の host は Capistrano::Configuration::Server クラスのオブジェクトで SSHKit::Host というクラスを継承しているため .username や .password などで属性の参照ができます
実は上記のタスクは単純に config/deploy/production.rb で定義した値を参照しているだけなので実際に ssh はしていません
本来は対象のサーバに ssh してコマンドを実行します
その場合は (execute)[https://github.com/capistrano/sshkit#the-command-map] というリソースを使います
新たに execute するタスクを追加してみます
vim lib/capistrano/tasks/test_tasks.rakenamespace :test do
desc 'Show the hostname'
task :echo do
on roles(:local_mac) do |host|
info "Host => #{host.hostname}"
info "Properties => #{host.properties.fetch(:my_property)}"
end
end
desc 'Show macOS version'
task :vers do
on roles(:local_mac) do |host|
execute :sw_vers
end
end
end
これで試しに test:vers タスクを実行してみると ssh できないというエラーになると思います
bundle exec cap production test:vers「Errno::ECONNREFUSED: Connection refused - connect(2) for 192.168.100.1:22」
これは単純に実行しているローカルの Mac で sshd が有効になっていないだけです
ちゃんと sshd を有効にしてあげれば成功するのでこちらを参考に mac の sshd を有効にして再度動作確認してみましょう
便利なので紹介しておきます
'capistrano/console' という gem を使うことで実現できます
簡単に言うと任意のコマンドを role や server で定義したサーバに一括で ssh 経由で実行することができます
Capfile に一行追加しましょう
vim Capfilerequire "capistrano/console"
そして cap production console とするとインタラクティブモードになり今回 role で指定したローカルの Mac に ssh してコマンドを実行することができます
bundle exec cap production consolecapistrano console - enter command to execute on production
production> hostname
00:00 console
01 hostname
username@192.168.100.1's password:
01 mac01
✔ 01 192.168.100.1 6.271s
これが嬉しいのは例えば role に 100 台のサーバを登録したら 100 台のサーバに対して一斉に同じコマンドを実行したりすることができるようになります
ちなみに有効にするとちゃんと cap -T のタスクの一覧にも表示されます
最新版の Capistrano3.14 に触ってみました
基本はタスクを追加するだけなので表示に簡単にタスクはかけるかなと思います
バージョン管理の機能があるので切り戻しも簡単にできるかなと思います
ただ冪等性はなく基本は execute でコマンドをリモートで実行していくだけなので chef や ansible のような便利なリソースはないのでゴリゴリ自分でデプロイコードを書いていく必要はあります
一応 capistrano はプラグインの機能があるので Capistrano::Dockerbuild
のようにプラグインとして作成してリソースとして使用することはできるかなと思います