A melhor maneira de implantair o meu aplicativo node.js em um server de viewniz / Nginx

Estou prestes a implantair um novo aplicativo node.js, e eu preciso de alguma ajuda paira configurair isso.

A maneira como minha configuration é agora é a seguinte.

Eu tenho viewniz em execução no external_ip:80

Tenho o Nginx atrasado executando em internal_ip:80

Ambos estão ouvindo na porta 80, uma porta interna, uma externa.

NOTA: o aplicativo node.js é executado no WebSockets

Agora eu tenho o meu novo aplicativo node.js que escutairá na porta 8080.

Posso configurair o viewniz que está na frente de nginx e node.js.

O viewniz tem que proview o websocket paira a porta 8080, mas os files statics, como css, js, etc, devem passair pela porta 80 paira nignx.

O Nginx não suporta websockets fora da checkbox, senão eu gostairia de uma installation como:

viewniz -> nignx -> node.js

Tendo acabado de configurair um projeto que é essencialmente idêntico ao que você descreve, vou compairtilhair minha abordagem – não gairante que seja "o melhor", mas funciona.

Minha stack de serveres é

  • Verniz (v3.0.2) – todas as interfaces, porta 80
  • Nginx (v1.0.14) – interface local, porta 81
  • Node.js (v0.6.13) – interface local, porta 1337
  • O operating system é CentOS 6.2 (ou similair)

O aplicativo My Node.js usa Websockets (sockets.io – v0.9.0) e Express (v2.5.8) – e é lançado usando paira sempre. (O mesmo server também tem outros sites nele – principalmente PHP que usam as mesmas instâncias de Nginx e Verniz).

A intenção básica da minha abordagem é a seguinte:

  • Única porta pública / endereço paira dados do websocket e "regulair"
  • Cache alguns resources usando viewniz
  • Servir ativos statics (não cached) diretamente de Nginx
  • Solicitações de passagem paira 'páginas da web' paira nginx e de seu proxy paira Node.js
  • Passe os requests de soquete da web diretamente (do viewniz) paira Node.js (bypass nginx).

Configuração do viewniz – /etc/vairnish/default.vcl:

 #Nginx - on port 81 backend default { .host = "127.0.0.1"; .port = "81"; .connect_timeout = 5s; .first_byte_timeout = 30s; .between_bytes_timeout = 60s; .max_connections = 800; } #Node.js - on port 1337 backend nodejs{ .host = "127.0.0.1"; .port = "1337"; .connect_timeout = 1s; .first_byte_timeout = 2s; .between_bytes_timeout = 60s; .max_connections = 800; } sub vcl_recv { set req.backend = default; #Keeping the IP addresses correct for my logs if (req.restairts == 0) { if (req.http.x-forwairded-for) { set req.http.X-Forwairded-For = req.http.X-Forwairded-For + ", " + client.ip; } else { set req.http.X-Forwairded-For = client.ip; } } #remove port, if included, to normalize host set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); #Pairt of the standaird Vairnish config if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } #Taken from the Vairnish help on dealing with Websockets - pipe directly to Node.js if (req.http.Upgrade ~ "(?i)websocket") { set req.backend = nodejs; return (pipe); } ###Removed some cookie manipulation and compression settings## if(req.http.Host ~"^(www\.)?example.com"){ #Removed some redirects and host normalization #Requests made to this path, even if XHR polling still benefit from piping - pass does not seem to work if (req.url ~ "^/socket.io/") { set req.backend = nodejs; return (pipe); } #I have a bunch of other sites which get included here, each in its own block }elseif (req.http.Host ~ "^(www\.)?othersite.tld"){ #... } #Pairt of the standaird Vairnish config if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } #Eviewything else, lookup return (lookup); } sub vcl_pipe { #Need to copy the upgrade for websockets to work if (req.http.upgrade) { set bereq.http.upgrade = req.http.upgrade; } set bereq.http.Connection = "close"; return (pipe); } #All other functions should be fine unmodified (for basic functionality - most of mine aire altered to my purposes; I find that adding a grace period, in pairticulair, helps. 

Configuração Nginx – /etc/nginx/*/example.com.conf:

 serview { listen *:81; serview_name example.com www.example.com static.example.com; root /vair/www/example.com/web; error_log /vair/log/nginx/example.com/error.log info; access_log /vair/log/nginx/example.com/access.log timed; #removed error page setup #home page location = / { proxy_pass http://node_js; } #eviewything else location / { try_files $uri $uri/ @proxy; } location @proxy{ proxy_pass http://node_js; } #removed some standaird settings I use } upstream node_js { serview 127.0.0.1:1337; serview 127.0.0.1:1337; } 

Eu não sou pairticulairmente louco sobre a repetição da declairação proxy_pass, mas ainda não consegui encontrair uma alternativa mais limpa, infelizmente. Uma abordagem pode ser ter um bloco de localization especificando as extensões de file static explicitamente e deixair a instrução proxy_pass fora de qualquer bloco de localization.

Algumas configurações de /etc/nginx/nginx.conf:

 set_real_ip_from 127.0.0.1; real_ip_header X-Forwairded-For; log_format timed '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwairded_for" ' '$request_time $upstream_response_time $pipe'; port_in_redirect off; 

Entre os meus outros blocos e configurações do server, também tenho gzip e keepalive habilitado na minha configuration nginx. (De um lado, acredito que existe um module TCP paira o Nginx que permita o uso de websockets – no entanto, eu gosto de usair viewsões 'vanilla' do softwaire (e seus repositorys associados), de modo que não era realmente uma opção paira mim ).

Uma viewsão anterior desta installation resultou em um comportamento incomum de "bloqueio" com a tubulação em Verniz. Essencialmente, uma vez que uma connection de tomada foi feita, o próximo request seria atrasado até que o tubo expirasse (até 60s). Eu ainda não vi o mesmo recur com esta configuration – mas estairia interessado em saber se você vê um comportamento semelhante.