문제

I have a Rails app that is running on port 8080 that I need to trick to think it's running on port 80.

I am running Varnish on port 80 and forwarding requests to nginx on port 8080, but when the user tries to login with OmniAuth and the Devise gem generates a url to redirect back to the server, it thinks its on port 8080 which then the user will see.

Is there any way to trick the Rails app to hard code the port as 80 (I would think it's a bad practice), or have nginx forward the request as if it's running on port 80?

Since I am not running a nginx proxy to the Rails app I can't think of a way to trick the port.

Has anyone ran into this issue before, if so what sort of configuration is needed to fix it?

Thanks in advance!

EDIT: Both nginx and Varnish are running on the same server.

도움이 되었습니까?

해결책

I have the same setup with Varnish on port 80 and nginx on port 8080 and OmniAuth (no Devise) was doing exactly the same thing. I tried setting X-Forwarded-Port etc in Varnish and fastcgi_param SERVER_PORT 80; in nginx, both without success. The other piece in my setup is Passenger (which you didn't mention) but if you are indeed using Passenger then you can use:

passenger_set_cgi_param SERVER_PORT 80; 

(The docs say you can set this in an http block but that didn't work for me and I had to add it to the server block.)

http://modrails.com/documentation/Users%20guide%20Nginx.html#passenger_set_cgi_param

다른 팁

Set up X-Forwarded-Port in Varnish. See this example and the other results from a Google search for "varnish x-forwarded-port".

You must also, of course, set up X-Forwarded-For and X-Forwarded-Proto.


The headers X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Port are a way for HTTP reverse proxies such as Nginx, Squid, or Varnish to communicate to the "back-end" HTTP application server, your Rails application running in Thin or Unicorn, who the user actually is and how the user actually connected.

For example, suppose you have Nginx in front of your Rails application. Your Rails application was booted with Thin and is listening on 127.0.0.1:8080, while Nginx is listening on 0.0.0.0:80 for HTTP and 0.0.0.0:443 for HTTPS. Nginx is configured to proxy all connections to the Rails app. Then your Rails app will think that any user's IP address is 127.0.0.1, the port is 8080, and the scheme is http, even if the actual user connected from 1.2.3.4 and requested the page via https on port 443. The solution is to configure Nginx to set the headers:

X-Forwarded-For: 1.2.3.4
X-Forwarded-Scheme: https
X-Forwarded-Port: 443

and the Rails app should use these parameters instead of the default ones.

The same applies for whatever reverse proxy you use, such as Varnish in your case.

You can make a proxy and server it as whatever port you want.

Maybe with apache on top and passenger stand alone...

<VirtualHost *:80>
 ServerName <name>
 DocumentRoot /home/deploy/<name>

 PassengerEnabled off
 ProxyPass / http://127.0.0.1:<port>/
 ProxyPassReverse / http://127.0.0.1:<port>/

</VirtualHost>

In shell:

passenger start -e staging -p 3003 -d

Your problem seems you're getting redirects to port 8080. The best solution would be to configure Rails (or the OmniAuth/Devise gem) to treat the requests as if they were fired on port 80 (but I have no idea how or if it is possible).

Like ablemike said; Apache has a great module for this (mod_proxy), with ProxyPassReverse it rewrites the redirects back to port-80 redirects. Better even, with mod_proxy_html it will replace port-8080 links in HTML pages with port-80 links.

If you only need to rewrite redirects, you can rewrite redirects in Varnish VCL with something like:

sub vcl_fetch {

  ...

  #Rewrite redirect from port 8080 to port 80
  if ( obj.http.Location ~ "^http://[^:]+:8080/.*" ) {
    set obj.http.Location = regsub(obj.http.Location, ""^(http://[^:]+):8080(/.*)","\1\2");
  }
}

(I think you have to replace obj with beresp if you use varnish >= 2.1)

If you have to rewrite HTML pages, this will be a lot harder to do completely correct with varnish.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top