Node.js production deployment with Nginx, Varnish, Upstart and Monit
In this post I’ll show You how to setup a production environment of a Node.js app with Nginx lightweight HTTP server and Varnish HTTP accelerator. We’ll also use Upstart and Monit to auto-start the Node.js server and make sure its running and git for code deployment.
In this example I’ll be using an Amazon EC2 instance, but it shouldn’t matter.
Nginx
Nginx is a lightweight HTTP server and revere-proxy, I’m using it in front of Node.js to utilize multiple Node.js processes and to server static assets and error pages.
Ubuntu installation:
sudo apt-get install nginx
create a new file under /etc/nginx/sites-available/myapp
First we define an upstream, which tells Nginx about our Node.js servers (If you have multiple servers just add all of them).
We define a redirection from myapp.com to www.myapp.com, keeping the original request URI.
Finally, We tell Nginx to handle HTTP error codes (the internal location means that the error page isn’t publicly accessible).
Then We tell Nginx to intercept any static assets (by directory and by extensions) and serve them directly. We also set the required headers and pass traffic to the upstream server we defined earlier.
As a final step We need to create a symbolic link from the file in /etc/nginx/sites-available to /etc/nginx/sites-enabled. Make sure that there are no other enabled sites with conflicting configuration.
Notice that We told Nginx to listen on port 8080
Restart Nginx:
sudo service nginx restart
Varnish
Varnish is a HTTP cache/accelerator, We’ll put it in front of Nginx to cache traffic.
Ubuntu installation:
sudo apt-add-repository ppa:varnish-software/sysadmin
sudo apt-get update
sudo apt-get install varnish
Edit /etc/default/varnish and tell Varnish to listen on port 80
Next edit /etc/varnish/default.vcl
What I’m doing here is telling Varnish about the Nginx server, in sub_recv making sure that static assets are always fetched from cache and in vcl_fetch stripping any cookies before static assets are inserted into cache (Varnish doesn’t cache requests with cookies by default).
restart Varnish
sudo service varnish restart
Upstart
We’ll useUpstart to demonize the Node.js process.
Create a new file under /etc/init/myapp.conf
Here We tell Upstart how to start our process, to respawn it if it dies and to auto-start on boot after the file systems and network interface are up.
Now We can start and stop our Node.js server
sudo start myapp
sudo stop myapp
Monit
We’ll use Monit to make sure the Node.js server hasn’t stopped responding and auto-restart it if it does.
Ubuntu installation:
sudo apt-get install monit
Edit /etc/monit/monitrc and uncomment the lines with set httpd.. use address localhost and allow localhost, We need those in order to use ‘monit status’.
Create a new file under /etc/monit/conf.d/myapp.conf
This tells Monit how to start and stop the Node.js server, How to check for a response and how often.
Restart Monit:
sudo service monit restart
Now everything should be working, the Node.js server is started on boot with Upstart and monitored with Monit. HTTP requests are handled with Nginx and cached with Varnish.
The final step is to setup an easy code deployment with git.
First step it to create a SSH shortcut, edit ~/.ssh/config on Your local machine.
Host ec2
Hostname myapp.com
IdentityFile ~/.ssh/mykey.pem
User ubuntu
ServerAliveInterval 30
ServerAliveCountMax 120
Make sure the shortcut is working by invoking `ssh ec2` and verify that everything is ok.
Next, create an empty git repository on Your server
cd /home/ubuntu
mkdir myapp.git
cd myapp.git
git init —bare
Add it as a remote repository to Your code
git remote add origin ssh://ec2/home/ubuntu/myapp.git
Now You’re ready to deploy new code
git push ec2
Finally, On Your server, create /home/ubuntu/myapp.git/hooks/post-receive and make sure its executable
This is pretty simple, It’ll install any dependencies and restart Node.js after each code deployment.
That’s it! Enjoy Your production ready configuration!
Blog comments powered by Disqus