Node.js express application production deployment Node.js express application production deployment express express

Node.js express application production deployment


I have implemented production environments for several commercial applications on AWS, most recently using Node/Express/Mongo. Through lots of investigation, trial and error, and a bit of scripting I've settled on a configuration that works for me.

Below is a summary of the services/utilities I use. By design, everything is widely available and well documented so you should have no problem finding discussions on how to configure each to your specific requirements.

AWS Services

  • EC2 Security Group: primary firewall
  • ELB/Autoscaler (optional): load balancing; add/remove instances based on load; enable SSL
  • Cloudwatch: monitor instance availability
  • SNS: specify notification methods for Cloudwatch alarms (e-mail/sms)

OS/Utilities

  • Ubuntu: the most recent LTS version, currently 14.04; configured to do weekly automatic updates using cron/apt-get
  • nginx: reverse proxy to node process; 50x error handling; serve /public files; enable SSL if not using ELB
  • Upstart: start/stop app for maintenance; respawn app if it crashes (ala forever); start app on reboot
  • Monit: monitor node process for extended outages (handles upstart respawn failure); monitor filesystem free space; monitor mongo process

I use the standard apt-get versions of node, express, and npm with no special config settings. For deploying app updates, I have written a cron script that checks a github branch, so releasing a new version is triggered automatically by committing to that branch.

There are of course many more options and these are by no means the definitive ones.... in other words, YMMV. However, in my experience these are fairly easy to configure, work reliably, keep things running smoothly, and notify you quickly if/when problems come up that require your attention.


I think Tom's answer was great. In addition to that, some things to consider.

MongoDB on AWS

There are some things to further consider when you host your MongoDB instance. Firstly, you're likely using a pretty standard EBS volume, but for your production database its really important to reduce latency involve with EBS. Mongodb recommends getting EBS optimized instances, and using EBS volumes with provisioned IOPS.

Provisioned IOPS EBS volumes are typically prefered over Ephemeral storage, because when you destroy an instance with Ephemeral storage you lose that data. However EBS is separate from your instance, and provide various other features which can come in handy for managing your mongodb cluster. Though Ephemeral storage will likely be more performant, you should be aware of the potential for losing data if you delete that instance.

I had the great experience with working with the guys at MongoDB for a short period of time while working for a client of mine, and you should absolutely use MMS to manage/monitor your mongoDB instances. It's free, unless you want backups, so theres no reason not to. Monit may monitor your systems but it will not monitor or report the health of your mongoDB cluster.

Process Management

Upstart is a great way to maintain availability of your node. However, not everyone is good at writing upstart scripts. Many people write really minimal upstart scripts. As others recommend, PM2 is a great process manager. PM2 will allow hot-reloading your app on deployment, providing zero downtime deployments. But back to the subject, PM2 can start itself as a daemon, and PM2 persists your deployment therefore being able to give you the benefits provided by upstart/init.d and you don't have to worry about writing and testing your upstart script.

Some extra sugar is that PM2 provides its own REST api(optionally) and web interface for managing your instances(reload, restart, stop, load/mem/cpu, etc).

Edit:PM2 can only hot reload if you are clustering. You'll need at least 2 nodes on a host to use clustering, and you'll want a CPU for each node. This may not be in your favor, however you can still use PM2 to upstart your app.

Content Distribution and Static Assets

You may already know its best not to server static assets with node. This is typically where Nginx comes to the rescue. Nginx provides other benefits, as Tom stated in his answer(50x errors, SSL). Its worth noting that AWS offers CloudFront a Content Distribution Network. While you may not be able to get all of your static assets on to cloudfront, its worth storing larger and non-compressible files like images on cloudfront especially if you expect to have a large number of mobile users. This will just bring your content closer to your end user.

References:


I've recently created/installed a nodejs+express+mongodb webapplication using OpenShift and it's hosted at AWS. It's free and I'm only using two gears at the moment (Mongo + web). Haven't had to configure any virtual firewalls/zones like I would have if I'd spun them up directly at AWS EC2.

Seems to be working out for me so far and a lot less hassles than my work earlier mucking about in the AWS console.