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
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?)
Any thoughts about Cocaine the PaaS not drug 🙂