[CF-I] Configure your staging machine with Node.js and NGINX

nodejs

If you are one of those critical readers, you might be asking yourself: what the hell is [CF-I]. Well, I'm a Linux "control" freak and I'm trying to compile a series of blogposts where I can keep track and explain to myself how I solved problems that i've been facing daily in the backend world.

If you want to cut the chase and skip the brief explanation you can find my NGINX Config files on this Github repository.

 PaaS & SaaS

Telling  freak like me to use Heroku for instance will kinda limiting and demotivating. That’s why I dislike using any Platform or Software as a Service, although they present many advantages. My friends tried to convince me otherwise using the following args:

” It’s really fast to setup, you’ll start coding your app in no time… ”
” …Ah I love NodeJitsu, I won’t worry about scaling my app”

You might agree with them, as these arguments are all valid, unfortunately the winning variable in todays matrix is speed
If you’re a  World of Warcraft fan, like I used to be, you can’t but recall that Goblin’s voice “Time is money friend…”

But I believe in building my own backend system without relying on any third party entities ( Except for Analytics and so) that will not only save you time and money but it will tickle your knowledge in understanding and dealing with complex systems. After all, it’s good practice, that’s what really matters. The currency of the Universe is Knowledge.

“Ahh! Take me back to configuring this goddamn Linux Machine…”

Node.JS & NGINX

NGINX is way faster at serving static content than Node.JS, combine them and you’ll throttle down the traffic that hits your Node processes, and therefore you’ll get a decent and scalable web application that can really scale beyond the good ol’ Web services like Apache. Not forget that both Node.JS and NGINX are event driven.

Setting up the Production Environment

My Linode VPS is running on an Ubuntu 12.04 LTS (Long Term Support) distribution I’ve also tried it on my Digital Ocean Debian 7 droplet with a slightly different setup.

After adding your domain zone inside the Linode DNS Manager and going through some basic Linux and security configurations you’re ready to install both Node.JS and NGINX.
After installing NGINX and building your Node app with Express for example you need to create your NGINX config file

sudo nano /etc/nginx/sites-available/example.com

Add the config file bellow assuming that your domain name is example.com


# Node Express on Port 8080
upstream example{
    server 127.0.0.1:8080;
}

# NGINX Server Instance
server {
    listen 0.0.0.0:80;
    server_name example.com www.example.com;
    access_log /var/log/nginx/example.log;

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

    # Proxy to the Node instance
    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_pass http://example.com;
      proxy_redirect off;
    }
 }

Then you need to create a symbolic link to your config file inside your sites-enabled directory

cd /etc/nginx/sites-enabled/  
sudo ln -s /etc/nginx/sites-enabled/example.com example.com

reload nginx

service nginx reload

Setting up the Staging Environment

If you need to create a staging env using a subdomain like staging.example.com you need to go back to your Linode DNS Manager go into the example.com zone and add an A/AAAA Record with the hostname “staging”

Once done you need to create another configuration file inside /etc/nginx/sites-enabled

call it staging.example.com and follow the previous procedure to create a symbolic link.

The configuration file will be slightly different. Don’t forget to run Express on a different port.


# Node Express Staging on Port 3000
upstream staging{
    server 127.0.0.1:3000;
}

# NGINX Server Instance
server {
    listen 0.0.0.0:80;
    server_name staging.example.com;
    access_log /var/log/nginx/staging.example.log;

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

    # Proxy to the Node instance
    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_pass http://staging.example.com;
      proxy_redirect off;
    }
 }

Use PM2 to launch your Node Apps as a Daemon

Pm2 is really awesome and simple to use. In the past I tried Forever but I’m glad that there’s a better tool now. I use nodemon just for development.

Start a Node App with Pm2

pm2 start app.js -i max

Reload all apps

pm2 reload all

2 thoughts on “[CF-I] Configure your staging machine with Node.js and NGINX”

  1. Great article!

    I’ve never tried Linode, how does it compare to AWS?

    By the way, I’d be delighted to read about your approach to deployments (grunt over ssh? clone on server side?) and environment configuration (encrypted, ENV, something else?)

Comments are closed.