Configuring nginx for Node.js

This post assumes the node app is ready. Nginx is an opensource web server that can be used as a reverse proxy, meaning it forwards client (HTTP or HTTPS) requests to the appropriate backend server. Additional configuration is unnecessary for PHP or plain HTTP files because Nginx (or Apache) web servers can by design serve them (PHP files might need some CGI addons). But Node.js is a completely different story because Node generates its own web server independent of Nginx or Apache. So to use Node and Nginx together, it is necessary for Nginx to receive requests and forward them to Node, so Node can return the correct files.

Prerequisites

In this post, we assume Linux environment, particularly Debian and its derivative, Ubuntu. You will need sudo privileges as well, so if you haven’t added yourself (Linux user) to sudo group, please run

usermod -aG sudo username

You’ll also need Nginx. If you haven’t installed it, please run

apt install nginx

Once you’ve fulfilled these requirements, let’s start configuring the virtual host. From here on, the root folder of my Node app will be /var/www/daeyoung.

Configuring reverse proxy

Your Nginx configurations are placed under /etc/nginx/. Under sites-available are configuration files for different domains, if your website consists of subdomains in addition to your primary domain. Let’s say we’re creating a configuration file for daeyoung.com. Then you’ll need

sudo touch /etc/nginx/sites-available/daeyoung.com

This file will start with a server block:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    ...
}

To set up a proxy for your Node app, the block you’ll need to modify is

location / {
    ...
}

If your Node app is running on port 3000, change that block to

location / {
    proxy_pass http://localhost:3000;
    include /etc/nginx/proxy_params;
}

The code is somewhat self-explanatory: It receives the request as proxy-passes it to localhost port 3000. Let’s now see what include /etc/nginx/proxy_params; is.

Proxy parameters

After the proxy_pass directive, there have to be lines after lines of proxy configuration, generic stuff that never changes. So instead of making the configuration long and dirty, we separate it out as a separate file, to never look at it again, until we have to. To change this file, use whatever text editor you prefer (e.g., nano, vi, vim, and emacs).

vim /etc/nginx/proxy_params

In that file, paste the following:

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

This is minimalistic configuration but you can always add more directives to it, which this post will not cover.

Restarting Nginx

Once you’ve finished configuring Nginx reverse proxy, we now need to push that change to Nginx. To do that, create a symbolic link of /etc/nginx/sites-available/daeyoung.com under /etc/nginx/sites-enabled. It is quite literally sites enabled. Unless the configuration isn’t pushed to that folder, the website won’t reflect the changes you’ve made (unless your /etc/nginx/nginx.conf is modified to directly read in sites-available but that’s not recommended). To create the symlink, run

ln -s /etc/nginx/sites-available/daeyoung.com /etc/nginx/sites-enabled

You can check for syntax errors with

sudo nginx -t

If there are no errors, restart Nginx to push the changes to production:

sudo systemctl restart nginx

Voila! You’ve configured a Nginx reverse proxy for your Node app!

Daeyoung Lim
Daeyoung Lim
Statistics PhD Candidate

My research interests include Bayesian statistics, biostatistics, and computational statistics. I’m an English grammar fiend and a staunch proponent of plain language.