Quick Access to Your Production Rails Console
Back when I was a dev manager, I used to monotonously do the same sequence of terminal commands ~5 times a day:
ssh into a particular host,
sudo su to a user with correct permissions,
cd to a project, and then open up
rails console or
hbase shell. I did this so many times that it became second nature. My product guy would have a problem and wanting to save my team from the incoming distraction I'd say "Alright, let me look at HBase real quick, we'll figure that out" or "Oh I can fix that user's account, hold on".
Being an engineer, this same repetitive sequence drove me nuts and I quickly got tired of it. I set out to automate as much of the process to get to a production shell prompt as soon as possible and that’s when I came across
expect is a handy tool that allows you to write scripts against interactive text interfaces, which means you can automate a simple workflow like ssh'ing into a host and running commands against it. It fit perfectly and below I'll share with you an abstract version of my production rails console script and another I just developed to get into rails console in a Docker environment.
Traditionally Hosted Scenario
Sharing the code for these scripts will help explain a lot so I’m going to start off with that:
The above is doing what we’ve discussed: ssh’ing into a host, changing to a different user, changing directories, and then opening up a
rails console session. The way this works is that
expect creates a new process (via
spawn) for the ssh session and then issues (
send) commands against that ssh process, 'expecting' (
expect) certain output from those responses. If at any point what it expects doesn't match up after a certain time frame then it'll exit. Otherwise, it proceeds through these steps and we finally get to our
interact command which brings the spawned process to the foreground allowing us to take over the session. Ta-da, we've got a remote
rails console and it takes only a few seconds and considerably less typing!
Docker Hosted Scenario
The reason I got back into thinking about these expect scripts again is due to Docker. I have a Dockerized Rails application that I was putting into production with AWS Elastic Beanstalk and I was updating the README with instructions on how to open rails console in that environment. While writing them I was thinking to myself “Well, this is going to be a PITA”, so I figured I could adapt my old
prod_railsc.sh script to the task. This is what I ended up with:
This does everything very similar to our first script, except we have to fetch the Image ID of the Rails Docker image before we can run the
rails console command against it.
expect allows us to use regular expressions to pull out specific output from our previous command, which we use above in the
expect -re "(.*)\r\n(.*) " line. We then pull out the
image_id variable and use that in our
docker run command. This only works in Single Container nodes, but it could be adapted pretty easily if you're running other services on the same host.
We’ve got ourselves a fast, automated way to access
rails console in both traditionally hosted and Docker hosted rail's environments. If you're interacting with your Rails instance in production to pull important database information, administer data, or even kick off one-time jobs then this script can save you time in the long run!
If you have an improvement or a better way of accessing your production shell then I would love to hear about it in the comments!