Advanced NGINX/PM2 server
by Alexandre Strzelewicz -

This tutorial is about setting up an hardened NGINX/PM2 combo server (on ubuntu).

Connecting via SSH

First let's copy some SSH keys to facilitate connections to the remote server:

$ ssh-keygen -t rsa                 # generate pub/priv keys
$ ssh-copy-id root@myserver.com     # copy key to target server

Now let's SSH to it:

$ ssh root@myserver.com

Usefull package

These packages are important for HTTPS connections, node.js:

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install htop git python-software-properties curl libm17n-0 rcconf dialog graphicsmagick build-essential openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev

Compile & install Nginx

We gonna compile and install a tuned Nginx.

Google perf tools

$ sudo apt-get install libgoogle-perftools-dev google-perftools

Nginx from sources

Let's get the latest stable version of Nginx and do some maths:

$ wget http://nginx.org/download/nginx-1.6.0.tar.gz
$ tar zxvf nginx-1.6.0.tar.gz
$ cd nginx-1.6.0/
$ ./configure --with-google_perftools_module --with-http_stub_status_module --with-http_ssl_module
$ make
$ make install
$ ln -s /usr/local/nginx/sbin/nginx /usr/bin/

Nginx startup script

To be sure that NGINX will be up on restart:
Create this file in /etc/init/nginx.conf:

# nginx

description "nginx http daemon"  
author "George Shammas <georgyo@gmail.com>"

start on (filesystem and net-device-up IFACE=lo)  
stop on runlevel [!2345]

env DAEMON=/usr/bin/nginx  
env PID=/usr/local/nginx/logs/nginx.pid

expect fork  
respawn  
respawn limit 10 5

pre-start script  
        $DAEMON -t
        if [ $? -ne 0 ]
                then exit $?
        fi
end script

exec $DAEMON  

Then activate it:

$ initctl list | grep nginx
$ initctl start nginx

NVM

NVM is Node Version Manager - Simple bash script to manage multiple node.js versions:

https://github.com/creationix/nvm

To install it:

$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh
$ source ~/.nvm/nvm.sh

Then:

$ nvm install v0.11.10       # Install
$ nvm use 0.11.10            # Use 0.11.10
$ nvm alias default 0.11.10  # Set 0.11.10 as default

Install PM2

PM2 will permits you to manage your NodeJS processes easily, (https://github.com/Unitech/pm2):

$ npm install pm2 -g

Create startup script

$ pm2 startup ubuntu

Run your app:

$ pm2 start app.js

Make PM2 start on reboot:

$ pm2 startup ubuntu

(Follow the instructions told by the CLI)

Nginx configuration

Content of the /usr/local/nginx/conf/nginx.conf:
(Change the port in the upstream part depending on which port your application run)

worker_processes  auto;

events {  
    worker_connections  1024;
}

http {  
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    tcp_nodelay     on;
    keepalive_timeout  2;

    gzip on;
    gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_proxied any;
    gzip_min_length  1000;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Disable GZIP for IE6                                                                                              
    gzip_disable "MSIE [1-6].(?!.*SV1)";

   upstream pm2upstream {
      server 127.0.0.1:3033;
      keepalive 64;
    }

    server {                                          
      listen 80;

      server_name myserver.com;
      keepalive_timeout 10;

      location / {
          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   X-Forwarded-Proto $scheme;
          proxy_set_header   Host              $http_host;
          proxy_set_header   X-NginX-Proxy     true;
          proxy_set_header   Connection        "";
          proxy_pass         http://pm2upstream;

     }
    }
}

Test

$ google-chrome http://myserver.com