How to Use binding.pry to Debug a Rails Application in a Docker Container

Written by vitalie-melnic | Published 2022/02/10
Tech Story Tags: docker | debugging | containers | containerization | rails | docker-containers | tdd | containers-devops | web-monetization

TLDRWhile at Bootcamp, you tend to build your own projects and debugging those is fairly easy. The team I'm currently working on is using a mixture of rails and VueJs for the front-end. I am writing this article as a future reference to myself; hopefully, it will be of some help to anyone who is reading. If you know others please do share, I will add them to the list as well: Debugging in a docker container isn't that straightforward. You need to have the 'pry-rails' gem installed, but you can still use it by running your tests.via the TL;DR App

I am writing this article as a future reference to myself; hopefully, it will be of some help to anyone who is reading. While at Bootcamp, you tend to build your own projects and debugging those is fairly easy. The team I'm currently working on is using Rails as a back-end and a mixture of rails and VueJs for the front-end.

Debugging in a docker container isn't that straightforward. At least it is not in the way my team set everything up. For starters, debugger does not work inside a container. I also had to struggle for the first month because binding.pry usage was not that straightforward to me.

I will describe the methods for debugging I got to use. If you know others please do share, I will add them to the list as well:

TDD with binding.pry

You need to have the 'pry-rails' gem installed. Binding pry won't stop the execution of your code, but you can still use it by running your tests in the container.

TDD is the golden standard and it works great in a Rails container.

It works by placing binding.pry inside your code and running the tests. The tests should stop at the statement in the code. If it doesn't, then you know that the binding.pry method was not reached. I like this method because I am bad at writing tests. I can debug my tests or my code with it.

Raise inspect

TDD is the way to go, but it is practically impossible to cover everything with tests. This is a trick that I love to use when I want to check out something quick. It works by placing a raise method at the desired stopping point. The raise method takes as an argument the object you would like to check and send it the .inspect message.

For exampleraise name_of_your_method_or_variable.inspect. Example below:

Since your code is inside a docker container, nothing will happen in the browser window. The only way to see your error is by going to your browser's Inspect -> Network. Repeat the request that you know will go through the function you placed the raise statement in. Make the request once and see the error displayed in the Preview tab.

Example below:

This is a nifty trick that can save you a lot of time. Suppose you are working on a feature in an application and you have to fill out a lot of required fields. When you press submit, your fields are being emptied. You would have to refill all those fields just to test once. That is a big waste of time. In the Chrome Inspection tool inside the Network tab, you can make a request once. Placing your mouse over the response, right-clicking on it and choosing replayXHR. The browser will repeat the request.

I was often told to read the backtrace, yet no one had explained what it meant. It can be intimidating when you don't know the ins and outs of a Rails application. Reading it is actually very straightforward, from bottom to top. Going through the backtrace you stop at the methods of the file that you modified and looks familiar. Other than the migrations they are usually at the top. You get a lot of valuable information not only the filename name of the method but also the line number.

Debugging with binding.pry_remote

For some reason, binding.pry doesn't stop execution in a container. Our team is using another gem called pry-remote. You would put binding.remote_pry wherever you would normally put binding.pry . Making the request, the app will look like it is being loaded, but nothing will happen. Running pry-remote in the shell of the rails container will then connect to the session. You will be able to interact with pry as you normally would.

Debugging with Rails.logger.info

To be honest, I stumbled on this method while writing this article. I haven't used it in day-to day work. As I understood from the documentation, there is a need for an initial setup which I didn't do. The way I used it is placing Rails.logger.info("--------------------------#{name_of_the_object}----------------------") like in the image below.

I guess you can debug using this method. The only downside for me is that it gets kind of hard to find in the container logs, hence the dashes. See the image below. Perhaps I am using it wrong more research is needed.

Final thoughts

Take this article with a grain of salt. This is my experience working with docker containers. Your set-up may differ from mine and something might not work. I assume every developer has a favourite set of tools and methods that he likes to use. I am interested to know what is yours.


Published by HackerNoon on 2022/02/10