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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With