Remote Debugging with Foreman and Byebug

Search for a command to run...

No comments yet. Be the first to comment.
Rails 7 ships with a lot of really great improvements to the frontend the biggest of which is removing webpacker in favor of a more generic approach to allow developers to use whatever they'd like to use to compile their assets like esbuild or import...

While working on Paylooza it was really important to me to have a very well tested application. Paylooza strives to be an affordable, off-the-shelf recurring billing solution for individuals and small businesses and because we are dealing with transa...

Hobby projects are great because they can expose you to problems you've never encountered before. While working on Scavenger Hunt Party! I was noticing some issues in the real-world that were not present in my development environment. The biggest o...

I'm subscribed to cassidoo's newsletter and one of the interesting things she always has in there is an Interview question of the week. Usually I don't spend too much time actually solving these but this one looked fun and I thought I had a pretty ...

With Rails 7 recently dropping there are a few improvements outside of the great new features that might take new projects by surprise. The first that I encountered after starting up a new Rails project was the bin/dev script that now uses foreman by default.
The benefit of foreman is you can create a Procfile that defines all the processes your application will need to run. Processes like a web app process and maybe a background worker process and foreman will run them both from a single command, foreman start. Then you can reuse this Procfile in production namely with Heroku that will create processes for all that are listed within that file. The downside is that all those processes are wrapped up in a single tab in your command line and doesn't lend itself well to debugging. This is because it is taking the output from all the processes defined and is simply echoing their output to you. When you debug you need access to the underlying process in order to interact with the debugger. You can get around this by running the web process in a separate tab but that takes away the benefit of foreman. Luckily, byebug has a solution with remote debugging!
Remote debugging with byebug is really simple to set up. Simply create a config/initializers/byebug.rb and start the server.
# config/initializers/byebug.rb
# frozen_string_literal: true
if Rails.env.development?
require 'byebug/core'
begin
Byebug.start_server 'localhost', ENV.fetch('BYEBUG_SERVER_PORT', 8989).to_i
rescue Errno::EADDRINUSE
Rails.logger.debug 'Byebug server already running'
end
end
A few things to highlight:
if Rails.env.development? is to ensure we start the server only in the development environment and not in the test environment. This makes it easier to debug in test because you're running those commands in a single command line process instead of through foreman but in development you're probably running it with foreman.begin rescue block is to allow multiple runs the rails command. I ran into an issue where I had the development server running but wanted to generate a migration using rails g migration. That command runs the initializers and was throwing an error since the byebug server was already up and running on the other process. In that case we just ignore it and output the error to the logs.byebug server can be whatever you want and can be set via the BYEBUG_SERVER_PORT environment variable. I've set the default port to be 8989 but it can be whatever you want that is not in use.Once all that is in place you can open another command line prompt and run byebug -R localhost:8989. Then once your web process hits the byebug command and stops for debugging the new process will have access to it and you can debug to your heart's content.
The default debugger in Rails 7 is now the default Ruby debugger aptly named debugger. There are some docs that say debugger supports remote debugging but I wasn't able to ever get it to work within foreman.
I hope this makes using foreman and debugging in Rails a more comfortable and happy experience!