Posted almost 6 years ago. Visible to the public. Repeats. Linked content.

How to use the Capistrano 2 shell to execute commands on servers

Capistrano 2 brings the shell command which allows you to run commands on your deployment targets.
There is also invoke to run a command directly from your terminal.

Both commands allow running Capistrano tasks or shell commands, and scope to individual machines or machine roles.

Unfortunately Capistrano 3 does not include these commands any more.

cap shell

Basics

First of all, spawn a Capistrano shell (we're using the multistage extension here):

Copy
$ cap staging shell

In your "cap" shell you can now run Capistrano tasks by prepending an exclamation mark. For example:

Copy
cap> !deploy:revision ** [out :: web1.example.com] 9aeed9030db6a7b5b4ba077337545677b4fd5c22 ** [out :: web2.example.com] 9aeed9030db6a7b5b4ba077337545677b4fd5c22 ** [out :: queue.example.com] 9aeed9030db6a7b5b4ba077337545677b4fd5c22

(deploy:revision is a custom task to check the deployed revision)

To run shell commands on each machine, simply put them there as if you were on a regular terminal session:

Copy
cap> uname -o ** [out :: web1.example.com] GNU/Linux ** [out :: web2.example.com] GNU/Linux ** [out :: queue.example.com] GNU/Linux

Running more than one shell command

Be aware that shell commands will be sent once, and that your shell on the remote machine is not persistent:

Copy
cap> cd /tmp cap> pwd ** [out :: web1.example.com] /home/deploy ** [out :: web2.example.com] /home/deploy ** [out :: queue.example.com] /home/deploy

Instead, queue them:

Copy
cap> cd /tmp && pwd ** [out :: web1.example.com] /tmp ** [out :: web2.example.com] /tmp ** [out :: queue.example.com] /tmp

Running commands only on individual machines

You may have some commands that you want to run only on a subset of machines, e.g. machines running queue workers.

To pick machines by name, use the on keyword:

Copy
cap> on web1.example.com uname -o ** [out :: web1.example.com] GNU/Linux

Join multiple machine names with commas (e.g. web1.example.com,web2.example.com).

The above is a bit impractical (you could just SSH to a single machine), but you can also scope to entire role groups using the with keyword:

Copy
cap> with web uname -o ** [out :: web1.example.com] GNU/Linux ** [out :: web2.example.com] GNU/Linux
Copy
cap> with queue uname -o ** [out :: queue.example.com] GNU/Linux

For more information, see the linked page.

cap invoke

To run shell commands on all servers, you can also use Capistrano's invoke. Its syntax is a bit more complicated:

Copy
$ cap staging invoke COMMAND='uname -o' ** [out :: web1.example.com] GNU/Linux ** [out :: web2.example.com] GNU/Linux ** [out :: queue.example.com] GNU/Linux

Note the COMMAND environment variable which must hold the command(s) you want to run.
As mentioned above, if you want to run multiple commands, you need to chain them:

Copy
$ cap staging invoke COMMAND='cd /tmp && pwd' ** [out :: web1.example.com] /tmp ** [out :: web2.example.com] /tmp ** [out :: queue.example.com] /tmp

Note that you probably should not use these commands for complex shell operations.
Instead, maybe create a file that does things for you and run that one instead. Or try an application like Terminator that allows sending the same keystrokes to multiple machines.

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Arne Hartherz
Last edit:
about 1 month ago
by Judith Roth
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more