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):
$ cap staging shell
In your "cap" shell you can now run Capistrano tasks by prepending an exclamation mark. For example:
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:
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:
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:
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:
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:
cap> with web uname -o
** [out :: web1.example.com] GNU/Linux
** [out :: web2.example.com] GNU/Linux
^
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:
$ 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:
$ 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
Show archive.org snapshot
that allows sending the same keystrokes to multiple machines.