Nginx proxy for Node applications

When you want to deploy your Node application, you probably dont want to expose your application directly on the internet. A good solution for this is adding a proxy in between the internet and your application.

Nginx is built to handle many concurrent connections so it's ideal to use as a gatekeeper in front of your application.

Nginx as basic proxy

It's relatively easy to use Nginx' built-in proxy capabilities to to achieve this.

server {  
  # exposed nginx server
  listen 80;
  server_name domain-name.com;

  location / {
    # node server runs on the following address
    proxy_pass http://127.0.0.1:3333;
  }
}

When you place your application behind a proxy, there are some things you need to think about though. You don't want your application to think that every client has the IP of the Nginx server.

In the next step, we add some headers to fiddle around with the IP's. This will ensure our application has access to the client's IP. Usually you need to some configuration to let your application trust these specific headers. Example configuration for Express

Nginx as load balancer

Once you have this setup, you can easily add multiple Node instances to the mix so Nginx can act as your load balancer. When you want to group multiple instances, you can use the upstream directive.

upstream node-server{  
  # troughout different requests by a client, redirect them to the same server
  # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash
  ip_hash;

  # multiple instances
  server 127.0.0.1:4444;
  server 127.0.0.1:3333;
}
server {  
  # exposed nginx server
  listen 80;
  server_name domain-name.com;

  # set headers to pass client IP to application behind proxy
  location / {
    proxy_set_header X-Forwarded-Proto https;
    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://node-server;
    proxy_redirect off;
  }

}

Nginx proxy that serves static assets

When using Express you most likely have added express-static to serve your static assets. This works fine but in production you can relieve your Node application from this task. It's straightforward to override this with Nginx.

Inside your server block, add a location block like this one:

# path to override
location /public {  
  # path to your actual public folder
  root /var/path/to/your/public/folder;
  # set far future expires header
  expires max;
}

# path can also be dynamic like this
location ~ ^/(build/|img/|scripts/|assets/|favicon.ico) {  
  root /some/path;
  expires max;
}

After editing your configuration and restarting the Nginx server you should see that the requests for the static assets will no longer make it to the Node process.