I'm using this buildpack to serve static files on Heroku with a node + nginx setup. While static assets are served properly, trying to serve content through node results in a 502 Bad Gateway. Node on its own works fine and so does nginx. The problem is when the two need to work together which I guess is because I haven't configured the nginx upstream settings right.
Here's my nginx conf:
worker_processes 1;
error_log /app/nginx/logs/error.log;
daemon off;
events {
worker_connections 1024;
}
http {
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
upstream node_conf {
server 127.0.0.1:<%= ENV['PORT'] %>;
keepalive 64;
}
server {
listen <%= ENV['PORT'] %>;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://node_conf;
}
location ~* ^.+\.(jpg|gif|png|ico|css|js|html|htm)$ {
root /app;
access_log off;
expires max;
}
location /static {
root /app;
index index.html index.htm;
}
}
}
.
My _static.cfg:
SERVER_TYPE="nginx"
BUILD_WEB_ASSETS="true"
.
My node server:
var app = require( 'express ')()
app.get( '/', function(req, res) { res.send( 'This is from Node.' ) })
app.listen( process.env.PORT )
.
I also have a sample html file in /static to test if nginx works:
<html>This is from nginx.</html>
.
With this config, appname.herokuapp.com should display "This is from Node." but instead I get the 502.
appname.herokuapp.com/static displays "This is from nginx" as it should, so no problems with nginx and static content.
I have tried every combination of values for upstream in nginx server settings but none have worked. What else can I try to make nginx proxy requests to node?
Here's my Heroku Procfile in case it helps: web: bin/start_nginx
I am not really familiar with Heroku, and pretty new to Nginx, but I'll give it a shot: To me it looks like the Nginx-config is saying that Nginx and the node.js app are using the same port (<%= ENV['PORT'] %>).
What you want is Nginx to listen to incoming connections (usually port 80), and have it forward them to the node.js app. Here is an example Nginx config:
# the IP(s) on which your node server is running. I chose port 4000.
upstream xxx.xxx.xxx.xxx { #Your IP adress as seen from the internet
server 127.0.0.1:4000; #Your local node.js process
}
# the nginx server instance
server {
listen 0.0.0.0:80; #Have Nginx listen for all incoming connections on port 80
server_name my-site;
access_log /var/log/nginx/my-site.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://xxx.xxx.xxx.xxx/; #Your IP adress as seen from the internet
proxy_redirect off;
}
}
This config is working for me on a webserver I am hosting in my living-room. Good luck!
Here's a README with information to get nginx and Node.js working together from a project I created a while back. Also included is an example nginx.conf.
As an overview, basically you're just creating sockets with Node then setting nginx to pipe those upstream. I commonly use this when I want to run multiple Node processes and have nginx stand in front of it.
It also includes working with socket.io out of the box, so you can use those to see how to configure your Node instance as well.