After managing an extremely large scale NodeJs deployment last year. I learnt a great deal about production deployments with a focus on scalability. The retrospective summary of these learning points are in a presentation given last year: Top 7 Things Learnt Deploying NodeJs Servers at Scale.
Production deployments are about a whole lot more than scalability though, and we'll examine another aspect of them here: Managing multiple deployment environments.
What are deployment environments anyway? permalink
To get to a production deployment, you will need intermediate deployments, and to get to those intermediate deployments, you will need a local deployment.
Deployment environments are different computers where a project can run. Facilitating that, however, is tricky business!
Local deployment environment permalink
A local deployment is the one that a developer runs on their own computer, while writing code, debugging it, et cetera. A project would normally only need one of these.
Some typical names:
Intermediate deployments are those that are not customer facing, but are also not running on any developer's machines. Usually these are run on CI/ CD servers (or provisioned by them). A project would normally have several of these.
Some typical names:
Production deployment environment permalink
A production deployment is one that is customer facing, so an actual customer of your business is going to hit this service, meaning that any downtime could mean that your business loses money. Therefore the acceptable downtime is zero - or, practically, as close to zero as you can possibly manage. A project would normally have one of these.
Some typical names:
The categorisation above does not imply the value of the
NODE_ENV environment variable. Though the similar name might make it seem so, they are indeed different concepts. The value of
NODE_ENV determines the optimisation level under which the
node binary executes the code. Additionally, many NodeJs libraries also do their own optimisations based on the value of
Here are example profiles of an
express server running without
production, then with
Read the full article for a more in-depth explanation: The drastic effects of omitting NODE_ENV in your Express.js applications.
Therefore in the example above, we would want to have the
live deployment run with
NODE_ENV=production (no surprises here). Also, we might want the
loadtest deployments run with
NODE_ENV=production as well, because we want those performance optimisations in place, even though they fall into the category of intermediate deployments. Thus, we quickly see the value of keeping the concepts of what production means separate: When thinking about our deployment environments, versus when thinking about what the value of
NODE_ENV should be.
When you have a NodeJs project, more often than not, you will have several tasks that you do often enough, and the standard practice for these is to standardise them - especially important in a collaborative development scenarios such as open source, and in-house development teams.
npm, the de facto package manager for NodeJs projects, provides a handy way to do this via
npm run someTask, where
someTask is specified within
package.json, in the
This is quite handy for simple tasks - where there are no environment variables involved, and where the task is always the same no matter which deployment it is being run on. However, when a project approaches a certain level of complexity, some of its tasks will need to vary based on the deployment environment, and they will need to make use of environment variables. This is where
better-npm-run come in. They are NodeJs libraries that are designed to augment
npm run allowing you to overcome those two initial hurdles.
Additional hurdles permalink
As a project becomes even more complex, you might encounter some extra hurdles related to deployment in different environments.
Variable substitution permalink
- You might need to substitute the value of an environment variable into another one
- You might need to substitute the value of an environment variable into the command
Different configuration files permalink
- You might need to load different sets of configuration files based on the deployment environment
- You might need to run a completely different command for a particular task based on the environment
- For example
localhost might need to run a server via
nodemon, whereas the other environments might need to run the server via
- You might need to define environments hierarchically rather than as a flat list
- You might have ad-hoc environments that are spun up, created dynamically by CI/ CD
The name is a contraction of environment runner.
erun is an implementation that implements all of the requirements listed above - and was created to scratch the proverbial itch, after running into all of these scenarios.
Head over to the erun project page to check out sample usage.