Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker debugging and sub-debugger with random port #107

Open
jcavalieri opened this issue Jul 20, 2017 · 55 comments
Open

Docker debugging and sub-debugger with random port #107

jcavalieri opened this issue Jul 20, 2017 · 55 comments

Comments

@jcavalieri
Copy link

jcavalieri commented Jul 20, 2017

Hi,

I'm trying to debug rails on a docker container using RubyMine. For lack of a better term, I do have an initial successful hand shake. However, the debugger then creates a "sub-debugger" on a different port. This port seems to be random, therefore, I can't pre-configure to have that port shared. Since the IDE doesn't respond to the sub-debugger port being open, then my rails site doesn't start.

root@f79144807c32:/myapp# rdebug-ide -d --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- /usr/local/bundle/bin/rails s -b 0.0.0.0 -p 3000 -e development
Fast Debugger (ruby-debug-ide 0.6.1.beta4, debase 0.2.2.beta9, file filtering is supported) listens on 0.0.0.0:1234
Connected from 10.211.55.2
5: Starting control thread
5: Processing in control: b /myapp/app/api/v1/users.rb:6
5: <breakpointAdded no="1" location="/myapp/app/api/v1/users.rb:6"/>
5: Processing in control: start
5: Starting: running program script
Fast Debugger (ruby-debug-ide 0.6.1.beta4, debase 0.2.2.beta9, file filtering is supported) listens on 0.0.0.0:37922
5: Ide process dispatcher notified about sub-debugger which listens on 37922

Note the port 37922. I'm having trouble finding documentation on the sub-debugger. Do you have any suggestions on how to get around this?

Other info, I'm not using "Docker for Mac" I installed docker tools via brew and and my default docker machine is using the parallels driver.

-John

@jcavalieri
Copy link
Author

jcavalieri commented Jul 20, 2017

Looks like this is a duplicate (or related):
#73

I'm a bit confused how some folks on the web say they got this working (without SSH).

@ivanprado
Copy link

Hi @jcavalieri . Did you found any solution to that? I'm stuck on the same problem.

@jcavalieri
Copy link
Author

Hi @ivanprado,
I haven't. However, rubymine does claim that they support it now. I was about to give that a try.
-John

@tatsucoo
Copy link

I have the same problem.
Is the problem solved? If the problem is solved, I would like to know how to do it.

@jcavalieri
Copy link
Author

I haven't solved it. RubyMine states to have a solution but I couldn't get it to work. I think what RubyMine is doing is adding their own container one's docker environment.

I haven't heard from the maintainers.

@valich, I see you are the most active recently on this repo. Any thoughts on this?

-John

@valich
Copy link
Contributor

valich commented Jan 31, 2018

We'll recheck how the workaround with using docker container as SSH remote interpreter work (have you tried it?). Generally debugging multiprocess stuff in Docker may be cumbersome indeed due to automatic port generation for subprocesses. We are planning to do some refactoring to use single port for the whole debug session, but I doubt we'll make it to 2018.1.

Right now I suppose one should either try to set up SSH connection, or we can make some fork with workarounds for specifying fixed ports.

@valich
Copy link
Contributor

valich commented Jan 31, 2018

OK we discussed and found quite a simple solution of moving to a single-port scheme without much refactoring (at least on IDE side) so we'll try to implement it.

In short, debuggee sets up a proxy to communicate with IDE via multiple connections (opposed to multiple connections from different debuggee processes). Subprocesses will communicate with the proxy with the request to forward the data to the outer client (IDE). The mapping (inner process <-> outer connection) will be also used to deliver responses (commands) back to subprocesses.

@jcavalieri
Copy link
Author

That's great to hear @valich!

@noizex
Copy link

noizex commented Feb 20, 2018

@valich, that sounds great! Any update on this? I used patch for rdebug-ide where I could provide fixed set of ports that were opened for subprocesses, but it really is PITA - it requires opening these ports and adds complexity. Running this in some proxy mode sounds like a good idea - will it work for existing IDEs without requiring any changes? Also any idea when some initial version could be expected? Happy to give it a try.

@valich
Copy link
Contributor

valich commented Feb 22, 2018

@noizex I think it just entered the state "in progress". I think it should be ready to try in a couple of weeks, no earlier.

@aaronblenkush
Copy link

aaronblenkush commented Mar 1, 2018

I was able to get this working over an ssh connection to a remote server (I have not tried this on a Docker container) by doing the following:

  • [Terminal 1]
    • ssh -L 1234:localhost:1234 -R 26162:localhost:26162 $remoteHost
    • rdebug-ide --debug --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- bin/rails s thin
  • [RubyMine]
    • Attach the debugger.
  • [Terminal 1]
    • Take note of the sub-debugger port ($subPort)
  • [Terminal 2]
    • ssh -L $subPort:localhost:$subPort $remoteHost

Note: At first I tried using bundle exec thin start... as the rdebug-ide command, but it seemed to create two subdebuggers, and the thin server never started.

@andrejska
Copy link

@valich any update on this ticket?

@noizex
Copy link

noizex commented Jun 20, 2018

Also very interested in this, could help with some testing if needed, or anything else - just shout :)

@jcavalieri
Copy link
Author

Hi @aaronblenkush ,
We want to avoid having to set up an SSH daemon on every docker container.

Hi @valich, did the proposed solution get any movement?

@sl-victorceron
Copy link

sl-victorceron commented Sep 19, 2018

I'm interested in a solution too. I've the same problem and can't find a solution otherwise using single cluster on Puma configuration.

@mrbiggred
Copy link

mrbiggred commented Dec 9, 2018

To work around this issue I overrode the find_free_port method in the lib/rubyd-debug-ide/multiprocess/pre_child.rb file and opened the port in my Docker container. I like this work around because I don't have to setup SSH in my Docker container.

# initializers/ruby-debug-ide.rb

# In non-dev and rake tasks the Ruby Debug IDE gem
# is not loaded so nothing to override.
if defined?(Debugger::MultiProcess)
  Debugger::MultiProcess.module_eval do
    class << self
      def find_free_port(host)
        server = TCPServer.open(host, 58438)
        port   = server.addr[1]
        server.close
        port
      end
    end
  end
end

In my Docker-Compose file I added the port:

web:
    ports:
      - "58438:58438"
      <Other ports, such as 8080 for Unicorn>

Now the debugger no longer hangs when spawning the second process. It used to hang after the second "Fast Debugger" line but now it works as expected.

Fast Debugger (ruby-debug-ide 0.6.1, ruby-debug-base19x 0.11.30.pre15, file filtering is not supported) listens on 0.0.0.0:1234
web_1       | => Booting Unicorn
web_1       | => Rails 3.2.16 application starting in development on http://0.0.0.0:8080
web_1       | => Call with -d to detach
web_1       | => Ctrl-C to shutdown server
web_1       | listening on addr=0.0.0.0:8080 fd=13
web_1       | worker=0 spawning...
web_1       | master process ready
web_1       | Fast Debugger (ruby-debug-ide 0.6.1, ruby-debug-base19x 0.11.30.pre15, file filtering is not supported) listens on 0.0.0.0:58438
web_1       | worker=0 spawned pid=10
web_1       | worker=0 ready
web_1       | 
web_1       | 
web_1       | Started GET "/" for 172.19.0.1 at 2018-12-09 15:48:36 +0000
                   <Never used to get to the above GET command>

In development I only use one process so I just hard coded the port but you could setup a range if you wanted too.

Details:

I'm supporting an older application that previously used Thin as it's development webserver but Unicorn in production. Part of the application is multi-threaded which would hang the Thin webserver since it's single threaded by default. I decided to use Unicorn in development to be consistent with production and when I did the switch I ran into the above issue when debugging. There was no issues when running the application using Unicorn without debugging (i.e. clicking the green arrow).

Ubuntu 18.04 LTS
RubyMine 2018.3
Ruby 1.9.3
Rails 3.2
Ruby Debug IDE Gem 1.6.1
Ruby Debug Base 19x 0.11.30-pre15
Unicon 4.3.1

Note : The find_free_port method is moved in the 0.7 beta of Ruby Debug IDE to lib/ruby-debug-ide/ruby-debug-ide.rb.

Feedback is welcome,.

Edit (Dec 11/18): Added check that the Debugger::MultiProcess is defined.

@vmassuchetto
Copy link

@mrbiggred how is this supposed to work if the initializers are loaded only when rdebug-ide launches the $COMMAND$ -- therefore, after the dispatcher hangs listening on the random port?

If anyone can help me, this is the ouput for a ruby:2.3-alpine3.7 Docker container:

bash-4.4# bundle exec rdebug-ide --debug --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- bin/rails server
Fast Debugger (ruby-debug-ide 0.6.1, debase 0.2.2, file filtering is supported) listens on 0.0.0.0:1234
Connected from 172.18.0.1
1324: Starting control thread
1324: Processing in control: catch off
1324: Processing in control: start
1324: Starting: running program script
1324: Processing in control: thread listFast Debugger (ruby-debug-ide 0.6.1, debase 0.2.2, file filtering is supported) listens on 0.0.0.0:33141
1324: Ide process dispatcher notified about sub-debugger which listens on 33141

@mrbiggred
Copy link

@vmassuchetto if I understand your question correctly you are asking why does overriding the find_free_port method work. It works because instead instead or returning a random port when spawning a new process a known port is returned. That known port can be opened on the Docker container so the RubyMine, running on your host, can connect and debug the spawned process.

As for your ruby:2.3-alpine3.7 output it appears RubyMine can't connect to port 33141. Did you open that port on your Docker container?

If I misunderstood your questions please let me know. Finally, it is possible my workaround has a bug and/or only works for my particular setup.

@vmassuchetto
Copy link

@mrbiggred Sorry if I was not clear. I'm trying to attach RubyMine to a running rdebug-ide instance. My problem seems to be exactly the same as the OP.

I just copied the find_free_port method. So I would expect the Docker port to be 58438, which continues to be a random port.

As you can see in our output, rails didn't get called, so initializers/ruby-debug-ide.rb can't be loaded at all. What's the correct configuration on RubyMine for this case?

@vmassuchetto
Copy link

Got it working by using a rails launch script without bundler (load Gem.bin_path("railties", "rails") call).

@jcavalieri
Copy link
Author

I think this wouldn't be too difficult to add a new command line option like --open-port-range. I'll give making an PR a try with this. I'm thinking --open-port-range 7000:8000. And this would work with an exposed port range in the dockerfile.

@ViugiNick
Copy link
Collaborator

@jcavalieri @vmassuchetto @mrbiggred There is a prototype of the debugger that uses only one port for all processes. It would be very helpful if you tried it. #164
https://github.com/ViugiNick/ruby-debug-ide/tree/so_reuseport

@jcavalieri
Copy link
Author

Hi @ViugiNick , I like what you are doing in your branch. Have you created an PR for this? I'm wondering what the maintainers would think of your solution.

@jcavalieri
Copy link
Author

Ha! @ViugiNick I see that you are a maintainer! I'll try out your branch and give you feedback.

@mrbiggred
Copy link

@ViugiNick what is the easiest to test your fix? I'm assuming the following updates to my Gemfile would work:

gem 'ruby-debug-ide' git: 'https://github.com/ViugiNick/ruby-debug-ide.git' branch: 'so_reuseport'

Will this replace the existing ruby-debug-ide gem since they will have the same version number? Is it better to manually delete the previous version first? Thank you.

@ViugiNick
Copy link
Collaborator

@mrbiggred Yes, it's better to delete the old one manually

@locofocos
Copy link

@ViugiNick I tested out your prototype. For my situation, it unfortunately isn't working any better. I'm not sure where I would go to offer any further debugging info about why the connection is failing with your prototype.

I've made this change to my gemfile:

  gem 'ruby-debug-ide', git: 'https://github.com/ViugiNick/ruby-debug-ide.git', branch: 'so_reuseport'

which brought in commit 593eef1 of your branch into my gemfile.lock.

My situation:
I'm using Rubymine, trying to open up a remote debugger to a ruby/rails application running inside docker. When I run the ruby/rails application without docker, I'm able to open a debugging connection using this gem just fine. Using docker gives me this error message:

Failed to find free socker port for process dispatcher

I did some snooping in wireshark without using Docker, to see if there was some port being used other than the ports listed in the commands I'm running. I saw 1 or 2 ephemeral ports being used every time (which I haven't explicitly configured anywhere). That led me #73 and then here.

OS - Mac 10.13
Docker - 2.0.0.0-mac81
Ruby - 2.6
Rubymine - 2018.3.5
ruby-debug-ide - 0.6.1
Rails server - passenger 6.0

My docker-compose file looks like this:

  debug:
    command: sh -c 'rm -rf ./tmp && bundle exec rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- bin/rails s -b 0.0.0.0'
    ports:
      - 3000:3000
      - 1234:1234
      - 26162:26162

Thanks for working to fix the issue!

@ViugiNick
Copy link
Collaborator

ViugiNick commented Apr 1, 2019

@locofocos Thanks for the feedback, I'll try to fix it ASAP.

In fact, this prototype still needs two ports (not more)

@howtwizer
Copy link

howtwizer commented Apr 18, 2019

@ViugiNick hm. good question.

app:
    build:
      context: ../../
      dockerfile: devops/dev/Dockerfile
    command: "bundle exec rails s -b 0.0.0.0"
    container_name: test_app
    depends_on:
      - redis
      - db
    env_file: .env
    image: "test_app:dev"
    ports:
      - "3000:3000"
      - "26162-26168"
    stdin_open: true
    tty: true
    volumes:
      - "../../:/usr/src/test_app"
      - "bundle:/usr/local/bundle"

Here is my part of docker-composer.yml I had add "26162-26168" but still have error. May be I'm doing it wrong. Do not have a lot of experience with it.

@peter-grainger
Copy link

@ViugiNick I have a slightly different issue

Exception: undefined method `chomp' for nil:NilClass
/usr/lib/ruby/gems/2.4.0/bundler/gems/ruby-debug-ide-ab971e6097a4/lib/ruby-debug-ide.rb:169:in `block in notify_dispatcher_if_needed'
/usr/lib/ruby/gems/2.4.0/bundler/gems/ruby-debug-ide-ab971e6097a4/lib/ruby-debug-ide.rb:166:in `times'
/usr/lib/ruby/gems/2.4.0/bundler/gems/ruby-debug-ide-ab971e6097a4/lib/ruby-debug-ide.rb:166:in `notify_dispatcher_if_needed'
/usr/lib/ruby/gems/2.4.0/bundler/gems/ruby-debug-ide-ab971e6097a4/lib/ruby-debug-ide.rb:123:in `block in start_control'
Fatal exception in DebugThread loop: undefined method `accept' for 3:Integer

@noizex
Copy link

noizex commented May 28, 2019

@peter-grainger seems like your dispatcher is not running, the error indicates that it failed to open connection to a given

acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port

s.gets.chomp just reads from the socket you open here https://github.com/ViugiNick/ruby-debug-ide/blob/so_reuseport/lib/ruby-debug-ide.rb#L170 and if it's nil it failed to do so.
So make sure your dispatcher is running and listening at provided host & port

@peter-grainger
Copy link

peter-grainger commented May 28, 2019

@noizex I'm running in a docker container and need to attach to IP 0.0.0.0 where would I set that to take effect?

@noizex
Copy link

noizex commented May 28, 2019

I guess putting IDE_PROCESS_DISPATCHER=0.0.0.0:1234 (or whatever is your host/dispatcher port) before the command, but I also think ruby-debug-ide allows passing this as command line arguments too.

@peter-grainger
Copy link

peter-grainger commented May 28, 2019 via email

@nirvdrum
Copy link

nirvdrum commented Oct 8, 2019

@ViugiNick With your branch I can now remote debug specs from RubyMine. Thanks!

@mrbiggred
Copy link

@ViugiNick I tried your branch on a different project and it works.

# Gemfile

gem 'ruby-debug-ide', git: 'https://github.com/ViugiNick/ruby-debug-ide.git', branch: 'so_reuseport'
gem 'debase'

Ubunutu: 18.04 LTS
Docker: 19.03.3
RubyMine: 2019.2
Ruby: 2.3.4
Rails: 4.1.16
Debase: 0.2.4
Passenger: 5.1.4

Haven't had a chance to try it on my other project yet. Thank you and I hope your PR (#164) gets merged soon.

carlobeltrame added a commit to carlobeltrame/hitobito-docker that referenced this issue Dec 3, 2019
As similarly proposed in ruby-debug/ruby-debug-ide#107
This hack is necessary as long as ruby-debug/ruby-debug-ide#164 is not merged and released because:
* We cannot easily modify the Gemfile because it is not in the same repository. So we need to use `gem install` in the Dockerfile to do it
* The newest RubyMine requires a prerelease version of ruby-debug-ide
* The fix with SO_REUSEPORT is only available on a specific branch of a specific fork, which is not up-to-date with the prerelease version
* We cannot use the monkey-patch in an initializer as proposed in the issue, because wagon:test doesn't run Rails and thus doesn't consider the initializers

The combination of these three aspects renders it impossible to easily install a version that includes the fix.
So instead, we simply overwrite the relevant code inside the bundle with something that works for our case for now.
As soon as the PR is merged and released, we can revert to installing the official, unaltered version into our docker container.
carlobeltrame added a commit to carlobeltrame/hitobito-docker that referenced this issue Feb 25, 2020
As similarly proposed in ruby-debug/ruby-debug-ide#107
This hack is necessary as long as ruby-debug/ruby-debug-ide#164 is not merged and released because:
* We cannot easily modify the Gemfile because it is not in the same repository. So we need to use `gem install` in the Dockerfile to do it
* The newest RubyMine requires a prerelease version of ruby-debug-ide
* The fix with SO_REUSEPORT is only available on a specific branch of a specific fork, which is not up-to-date with the prerelease version
* We cannot use the monkey-patch in an initializer as proposed in the issue, because wagon:test doesn't run Rails and thus doesn't consider the initializers

The combination of these three aspects renders it impossible to easily install a version that includes the fix.
So instead, we simply overwrite the relevant code inside the bundle with something that works for our case for now.
As soon as the PR is merged and released, we can revert to installing the official, unaltered version into our docker container.
@mrbiggred
Copy link

mrbiggred commented Oct 8, 2020

I was using @ViugiNick so_reuseport branch it worked most of the time but sometimes would get really slow. Especially once we updated to a newer version of Passenger. Not sure why but I think because it is creating more threads then before. His PR is here.

I've created a new fix that uses a port range instead of a single port like my previous workaround. Currently the ports are hard code but if this fix works I can investigate making the ports configurable.

Please try our my fix and let me know what you think. If the feedback is positive I will create a PR. To try it out first update your Gemfile:

gem 'ruby-debug-ide', git: 'https://github.com/corgibytes/ruby-debug-ide', branch: 'feature-add-fixed-port-range'

Then update your Docker Compose file to allow the port range 58430-58450:

services:
  web:
    <Other setup>

    ports:
      - "3000:3000"
      - "1234:1234"
      - "58430-58450:58430-58450"

Then remove the old Ruby Debug IDE gem and install the new one:

gem uninstall ruby-debug-ide

bundle install

Now when click debug in RubyMine it and shouldn't stop at Subprocess Debugger listens on line. If you want to see what ports the debugger is trying to open enable "Verbose debugger output" in the Settings-->Debugger.

image

image

This fix is from version 7.2 of the Ruby Debug IDE. Feedback would be much appreciated. Thank you.

@cshupp1
Copy link

cshupp1 commented Oct 9, 2020

@mrbiggred
I am trying your solution, this is what I have done:

In my gemfile:

  gem 'debase'
  gem 'ruby-debug-ide', git: 'https://github.com/corgibytes/ruby-debug-ide', branch: 'feature-add-fixed-port-range'

During the bundle install I see it reference your git repo.

In my docker-compose.yml:

    ports:
      - "3000:3000"
      - "26162:26162"
      - "1234:1234"
      - "58430-58450:58430-58450"

I bring my docker containers up via docker-compose up.

I ssh into the container with the puma server and execute:

rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162  -- bin/rails server --binding=0.0.0.0
Fast Debugger (ruby-debug-ide 0.7.2, debase 0.2.4.1, file filtering is supported) listens on 0.0.0.0:1234

The server hangs there forever. I assume it is waiting for a remote debugger to attach? So I try to attach:
image

I still get the dreaded, "Failed to find free socket port...".
I checked the check box, "Verbose debugger output" but see no output in my docker-compose up console or in my "docker exec -it xxx bash" console that I used to launch the rails server.

I will hit ctrl-c to motivate puma to keep coming up.
When puma comes up it does respond to request but still my debugger cannot attach.

Is there any other data from me you need? I am very interested in your solution so willing to help.

Thanks.

@mrbiggred
Copy link

@cshupp1 thank you for trying my fix and your feedback. I've never tried the steps you outlined to run the RubyMine debugger. What I do is:

  1. Make sure my Docker container builds and runs successfully outside of RubyMine:
docker-compose build

docker-compose up web

I should be able to connect to my Docker container via a web browser. If I can't then I need to debug you Docker setup.

  1. Stop my Docker container if it's running. Then in RubyMine Settings-->Languages & Frameworks-->Ruby SDK and Gems and setup a remote debugger. See the screenshots below. You can find the official RubyMine Docker Compose documentation here.

Snag_1423b1e9

Snag_14247ce9

Snag_1425832e

  1. Once that is setup I create a Rails Run/Debug Configuration as shown below, if it does not exist already:

Snag_1425b47f

  1. Then I click the green bug beside the play button. This starts my Docker container with my Rails server (Puma, Unicorn, Passenger, etc) running and I can now set breakpoints in RubyMine.

Snag_14267946

Snag_1429e734

Let me know if the above works for you. If you need to run the ruby-debug-ide via the command line let me know and I can dig into your issue some more. I'm also curious if running the ruby-debug-ide via the command line instead of through the RubyMine IDE is something other people do.

@cshupp1
Copy link

cshupp1 commented Oct 9, 2020

@mrbiggred

Well I just might need to do it my way...
OK I am trying your way...
image
Note how there is no 'rails' gem visible to ruby mine.

But when I docker exec in it is there:
image

But ruby mine sees action cable in the same place:
image

Because of this I get the yucky 'No Rails found in sdk"
image

BTW, I would have never in a million years realized this approach was even possible. Thanks for the detailed instructions. It seems as though there might be a bug in rubymine for inspecting super large docker images.

@mrbiggred
Copy link

@cshupp1 you can try to refresh the gems that RubyMine sees in your Docker file by clicking the down arrow overtop of the gems. Hopefully after clicking the down arrow will see the Rails gems.

Snag_18bfb71d

Also try removing the line that starts the ruby-debug-ide from your docker-compose.sh file. RubyMine will start the debugger for you.

# Remove the below line
rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162 --bin/rails server --binding=0.0.0.0

@cshupp1
Copy link

cshupp1 commented Oct 11, 2020

@mrbiggred
I will start off by saying your approach works!
image

This RubyMine approach is new to me, I was expecting my remote debugger approach as I outlined previously.

To get your approach to work I did a docker-compose down to allow RubyMine to manage it. Then I clicked the checkbox to resynch as you advised. With the image down the scan completed and Rails was found.

I removed the following line:

rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162  -- bin/rails server --binding=0.0.0.0

To allow the debug configuration to manage it as advised. Then I click the debug button and voila!

Of course, with this approach the application bombs out in initialization (it can't find the reddis service).

If I have the rdebug line replaced with:

rails server --binding=0.0.0.0

And docker-compose up myself in the command line everything seems to work.

It would be interesting to know why my original approach fails.

Thanks for your help!

@dhanaraj0
Copy link

dhanaraj0 commented Oct 12, 2020

@mrbiggred
I have tried to use your branch, but still, I'm getting below error message. Not sure if I have made a mistake while configuring. I'm able to run the application and open it in browser. Only when I try to debug it, I see below issue.

dev_1 |
dev_1 | Creating scope :active. Overwriting existing method User.active.
dev_1 | [8] Puma starting in cluster mode...
dev_1 | [8] * Version 4.3.5 (ruby 2.6.3-p62), codename: Mysterious Traveller
dev_1 | [8] * Min threads: 5, max threads: 5
dev_1 | [8] * Environment: development
dev_1 | [8] * Process workers: 1
dev_1 | [8] * Preloading application
dev_1 | [8] * Listening on tcp://0.0.0.0:3000
dev_1 | [8] Use Ctrl-C to stop
dev_1 | 26: Checking if port is free: 58432
dev_1 |
dev_1 | 26: Port 58432 is free.
dev_1 |
dev_1 | 26: connection failed(1)
dev_1 | Exception: Connection refused - connect(2) for "172.18.0.1" port 26168
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in initialize' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in open'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in block in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in times'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:166:in block in _start_control_common'
dev_1 | 26: connection failed(2)
dev_1 | Exception: Connection refused - connect(2) for "172.18.0.1" port 26168
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in initialize' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in open'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in block in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in times'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:166:in block in _start_control_common'
dev_1 | 26: connection failed(3)
dev_1 | Exception: Connection refused - connect(2) for "172.18.0.1" port 26168
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in initialize' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in open'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:221:in block in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in times'
dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:219:in notify_dispatcher_if_needed' dev_1 | /usr/local/bundle/bundler/gems/ruby-debug-ide-e1ed54c9b8a6/lib/ruby-debug-ide.rb:166:in block in _start_control_common'
dev_1 | Fatal exception in DebugThread loop: undefined method `accept' for 3:Integer

My docker-compose file's web service (named dev) looks like this

dev:
build: .
#command: foreman start -m "web=1,worker=1,assets=1" -f Procfile.dev
command: tail -f /dev/null
volumes:
- .:/app:cached
- ./tmp/root:/root/host:cached
ports:
- "3000:3000"
- "1234:1234"
- "58430-58450:58430-58450"
- "26166:26168"
depends_on:
- db
- redis
- mongo-service

My docker dev setup is running on MacBook.

@cshupp1
Copy link

cshupp1 commented Oct 12, 2020

@mrbiggred

The redis problem was on my end. As far as I can tell your solution works flawlessly!
Will you update this issue when your fix is accepted?

Thanks!

@mrbiggred
Copy link

mrbiggred commented Oct 14, 2020

@dhanaraj0 thank you for trying my fix the the feedback. I think you are experiencing the issue #186 (Error Raised when Debugging a Multi-Process app in Docker on a Mac). Based on the error:

Exception: Connection refused - connect(2) for "172.18.0.1" port 26168

Try the fix suggested in the issue and let me know if fixes the Connection refused error. I plan to deal with the Multi-Process Docker on Mac issue after I finish testing this fix.

@dhanaraj0
Copy link

@mrbiggred
Thanks for taking and responding. Since I'm running docker on my Mac, I have applied fix from your branch and #186 to a new branch(dhanaraj0@6a50fd4) and tried it. It is working, I'm able to set break points from RubyMine and debug. I really appreciate the work you are doing.

If anyone is facing issues on Mac, we need to apply the fix for #186 and #107
I have created a branch with these fixes in place, till respective fixes goes to master, you can try to use this branch - https://github.com/dhanaraj0/ruby-debug-ide/tree/debug

@cshupp1
Copy link

cshupp1 commented Nov 17, 2020

@mrbiggred Just want to post that I have your patch working, through docker, with Visual Studio. I want to document it here for everyone. This is the approach I wanted to take earlier with RubyMine (that doesn't work there) as that approach would have been more IDE agnostic.

The pretty picture:
image

From a docker exec console I run:

 rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162  -- /usr/local/bundle/bin/rspec ./modules/vba_documents/spec/jobs/upload_processor_spec.rb

At this point, it just hangs around waiting for my debugger to attach.
Please note, the standard Ruby plugin was installed to VS code.
image

I create a launch.json as follows:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        
        {
            "name": "Listen for rdebug-ide",
            "type": "Ruby",
            "request": "attach",
            "remoteHost": "127.0.0.1",
            "remotePort": "1234",
            "remoteWorkspaceRoot": "/srv/vets-api/src"
        }
    ]
}

By default, the key remoteWorkspaceRoot is generated as:

"remoteWorkspaceRoot": "${workspaceRoot}" 

That doesn't work even though, in my case, "/srv/vets-api/src" is "${workspaceRoot}" 🤷‍♂️

Push play:
image

And in the docker shell we can see the rspec take off, breaks being hit along the way!

@antmonnier
Copy link

This one took me a bit of a struggle too, the solution for me was to prevent ruby-debug-ide from attaching itself to subprocesses:

  • Open the Settings dialog.
  • Navigate to Build, Execution, Deployment, then Debugger.
  • Untick Attach to subprocesses automatically while debugging.

image

@EugeneKovalev
Copy link

EugeneKovalev commented Jan 20, 2022

This is my solution.

In .env set WEB_CONCURRENCY to 0.

or in puma.rb set the number of workers also to 0:
workers ENV.fetch('RAILS_ENV') {'development'} == 'development' ? 0 : (ENV['WEB_CONCURRENCY']||4)

The option provided by @antmonnier is bad since it makes the debugger useless, it does not intercept adding/removal of breakpoints which is a crucial option.

@rgavriel
Copy link

or in puma.rb set the number of workers also to 0

but for some, me included, the only reason to use puma is the need for multi workers.
I've a request going to rails, which calls service X, what in turn call the original rails application.
If I'm running with a single thread, it get to a dead-lock ):

@mrbiggred
Copy link

Just a heads up that I created a fork of ruby-debug-ide that fixes the multiport issue on Docker. Please try it out and let me know if it works for you. If you haven any questions, spot an issue, or have an improvement please let me know by opening a issue or PR in the forked repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.