back to index

Reverse-Proxying a Node Service with Nginx

Routing traffic through Nginx to a Node app listening on a non-standard port.

published Mar 24, 2018 tags #linux #nginx #node

~/posts/nginx-node-service $ cat post.md

/ LANG EN / 中文
/ THEME / /

Overview

A short walkthrough of putting Nginx in front of a Node service that’s listening on some other port, install steps included.

Install

You’ll need:

  1. Nginx
  2. Node
  3. forever

Node

curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
sudo apt-get install -y nodejs

Nginx

sudo apt-get install -y nginx

forever

sudo npm install -g forever

Configuration

Start with Nginx’s global config.

Global

cd /etc/nginx
cat nginx.conf

It looks roughly like this:

2018-07-19 update: uncommenting client_max_body_size and raising it lifts the upload size cap.

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off; # 2019-03-05 update: turning this off hides the nginx version, small security win

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    ##
    # Max POST upload size limit
    ##

    # client_max_body_size 20m;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;       # <== make sure this isn't commented out
    include /etc/nginx/sites-enabled/*;     # <== same
}

Make sure include /etc/nginx/conf.d/*.conf; and include /etc/nginx/sites-enabled/*; are uncommented.

Per-project

Drop a project-specific config under /etc/nginx/conf.d. The example below sets up cgb.mipha.io for champion-gg-bot, whose Node service listens on port 8081:

cd /etc/nginx/conf.d
sudo nano cgb_mipha_io_8081.conf
upstream cgbmiphaio {                   # app name
    server 127.0.0.1:8081;              # node's port
    keepalive 64;
}

server {
    listen 80;                          # 80 for http, 443 for https
    server_name xxx.xxx.xxx.xxx cgb.mipha.io;  # multiple names, space-separated

    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_set_header Connection "";
        proxy_pass http://cgbmiphaio;   # app name from upstream above
    }
}

Nginx won’t auto-reload the new file. Validate first, then reload:

sudo nginx -t
sudo service nginx reload
# or, if this is the first start
sudo service nginx start

Running the project

Once the project is built, hand it off to forever:

forever start dist/index.js

To inspect or stop:

forever list
forever stop dist/index.js
forever stopall
back to index