passenger icon indicating copy to clipboard operation
passenger copied to clipboard

PassengerPreStart / prespawn fails for apps not reachable via 127.0.0.1

Open FooBarWidget opened this issue 11 years ago • 10 comments

From svnmnt on September 15, 2013 15:02:16

What steps will reproduce the problem?

  1. configure virtual host example.com which is only reachable on public IP and not on 127.0.0.1
  2. add "PassengerPreStart http(s?)://example.com"
  3. restart apache
  4. rails app is not prestarted

alternative way:

  1. from above
  2. run "ruby prespawn http://example.com " from the command line

What is the expected output? What do you see instead?

I expect, that the app would have been prestarted. I see a "Connection refused" error. Details are given below.

What version of Phusion Passenger are you using? Which version of Rails? On what operating system?

Passenger Version: 4.0.17 Rails: 4.0.0 OS: FreeBSD 8.2 Please provide any additional information below. The httpd-error.log shows:

[...]/gems/passenger-4.0.17/helper-scripts/prespawn:105:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:105:in `new'
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:105:in `connect'
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:112:in `connect'
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:86:in `socket'
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:90:in `head_request'
        from [...]/gems/passenger-4.0.17/helper-scripts/prespawn:145:in `<main>'

The problem is that the connection is made to host '127.0.0.1' which is hard coded in the prespawn script. I've attached a patch which uses request_host instead of 127.0.0.1 for the connection.

Attachment: prespawn_fix.diff

Original issue: http://code.google.com/p/phusion-passenger/issues/detail?id=949

FooBarWidget avatar May 29 '14 09:05 FooBarWidget

From honglilai on September 16, 2013 04:38:42

This fix is not the proper way to do it. If the host name in request_host points to a load balancer, or a DNS entry with multiple IP addresses, or generally not the local host, then it won't work properly.

A better way would be for Passenger to parse the web server config file and to truly pre-start processes instead of using the current make-an-internal-request-to-the-web-server route.

For now, you can solve this problem locally by sending a request to the correct IP address manually.

FooBarWidget avatar May 29 '14 09:05 FooBarWidget

This just appeared in my Nginx+Passenger Redmine application. I don't listen to 127.0.0.1 and configure nginx via Passenger or rather via Passengerfile.json. I can only set "address" to a single address. Any pointers how I can avoid this error? Add something to nginx.conf? Anywhere else?

danowar2k avatar Nov 15 '16 15:11 danowar2k

You can track the progress on this issue at: https://github.com/phusion/passenger/tree/prespawn_non_localhost

CamJN avatar Nov 28 '16 18:11 CamJN

Hello,

The "progress article" is no longer valid it seems.

Was this ever fixed? We're suffering from this too and don't see why this limitation is imposed :(

Something to override the behavior at least would be terrific!

HOSTED-POWER avatar May 11 '18 10:05 HOSTED-POWER

It's not fixed yet, unfortunately. The limitation is due to us not knowing to which ip passenger is bound to in apache and nginx integration modes.

CamJN avatar May 31 '18 16:05 CamJN

Why not simply have an option to resolve the hostname? :)

HOSTED-POWER avatar May 31 '18 16:05 HOSTED-POWER

We don't do that because the dns resolution for a hostname might point to a load balancer not the server passenger is installed on.

CamJN avatar May 31 '18 16:05 CamJN

Thanks for feedback, but it could at least be provided as an option, it would help us so much :)

HOSTED-POWER avatar May 31 '18 16:05 HOSTED-POWER

Why not an option to specify the IP address explicitly to be used in establishing the connection?

jgosmann avatar Jan 10 '21 16:01 jgosmann

Modified prespawn script to try to connect to @uri.host if 127.0.0.1 and ::1 both failed, works for me nicely. If this is bad for some reason would it help to introduce support for another uri scheme - ie http_ip://192.168.1.2/ - which would basically say 'ok, i know what i'm doing, let me' and provide me with the option I need (potentially checking that this is indeed ip interface on this machine)?

Current prespawn script i'm using:

class TCPPrespawnLocation < PrespawnLocation
  def request_port
    @uri.port
  end

  def connect
    TCPSocket.new('127.0.0.1', request_port)
  rescue Errno::ECONNREFUSED
    begin
      TCPSocket.new('::1', request_port)
    rescue Errno::ECONNREFUSED
      TCPSocket.new(@uri.host, request_port)
    end
  end
end

then in my prestart I put IP on which nginx is listening on:

passenger_pre_start http://<ip>/;

mzagar avatar Nov 23 '21 21:11 mzagar