Read more

Capistrano 3: Running a command on all servers

Dominik Schöler
December 21, 2023Software engineer at makandra GmbH

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
Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

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
Posted by Dominik Schöler to makandra dev (2023-12-21 11:55)