Capistrano 3: Running a command on all servers

Updated . Posted . Visible to the public.

This Capistrano task runs a command on all servers.

bundle exec cap production app:run cmd='zgrep -P "..." RAILS_ROOT/log/production.log'

Code

# lib/capistrano/tasks/app.rake

namespace :app do

  # Use e.g. to grep logs on all servers:
  #   b cap production app:run_cmd cmd='zgrep -P "..." RAILS_ROOT/log/production.log' 
  #
  # * Use RAILS_ROOT as a placeholder for the remote Rails root directory.
  # * Append ` || test $? =1;` to grep calls in order to avoid exit code 1 (= "nothing found")
  # * To be able to process the output with a pipe, prepend `yes | ` to confirm the prompt
  desc 'Run a command on all servers'
  task :run do
    cmd = ENV['cmd'].to_s
    raise 'Please specify the command with CMD=…' if cmd == ''

    cmd = cmd.gsub /RAILS_ROOT/, shared_path.to_s
    puts '> RAILS_ROOT in your command has been replaced with the remote Rails root directory.'

    puts "Prepared command: #{cmd}"
    print '> Run this on all servers? [n] '
    if $stdin.gets =~ /y/
      on roles :app do
        execute cmd
      end
    else
      puts 'x Canceled.'
    end
  end

Make sure you require custom Capistrano task files:

# Capfile

Dir.glob('lib/capistrano/tasks/*.rake').each do |r|
  # `import r` calls Rake.application.add_import(r), which imports the file only
  # *after* this file has been processed, so the imported tasks would not be
  # available to the hooks below.
  Rake.load_rakefile r
end
Profile picture of Dominik Schöler
Dominik Schöler
Last edit
Dominik Schöler
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2023-12-21 10:55)