Node.jsをunix domain socketでlistenしたときにNginxからプロキシできない
という現象に対応した際のメモ。
環境
CentOS 7 on VirtualBoxです。
Nodeのソース
// express使っている var sockPath = '/tmp/node.sock'; var server = app.listen(sockPath, function() { console.log('Listening on port %d', server.address().port); });
nginx.conf
worker_processes 1; events { worker_connections 1024; } http { upstream app { server unix:/tmp/node.sock; } server { location / { proxy_pass http://app; } } }
現象
curl localhost
すると 502Bad Gatewayが返る。
nginxのerror.logには
2015/07/29 11:05:16 [crit] 10781#0: *1 connect() to unix:/tmp/node.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/node.sock:/", host: "localhost"
とな。
対処方法
とりあえず、ググってみたところ、下記のページがひっかかりました。
/tmp
をプロセス間のコミュニケーションに使ってはいかんと最近はなっているとのこと。
試しに、/tmp
→/var/lib/app
に変更してみました。
すると今度はPermission denied
と怒られました。
2015/07/29 11:26:03 [crit] 10995#0: *15 connect() to unix:/var/lib/app/node.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/var/lib/app/node.sock:/", host: "localhost"
更にググったところ
な回答があったので、
以下のコマンドでnginxをnode.jsのアプリのフォルダに触れるようにし、
chown nodeuser:nginx /var/lib/app chmod g+rxs /var/lib/app # これでnginxグループのrxがnode.sockにも継承される!
さらに、
var sockPath = '/var/lib/app/node.sock'; try { fs.unlinkSync(sockPath); } catch(e) { } var server = app.listen(sockPath, function(err) { if (err) throw err; fs.chmodSync(sockPath, '660'); console.log('Listening on port %d', server.address().port); });
な感じで、なんとか動くようにはなりました。
なお、node.sockにはnginxグループのwrite権限が必要なので、chmodSyncは必要です。
が、イマイチスマートでない。。納得いかない。。
※追記:こちらの方法でいけるかもしれない(試してはいない)