If you're one of those critical readers, you might be asking yourself: what the hell is [CF-I]. Well, I'm a 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 weface daily in the backend world.
If you want to cut the crap and skip the brief explanation you can find my NGINX Config files on this Github repository.
PaaS & SaaS
Telling a control freak to use Heroku for instance will kinda limit and demotivate him. That’s why I hate using any Platform or Software as a Service. My friends tried to convince me otherwise using the following args:
” Dude, 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, anyways the dominating variable in our matrix nowadays is speed
I remember a Goblin from World of Warcraft saying “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 boost your knowledge in understanding and dealing with complex systems. At the end of the day, that’s what really matters. The currency of the Universe is Knowledge.
Ah! Take me back to programming!
Node.JS & NGINX
NGINX is way faster at serving static content than Node.JS, combine them and you’ll minimise the traffic that hit your Node process therefore you’ll get a decent and scalable web application that can really scale beyond the good ol’ Web Servers like Apache and let’s 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

Good day very nice web site!! Man .. Beautiful .. Amazing .. I will bookmark your site and take the feeds additionally?I am satisfied to find so many useful info here within the post, we’d like work out more strategies on this regard, thank you for sharing. . . . . .
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?)
Um, why are your sites-available/sites-enabled symlinks going in the reverse direction as most of the rest of the world? Is that some buck-the-trend control freak thing?
Same results, you gotta a point tho by default it’s in reverse…
Why not to start Node server on socket instead of port? For me it is more clear and transparent
Any thoughts about Cocaine the PaaS not drug 🙂