How often have you heard “Well, it worked on dev and stage!” when things crash on prod? Hopefully, this post will change all that.
Here are nine tips on deploying scalable Node.js applications into production.
Get your deployment architecture right
A typical deployment might look like (simplified)
Use a reverse proxy
Don’t expose your Node.js app server directly to incoming HTTP traffic. Always put a reverse proxy in front of it to handle concerns like
- SSL termination
- Serving static content
- Caching slow changing parts of site
- Gzip compression and more
Popular alternatives are Nginx and Apache. Of late, we have been using Nginx for all our applications with good results. Remember to proxy your web socket traffic also.
Deploy a cluster
Node.js event loop is single threaded, though it has additional threads for handling file and network events. This architecture restricts each instance to one logical CPU core.
So, deploy a cluster of Node.js app servers to maximize usage of multicore systems and also high availability.
There are multiple options for this, such as PM2 and StrongLoop Cluster Management. We usually end up using StrongLoop’s cluster solutions, because many of our applications are built on Loopback API and also it has nice features like options to run as background process (detached), clustered (with options of specifying number of CPU cores), non-profiled, profiled, with Log aggregation and routing options, with ability to send PIDs to file for history tracking.
Setup a load balancer
No matter how much you tune a single instance Node.js app server, it can only handle so much traffic. For horizontal scaling, setup a load balancer like HAProxy or Nginx.
Since StrongLoop Process Manager integrates with Nginx Controller, we always use Nginx as the load balancer.
One thing to consider while load balancing is whether your application is sticky sessions. Nginx pl3us supports sticky sessions. Or you can use tokens and move your session to a shared store like Redis. In general, for high-performance applications, it is not good to have sticky sessions.
Setup automatic restart of Node.js processes using something like StrongLoop PM or Forever. Also, to make sure things restart on server restart, add it to init.d also.
Monitor and collect metrics
If you have the budget, use commercial APM solutions like AppDynamics to monitor and collect metrics on your production setup.
Alternatively, you can hook up StrongLoop PM to Graphite to achieve a degree of this.
Node.js has a rich plugin ecosystem. Developers might inadvertently include a plugin that is not secure. Make sure your team maintains a private NPM repository of whitelisted which includes only plugins that go through review process.
Tools like the Node Security Platform or Snyk can help in this by using exploit databases to find and fix possible security issues in your application.
Make sure your application uses an asynchronous performance logger like Winston or Bunyan
Define your infrastructure as code using something like LambdaCD and automate everything including environment specific configuration.
Have any Node.js hacks, tips or tricks to add? Let us know!