Reputation: 16873
I am trying to deploy up a Perl application that uses CGI::Application
through Nginx, using FastCGI to communicate between them.
Nginx keeps returning "502 Bad Gateway", and the error log is filled with this:
2015/02/03 12:40:03 [error] 11209#0: *2 upstream prematurely closed connection while reading response header from upstream, client: 10.1.1.23, server: www.example.com, request: "GET /test.fcgi HTTP/1.1", upstream: "http://127.0.0.1:5001/test.fcgi", host: "www.example.com"
Here is the Nginx site configuration:
upstream @perl {
# I had been trying to use a socket, but I switched to TCP to try WireShark.
# server unix:/var/run/nginx/my-app.sock;
server 127.0.0.1:5001;
}
server {
listen 80;
listen 443 ssl;
server_name www.example.com;
root /home/example/sites/www.example.com;
location ~* \.fcgi(/|$) {
fastcgi_split_path_info ^(.+?\.cgi)(/.*)$;
# (I know that the `if` is old-style, and that `try_files` is better, but that shouldn't affect whether it works or not.)
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 443;
proxy_pass http://@perl;
}
}
To see if the problem is with the Perl application itself, I created a new fcgi application based on the test code found in the CGI::Fast
documentation:
#!/usr/bin/perl -wT
use CGI::Fast;
# Added this to see if there are errors.
# See http://perldoc.perl.org/CGI/Carp.html
BEGIN {
use CGI::Carp qw(carpout);
open(LOG, ">>/home/example/sites/www.example.com/err.log") or
die("Unable to open mycgi-log: $!\n");
carpout(LOG);
}
local $count = 0;
$ENV{FCGI_SOCKET_PATH} = "127.0.0.1:5001";
$ENV{FCGI_LISTEN_QUEUE} = 100;
while ( my $q = new CGI::Fast ) {
$count++;
print $q->header( "text/plain" ),
"You are request number $count. Have a good day!\n";
}
When I run ./test.fcgi
, I can see in netstat
that it has bound to port 5001. When I go to the URL in the browser, I still get a 502 with this super-simple app. There is nothing in the error log that Carp
is writing to.
I do not want to use plain CGI (via a wrapper script) because of the application's long startup time, and I can't convert the whole application to Plack/PSGI.
How can I figure out why Nginx won't talk to Perl CGI::Fast
, even to the plain example from the docs?
Upvotes: 4
Views: 561
Reputation:
You are running a FastCGI server, but you are telling Nginx to connect to an HTTP server. These are not the same protocol.
To connect to a FastCGI server from Nginx, use ngx_http_fastcgi_module
, not ngx_http_proxy_module
, e.g.:
fastcgi_pass 127.0.0.1:5001;
Note that the proxy_set_header
module is not applicable here, as FastCGI uses CGI environment variables, not headers. If you need to set extra headers, you can do so using the fastcgi_param
directive, e.g.
fastcgi_param ENVIRONMENT_VARIABLE $value;
Nginx ships with some standard fastcgi_param
directives in a file which you'll probably want to just import wholesale:
include fastcgi_params;
Upvotes: 6