Last Updated: February 25, 2016
·
491
· wireframe

Using pry-remote to debug within Vagrant VM

Originally posted on codecrate.com

Vagrant is awesome and an absolutely essential
part of every development environment. Running your application within a
vagrant virtual machine does introduce a few challenges though...

One particularly nasty issue I hit recently was trying to debug some code using
my favorite Ruby debugging tool, Pry.

The issue was that my application was launched within the VM using a linux process
manager (Ubuntu upstart) which means that the process is forked into the
background and it is not possible to halt the process to start a debugging
session using the standard binding.pry call.

Pry-remote to the rescue!

Debugging background processes requires using the
pry-remote gem which
was designed for this exact usecase. All you need to do is
swap out the method calls from binding.pry to binding.remote_pry and when
your application server hits the debugger, connect to the background process using the
pry-remote command. Voila!

Connecting from the host OS

Now, debugging the background application process is awesome, but there is one
gotcha with this setup...it only works from within the guest virtual
machine
. That's pretty annoying for me since I like to use my host OS for terminal
commands and tools.

Vagrant supports port-forwarding from the host OS to the guest, but that
doesn't work in this case since the pry-remote gem is opening up a random port
each time the debugger is triggered.

To workaround this issue, I use this simple shell script that automates
connecting to the virtual machine and firing up pry-remote.

#!/bin/bash

# connect to application within virtual machine to debug running process
# binding.remote_pry should be used to trigger breakpoints
vagrant ssh -c 'cd /vagrant && bundle exec pry-remote'

This solution combines the awesomeness of debugging applications with pry with
the convenience of not needing to manually ssh into the virtual machine all the
time!