Como configurar o servidor HTTP Nginx proxy_pass Node.js através do soquete UNIX?

16

Estou tentando configurar um servidor Nginx para conectar-se a um servidor HTTP Node.js. por meio de um soquete de domínio UNIX.

O arquivo de configuração do Nginx:

server {
  listen 80;

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

(de acordo com http://wiki.nginx.org/HttpProxyModule#proxy_pass )

O script Node.js:

var http = require('http');

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

Agora, quando tento ligar

curl http://localhost/

Eu recebo apenas a página de erro 502 Bad Gateway em curl e nada no processo Node.js.

Estou fazendo algo errado?

editar:

Depois de tentar a solução do quanta, o erro deve estar relacionado à configuração do Nginx, pois o processo Node.js. estabelece a conexão com o soquete corretamente.

Eu também tentei configurar o Nginx desta maneira:

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

server {
  listen 80;

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

Mas isso também não funcionou.

BTW eu estou usando o Nginx v1.0.6.

O seguinte está sendo gravado no log de erros no Nginx, quando eu uso a segunda configuração

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
fonte

Respostas:

6

chmod 777 /tmp/app.socket

Esta é uma solução, mas não a solução.

você provavelmente deve executar os dois servidores da web com o mesmo usuário e / ou mesmo grupo, para não precisar que o mundo do soquete seja gravável. Também não vejo por que um soquete precisa ser executável. então 6 deve ser suficiente. ie: 660

Fehlersturm
fonte
Para aqueles menos familiarizados com as permissões do Unix, se esse esquema fosse usado para várias contas no mesmo host, cada conta poderia e gravaria no soquete das outras. É por isso que "não é uma solução", mesmo que funcione.
Mark Stosberg
5

"502 Bad Gateway" significa que o Nginx não pode receber resposta do servidor upstream. Certifique-se de ter um processo escutando /tmp/app.socket:

# netstat --protocol=unix -nlp | grep app.socket
quanta
fonte
Eu tenho um processo escute /tmp/app.socket. Quando eu executo seu comando, isso me dá unix 2 [ ACC ] STREAM HÖRT 29673 7029/node /tmp/app.socket. Mas obrigado pela sua dica. Este comando é bastante útil.
pvorb
3

Eu resolvi isso. A mensagem de log de erro que eu poste acima me leva à resposta.

Sempre iniciei o processo Node.js. como um usuário normal, enquanto o Nginx foi iniciado pela raiz. Quando o Node.js foi iniciado, ele criou o soquete com srwxr-xr-xdireitos. Portanto, o Nginx não pôde escrever no soquete, apenas pôde ler a partir dele. Dessa forma, tudo poderia ser configurado corretamente quando os processos foram iniciados. Porém, quando liguei para a página da Web, o Nginx percebeu que não tinha o direito de proxy da solicitação no soquete.

A solução foi executar

chmod 777 /tmp/app.socket

Agora está tudo bem.

Obrigado mesmo assim!

pvorb
fonte
2

Sei que estou atrasado para a festa, mas esta página apareceu em uma pesquisa no Google para esse problema exato. Executar um comando shell não é realmente uma solução ideal para mim, e foi assim que eu o resolvi;

Em vez de executar o chmod manualmente, você pode fazer o Node fazê-lo com a biblioteca 'fs' após a criação do soquete:

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');
}

Obviamente, se você já possui outras coisas no evento onListening, adicione a chamada para chmodSync na função existente.

jliles
fonte