Node.js with NGINX

Installs git, NPM, Node.js and NGINX as a proxy for static files.

This cookbook is designed as template and needs to be modified to suit your needs.

This cookbook uses git to download a sample node.js repository, installs the dependencies and uses forever to start the index.js. Then nginx is configured to serve static files from the repository's public folder.

The following is installed:
git - is a distributed revision control system
NPM - is a package manager
Node.js - allows running javascript on the server.
pm2 - allows managing node servers.
nginx - is a proxy / webserver.
ufw - Ubuntu firewall. By default only ports 80, 443 and 22 are open.

Configuration summary

Ubuntu Ubuntu Vivid Vervet 15.04 Ubuntu Ubuntu Vivid Vervet 15.04
Package nginx install
Files

/etc/nginx/sites-available/default ensure file exist

## You should look at the following URL's in order to grasp a solid understandi$
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##


   #     proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=$
   #     proxy_temp_path /var/temp;
        include mime.types;

upstream nodejs_upstream {
        server localhost:5000; # change the port number
        keepalive 64;
}

server {
        listen 80;
        server_name nodeserver;
        access_log off;
        
        #http://wiki.nginx.org/HttpChunkinModule
        
        chunkin on;
 
        error_page 411 = @my_411_error;
        location @my_411_error {
            chunkin_resume;
        }
    
        
        location ~ /\.  { # eg .git is
               return 403; # not allowed
        }

        location ~* \.(js|jpg|png|svg|css|txt)$ {
                root /root/node-js-sample/public/; # change this to your node reposetory's public files.
                access_log off;
                expires 1w;
        }
        
        location / {
                proxy_redirect off;
                proxy_http_version 1.1;

                #for socket.io or similar
           #     proxy_set_header Upgrade $http_upgrade;
           #     proxy_set_header Connection "upgrade";

           #     proxy_set_header X-Real-IP $remote_addr;
           #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           #     proxy_set_header X-Rorwarded-Proto $scheme;
           #     proxy_set_header Host $host; #$http_host;
           #     proxy_set_header X-NginX-Proxy true;

                 proxy_hide_header X-Powered-By;
                 
                proxy_pass http://nodejs_upstream;

            #    proxy_cache one;
            #    proxy_cache_key sfs$request_uri$scheme;
        }
}

/etc/nginx/nginx.conf ensure file exist

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

events {
        worker_connections 1024;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        server_tokens off;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;

        # server_names_hash_bucket_size 64;
        server_name_in_redirect off;

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

        #Buffers
        #client_body_buffer_size 10K;
        #client_header_buffer_size 1k;
        #client_max_body_size 8m;
        #large_client_header_buffers 2 1k;

        #Timeouts
        client_body_timeout 12;
        client_header_timeout 12;
        keepalive_timeout 15;
        send_timeout 10;

        ##
        # Logging Settings
        ##

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

        ##
        # Gzip Settings
        ##
        
        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 5;
        gzip_min_length 1000;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/html text/css application/json application/x-javascript text/xm$

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##
        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

/var/temp ensure directory exist

/var/log/nginx ensure directory exist

/var/log ensure directory exist

/etc ensure directory exist

/etc/nginx/sites-available ensure directory exist

/var/cache ensure directory exist

/var/cache/nginx Permissions: www-data (Recursive) ensure directory exist

/etc/nginx ensure directory exist

/var ensure directory exist

Hooks

Post custom

#!/bin/bash
set -ue

rm -rf node-js-sample
git clone https://github.com/heroku/node-js-sample.git
cd node-js-sample
npm install
npm install pm2 -g
pm2 start index.js
sudo service nginx restart
sudo pm2 startup ubuntu
pm2 save
Package ufw install
Hooks

Post firewall-rules

#!/bin/bash
set -ue

ufw enable
ufw allow 80/tcp #http
ufw allow 443/tcp #https
ufw allow 22/tcp #ssh
ufw reload
Package git install
Hooks

Post git-settings

#!/bin/bash
set -ue

# allows Push to deploy see: https://github.com/blog/1957-git-2-3-has-been-released
#git config receive.denyCurrentBranch updateInstead
Package nodejs install
Hooks

Post symlinking

#!/bin/bash
set -ue

sudo ln -s /usr/bin/nodejs /usr/bin/node
Package npm install
Debian Wheezy 7.0 Debian Wheezy 7.0
Package nginx install
Files

/etc/nginx/nginx.conf ensure file exist

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

events {
        worker_connections 1024;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        server_tokens off;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;

        # server_names_hash_bucket_size 64;
        server_name_in_redirect off;

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

        #Buffers
        #client_body_buffer_size 10K;
        #client_header_buffer_size 1k;
        #client_max_body_size 8m;
        #large_client_header_buffers 2 1k;

        #Timeouts
        client_body_timeout 12;
        client_header_timeout 12;
        keepalive_timeout 15;
        send_timeout 10;

        ##
        # Logging Settings
        ##

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

        ##
        # Gzip Settings
        ##
        
        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 5;
        gzip_min_length 1000;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/html text/css application/json application/x-javascript text/xm$

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##
        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

/etc/nginx/sites-available/default ensure file exist

## You should look at the following URL's in order to grasp a solid understandi$
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##


   #     proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=$
   #     proxy_temp_path /var/temp;
        include mime.types;

upstream nodejs_upstream {
        server localhost:5000; # change the port number
        keepalive 64;
}

server {
        listen 80;
        server_name nodeserver;
        access_log off;
        
        location ~ /\.  { # eg .git is
               return 403; # not allowed
        }

        location ~* \.(js|jpg|png|svg|css|txt)$ {
                root /root/node-js-sample/public/; # change this to your node reposetory's public files.
                access_log off;
                expires 1w;
        }
        
        location / {
                proxy_redirect off;
                proxy_http_version 1.1;

                #for socket.io or similar
           #     proxy_set_header Upgrade $http_upgrade;
           #     proxy_set_header Connection "upgrade";

           #     proxy_set_header X-Real-IP $remote_addr;
           #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           #     proxy_set_header X-Rorwarded-Proto $scheme;
           #     proxy_set_header Host $host; #$http_host;
           #     proxy_set_header X-NginX-Proxy true;

                 proxy_hide_header X-Powered-By;
                 
                proxy_pass http://nodejs_upstream;

            #    proxy_cache one;
            #    proxy_cache_key sfs$request_uri$scheme;
        }
}

/var/log/nginx ensure directory exist

/var/temp ensure directory exist

/var/log ensure directory exist

/etc ensure directory exist

/etc/nginx/sites-available ensure directory exist

/var/cache ensure directory exist

/var/cache/nginx ensure directory exist

/etc/nginx ensure directory exist

/var ensure directory exist

Hooks

Post customise-me

#!/bin/bash
set -ue

rm -rf node-js-sample
git clone https://github.com/heroku/node-js-sample.git
cd node-js-sample
npm install
npm install -g pm2
pm2 start index.js
sudo service nginx restart
sudo pm2 startup
pm2 save
Package ufw install
Hooks

Post rules

#!/bin/bash
set -ue

ufw enable
ufw allow 80/tcp #http
ufw allow 443/tcp #https
ufw allow 22/tcp #ssh
ufw reload
Package nodejs install
Hooks

Post configure

#!/bin/bash
set -ue

apt-get install --yes nodejs
Package htop install
Package git install
Ubuntu Trusty Tahr 14.04 Ubuntu Trusty Tahr 14.04
Package nginx install
Files

/etc/nginx/sites-available/default ensure file exist

## You should look at the following URL's in order to grasp a solid understandi$
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##


   #     proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=$
   #     proxy_temp_path /var/temp;
        include mime.types;

upstream nodejs_upstream {
        server localhost:5000; # change the port number
        keepalive 64;
}

server {
        listen 80;
        server_name nodeserver;
        access_log off;
        
        #http://wiki.nginx.org/HttpChunkinModule
        
        chunkin on;
 
        error_page 411 = @my_411_error;
        location @my_411_error {
            chunkin_resume;
        }
    
        
        location ~ /\.  { # eg .git is
               return 403; # not allowed
        }

        location ~* \.(js|jpg|png|svg|css|txt)$ {
                root /root/node-js-sample/public/; # change this to your node reposetory's public files.
                access_log off;
                expires 1w;
        }
        
        location / {
                proxy_redirect off;
                proxy_http_version 1.1;

                #for socket.io or similar
           #     proxy_set_header Upgrade $http_upgrade;
           #     proxy_set_header Connection "upgrade";

           #     proxy_set_header X-Real-IP $remote_addr;
           #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           #     proxy_set_header X-Rorwarded-Proto $scheme;
           #     proxy_set_header Host $host; #$http_host;
           #     proxy_set_header X-NginX-Proxy true;

                 proxy_hide_header X-Powered-By;
                 
                proxy_pass http://nodejs_upstream;

            #    proxy_cache one;
            #    proxy_cache_key sfs$request_uri$scheme;
        }
}

/etc/nginx/nginx.conf ensure file exist

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

events {
        worker_connections 1024;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        server_tokens off;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;

        # server_names_hash_bucket_size 64;
        server_name_in_redirect off;

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

        #Buffers
        #client_body_buffer_size 10K;
        #client_header_buffer_size 1k;
        #client_max_body_size 8m;
        #large_client_header_buffers 2 1k;

        #Timeouts
        client_body_timeout 12;
        client_header_timeout 12;
        keepalive_timeout 15;
        send_timeout 10;

        ##
        # Logging Settings
        ##

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

        ##
        # Gzip Settings
        ##
        
        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 5;
        gzip_min_length 1000;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/html text/css application/json application/x-javascript text/xm$

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##
        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

/var/log/nginx ensure directory exist

/var/temp ensure directory exist

/var/log ensure directory exist

/etc ensure directory exist

/etc/nginx/sites-available ensure directory exist

/var/cache ensure directory exist

/var/cache/nginx ensure directory exist

/etc/nginx ensure directory exist

/var ensure directory exist

Hooks

Post custom

#!/bin/bash
set -ue

rm -rf node-js-sample
git clone https://github.com/heroku/node-js-sample.git
cd node-js-sample
npm install
npm install pm2 -g
pm2 start index.js
sudo service nginx restart
sudo pm2 startup ubuntu
pm2 save
Package ufw install
Hooks

Post firewall-rules

#!/bin/bash
set -ue

ufw enable
ufw allow 80/tcp #http
ufw allow 443/tcp #https
ufw allow 22/tcp #ssh
ufw reload
Package nodejs install
Hooks

Post symlinking

#!/bin/bash
set -ue

sudo ln -s /usr/bin/nodejs /usr/bin/node
Package htop install
Package git install
Package npm install

Quick Deployment
Advanced Deployment