Comment configurer le serveur HTTP Nginx proxy_pass Node.js via un socket UNIX?

16

J'essaie de configurer un serveur Nginx pour se connecter à un serveur HTTP Node.js via une socket de domaine UNIX.

Le fichier de configuration Nginx:

server {
  listen 80;

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

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

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

Maintenant, quand j'essaie d'appeler

curl http://localhost/

Je reçois uniquement la page d'erreur 502 Bad Gateway en curl et rien sur le processus Node.js.

Est-ce que je fais quelque chose de mal?

Éditer:

Après avoir essayé la solution de quanta, l'erreur doit être liée à la configuration de Nginx, car le processus Node.js établit correctement la connexion au socket.

J'ai également essayé de configurer Nginx de cette façon:

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

server {
  listen 80;

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

Mais cela n'a pas fonctionné non plus.

BTW J'utilise Nginx v1.0.6.

Ce qui suit est écrit dans le journal des erreurs dans Nginx, lorsque j'utilise la deuxième 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
la source

Réponses:

6

chmod 777 /tmp/app.socket

C'est une solution mais pas la solution.

vous devriez probablement exécuter les deux serveurs Web avec le même utilisateur et / ou le même groupe afin de ne pas avoir à rendre votre monde de socket accessible en écriture. De plus, je ne vois pas pourquoi un socket doit être exécutable. donc 6 devrait suffire. soit: 660

Fehlersturm
la source
Pour ceux moins familiers avec les autorisations Unix, si ce schéma était utilisé pour plusieurs comptes sur le même hôte, chaque compte pourrait et écrire dans le socket des autres. C'est pourquoi ce n'est "pas une solution" même si cela fonctionne.
Mark Stosberg
5

"502 Bad Gateway" signifie que Nginx ne peut pas recevoir de réponse du serveur en amont. Assurez-vous d'avoir un processus à écouter /tmp/app.socket:

# netstat --protocol=unix -nlp | grep app.socket
quanta
la source
J'ai un processus à écouter /tmp/app.socket. Lorsque j'exécute votre commande, cela me donne unix 2 [ ACC ] STREAM HÖRT 29673 7029/node /tmp/app.socket. Mais merci pour votre conseil. Cette commande est assez pratique.
pvorb
3

Je l'ai résolu. Le message du journal des erreurs que j'ai posté ci-dessus m'a conduit à la réponse.

J'ai toujours démarré le processus Node.js en tant qu'utilisateur normal, tandis que Nginx a été démarré par root. Lorsque Node.js a été démarré, il a créé le socket avec des srwxr-xr-xdroits. Nginx ne pouvait donc pas écrire sur le socket, il ne pouvait que lire sur celui-ci. De cette façon, tout pourrait se mettre en place correctement, au démarrage des processus. Mais une fois que j'ai appelé la page Web, Nginx s'est rendu compte qu'il n'avait pas les droits de proxy de la requête sur le socket.

La solution était d'exécuter

chmod 777 /tmp/app.socket

Maintenant, tout va bien.

Merci quand même!

pvorb
la source
2

Je sais que je suis en retard à la fête, mais cette page est apparue dans une recherche Google pour ce problème exact. L'exécution d'une commande shell n'est pas vraiment une solution idéale pour moi, et c'est ainsi que je l'ai résolue;

Au lieu d'exécuter chmod manuellement, vous pouvez faire en sorte que Node le fasse avec la bibliothèque 'fs' après la création du socket:

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

Évidemment, si vous avez déjà d'autres choses dans votre événement onListening, vous devez simplement ajouter l'appel à chmodSync dans la fonction existante.

jliles
la source