19

I am trying to configure a Nginx server to connect to a Node.js HTTP server via a UNIX domain socket.

The Nginx configuration file:

server {
  listen 80;

  location / {
    proxy_pass http://unix:/tmp/app.socket:/;
  }
}

(according to http://wiki.nginx.org/HttpProxyModule#proxy_pass)

The Node.js script:

var http = require('http');

http.createServer(function(req, res) {
  console.log('received request');
  req.end('received request\n');
}).listen('/tmp/app.socket');

Now, when I try to call

curl http://localhost/

I only get the 502 Bad Gateway error page in curl and nothing on the Node.js process.

Am I doing something wrong?

edit:

After trying quanta's solution, the mistake must have to do with the Nginx configuration, since the Node.js process establishes the connection to the socket correctly.

I also tried to configure Nginx this way:

upstream myapp {
  server unix:/tmp/app.socket;
}

server {
  listen 80;

  location / {
    proxy_pass http://myapp;
  }
}

But this didn't work either.

BTW I'm using Nginx v1.0.6.

The following is being written to the error log in Nginx, when I use the second configuration

2011/09/28 13:33:47 [crit] 1849#0: *5 connect() to unix:/tmp/app.socket failed  (13: Permission denied) while connecting to upstream, client: 127.0.0.1,        server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/app.socket:/", host: "localhost:80"
pvorb
  • 980
  • 3
  • 10
  • 15

4 Answers4

12

chmod 777 /tmp/app.socket

This is a solution but not the solution.

you should probably run both webservers with the same user and/or same group so you dont have to make your socket world read writable. Also i dont see why a socket needs to be executable. so 6 should be enough. i.e: 660

Fehlersturm
  • 136
  • 1
  • 2
  • For those less familiar with Unix permissions, if this scheme were used for multiple accounts on the same host, each account could and write to the others socket. That's why this is "not a solution" even though it works. – Mark Stosberg Mar 12 '15 at 14:20
5

"502 Bad Gateway" means that Nginx cannot receive response from upstream server. Make sure that you have a process listen on /tmp/app.socket:

# netstat --protocol=unix -nlp | grep app.socket
quanta
  • 50,327
  • 19
  • 152
  • 213
  • I have got a process listen on `/tmp/app.socket`. When I run your command it gives me `unix 2 [ ACC ] STREAM HÖRT 29673 7029/node /tmp/app.socket`. But thanks for your tip. This command is quite handy. – pvorb Sep 28 '11 at 00:39
4

I solved it. The error log message I postet above lead me to the answer.

I always started the Node.js process as a normal user, while Nginx was started by root. When Node.js was started, it created the socket with srwxr-xr-x rights. So Nginx could not write to the socket, it could only read from it. This way everything could set up correctly, when the processes got started. But once I called the a web page, Nginx realized that it didn't have the rights to proxy the request to the socket.

The solution was to run

chmod 777 /tmp/app.socket

Now, everything is ok.

Thank you, anyway!

pvorb
  • 980
  • 3
  • 10
  • 15
2

I know I'm late to the party, but this page came up in a Google search for this exact problem. Running a shell command isn't really an ideal solution for me, and this is how I solved it;

Instead of running chmod manually, you can make Node do it with the 'fs' library after the socket is created:

var fs = require('fs');

var server = http.createServer(...This varies by implementation...);

server.listen('/path/to/socket');

server.on('listening', onListening);

function onListening() {
  fs.chmodSync('/path/to/socket', '777');
}

Obviously if you have other things in your onListening event already, you should just add the call to chmodSync into the existing function.

jliles
  • 21
  • 3