Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Puma only binding to tcp6? (via `rails s`)

Brand new generated Rails 4.2.0 project. Ran rails s, behaved as expected using WEBrick:

vagrant@web1:~$ netstat -nlpt
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      27158/ruby2.1   
tcp6       0      0 ::1:3000                :::*                    LISTEN      27158/ruby2.1   

Added puma to Gemfile, ran bundle, then rails s again; came up with Puma, but only bound tcp6 interface, not tcp:

vagrant@web1:~$ netstat -nlpt
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 ::1:3000                :::*                    LISTEN      27116/ruby2.1   

Any clue why? I've been googling with no luck.

UPDATE:

Running puma -b tcp://0.0.0.0:3000 works. However, adding the bind directive to config/puma.rb and running rails s doesn't:

bind 'tcp://0.0.0.0:3000'

The threads/workers directives in my config file are working, however, so I know the config file is getting loaded and used. (Even added a puts statement to be sure.)

The config file even gets picked up if I just run puma, binding to the correct interface. I may just have to resort to running puma instead of rails s, even though it's annoying and has to be added to my developer docs.

UPDATE2:

I was mistaken. Running rails s does not pick up config/puma.rb automatically. Still investigating...

like image 997
odigity Avatar asked Jan 04 '15 17:01

odigity


2 Answers

The problem you see is that Puma by default binds to localhost. This was treated as a normal hostname by the underlying Rails TcpServer and there resolved to only one IP address (the IPv6 version in your case) but not to both the IPv4 and IPv6 versions.

This issue has been dealt with in Puma issue #782 and solved on July 18, 2016 with this patch. In current versions, an exception is made specifically for localhost, which now binds to both the IPv4 and IPv6 resolutions.

For all other domains, Puma will still bind to the first IP address returned by the system's name resolution. In these cases, you can at least choose if you want Puma to bind to the IPv4 or IPv6 resolution by adding an appropriate entry to /etc/hosts.

like image 119
tanius Avatar answered Nov 01 '22 10:11

tanius


Running rails like:

rails s -b 0.0.0.0

works for me. The problem is that "localhost" (the default bind address) bind on IPv4 and IPv6 and the v6 is chosen if both are available. 0.0.0.0 force the use an IPv4 address (also work with 127.0.0.1).

like image 20
Fabien Sa Avatar answered Nov 01 '22 11:11

Fabien Sa