I'd like to use VScode as an integrated debugger with Ruby on Rails. There seem to be pretty good guides on how to do this, whether launching the process in VScode or attaching to a running debug server.
However, I cannot find good guides on how to do this when running unicorn. Consider this typical command to start the debug server:
rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 1234 -- ./bin/rails s
It's expecting bin/rails s
to start the rails server. This is the command we currently use to start unicorn:
bundle exec unicorn_rails -E "develop_against_staging" -p 3010 -c "${PWD}/config/unicorn.rb"
Is there a way to start unicorn from within rails? Or is there another way to tell rdebug-ide
what to do? I can't even find good documentation for rdebug-ide
. I'll keep fiddling and answer this myself if I figure something out.
First you need to install Ruby extension
Add following gems in your Gemfile:
gem 'debase'
gem 'ruby-debug-base', :platforms => [:jruby, :ruby_18, :mingw_18]
gem 'ruby-debug-base19x', '>= 0.11.30.pre4', :platforms => [:ruby_19, :mingw_19]
gem 'ruby-debug-ide' , "~>0.6.1"
Then you need to let rdebug-ide know you are using unicorn (multi-process app) by providing the --dispatcher-port
option. Please take a look at rdebug-ide file to see all the available options.
--dispatcher-port: It is a same port that you will use to run unicorn. In your case 3010
.
So it should look like this:
bundle exec rdebug-ide --debug --port 1234 --dispatcher-port 3010 -- vendor/bundle/ruby/2.6.0/bin/unicorn -E "develop_against_staging" -p 3010 -c "${PWD}/config/unicorn.rb
Running above command alone wont start the debugging, infact your Unicorn server wont be starting yet. When looking at the logs after running the above command in the terminal window you will notice a message something like this
Fast Debugger (ruby-debug-ide 0.6.1, debase 0.2.4.1, file filtering is supported) listens on 127.0.0.1:1234
The logs telling us rdebug-ide is ready to be connected at port 1234. Create a launch.json file if it is not already created and add this configuration.
{
"version": "0.2.0",
"configurations": [
{
"name": "1234 Listen for rdebug-ide",
"type": "Ruby",
"request": "attach",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"remoteWorkspaceRoot": "${workspaceRoot}",
"cwd": "${workspaceRoot}"
}
]
}
Once you add the entry, go ahead and click on Play
Image here button to start debugging.
Now that your unicorn server is started, if you try to access your application you wont be able to access it because the worker process haven't started yet.
Continue to look at logs carefully you will notice
122: Ide process dispatcher notified about sub-debugger which listens on 34865
. This is telling us a new sub-debugging process is started on port 34865
. This is a randomly generated port find_free_port.
Note: There will a one port per unicorn-worker.
Once you see the above log add another entry into your launch.json file and copy the newly generated port into the file. Like this
{
"version": "0.2.0",
"configurations": [
{
"name": "1234 Listen for rdebug-ide",
"type": "Ruby",
"request": "attach",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"remoteWorkspaceRoot": "${workspaceRoot}",
"cwd": "${workspaceRoot}"
},
{
"name": "34865 Listen for sub-rdebug-ide",
"type": "Ruby",
"request": "attach",
"remoteHost": "127.0.0.1",
"remotePort": "34865",
"remoteWorkspaceRoot": "${workspaceRoot}",
"cwd": "${workspaceRoot}"
}
]
}
Once added, select the new configuration and click play button. If you had set number of worker to one only in your unicorn.config file, you should see the the log something like this.
I, [2022-07-13T19:44:26.914412 #122] INFO -- : worker=0 ready
. Now put a breakpoint and start using your application, it will break once it reach that code path.
If you have successfully setup everything and got to this point, there will be some gotcha that you may need to deal with.
This complexity is because of unicorn master-worker design.
Answering this in a bit rush, please let me know if you have any questions. I apologies if I made this more confusion for you.