Debugging a Rails application that is running in a docker container
Vitalie Melnic
Software Engineer at Wordminds, Ruby, Ruby on Rails, JavaScript, VueJs, SCSS
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 example `raise 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 in the file that you modified and look familiar. Other than migrations, they are usually at the top. You get a lot of valuable information, not only the filename, the 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 by 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 favorite set of tools and methods that he likes to use. I am interested to know what is yours.