Executing SSH scripts on multiple servers

Since this article I have bought a special domain for it: serverchief.io

I manage a bunch of server, each week I have to SSH in each and every one of them to update packages, check their disk usage and do a bunch of maintenance stuff. This is a lot of work 🙁

So I thought, hey! This can be much easier if I had a tool that would SSH in for me and execute the commands for me and report the output back so I only have to login to servers that have errors and I can easily scan through the output (and look back at earlier executions to see if something has changed).

As it turns out there are a few tools out there (the best I found Commando.io) but they are all to bulky, too expensive or just not how I wanted it to work.

The one thing led to another and I installed me a fresh Laravel instance and started working on said tool.


I started with server management, I needed to add all my servers and the app should be able to logon to the server. I wanted it to be transparant to the user so I decided to generate a public/private key pair for each server to use as credentials so that I did not need to store passwords and users can easilly revoke access without removing the server from the dashboard.

Commando server dashboard

This was all very straight forward, I pulled in the phpseclib package to generate a RSA public/private key pair and saved them with a server name, host, user and location to the database (the private key is stored encrypted).


Then on to the next section, I needed to be able to define scripts, so I could easily start them without typing them each time… makes sense, right 🙂

Commando script editor

For the script editor I used the CodeMirror editor with the shell syntax highlighting.


Now comes the really interesting (and cool) part of the app. The script execution!

Commando queuing execution

When you queue an execution you can select the script and on which servers the script should be executed, there is no limit on how many servers at once you can execute, if the app is too busy with other requests the execution simply waits on the queue as the interface will indicate.

Commando job waiting

When the app starts running the script the interface updates in realtime, showing the server output and the start time, as wel as the execution time when finished and if the script finished successfully or with errors).

Commando successfull execution

Each execution has it’s own job on the queue so if one server fails the rest continues on just fine untill they are all done. The interface is updates realtime using Slanger a open source server implementation of Pusher.

Cool, now what?

Well I’m not done yet, I would like to create server groups (implemented as tags) so I don’t have to manually select which of the many servers the script needs to run. I also would like to have some sort of subscription/registration (this is implemented now) so others can use this app too without me making accounts manually.

So, no, there is no registration, yet go here. If you are very eager to try (on your own risk ;)) you can register now, please do let me know how it works for you!