3
votes

I'm attempting to implement a Catalyst application using nginx as a frontend web proxy for static files, and using Starman for my backend webserver. (I could use Apache & FastCGI and it works just fine, but I'd really like to get the whole PSGI / Plack and Starman thing ironed out)

Starman starts up okay and can handle my requests just fine on http://localhost:5000. When I fire up nginx to use as my front-end proxy, my urls become ugly and mangle with the port number (5000) whenever or wherever I use the $c->uri_for method.

Example :

$c->uri_for("/login")
becomes
http://myapp.example.com:5000/login 
rather than
http://myapp.example.com/login 

I have some logs being created so I can see what X-Forwarded-Host and X-Forwarded-For are set as. For normal requests, there are values set (coming from nginx), but whenever the $c->uri_for method is used, those values do not exist.

Has anyone else had this problem?
Am I missing something else in my configuration of either nginx or my Catalyst conf?

Thanks!

nginx config :

server {
        listen        80;
        server_name   myapp.example.com;

        location /static {
            root /data/users/MyApp/root;
            expires 30d;
        }

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_pass http://localhost:5000/;
        }
    }

Event though this will be ran on the same physical server, in MyApp config I have set :

MyApp->config(using_frontend_proxy => 1)

Versions :

Catalyst : 5.80024
nginx : 0.7.67
Plack : 0.9942
Starman : 0.2006
2

2 Answers

4
votes

My problem was in my myapp.psgi file.

from Catalyst::Engine::PSGI and look at Plack::Middleware::ReverseProxy:

...
use Plack::Builder;
use MyApp;

MyApp->setup_engine('PSGI');
my $app = sub { MyApp->run(@_) };

builder {
 enable_if { $_[0]->{REMOTE_ADDR} eq '127.0.0.1' } 
        "Plack::Middleware::ReverseProxy";
 $app;
};
1
votes

In my case the frontend was in a different host and adding

MyApp->config(using_frontend_proxy => 1)

did make a difference and solved the problem.