Per-Environment Configuration
It’s a well-established practice to supply credentials and environment-specific configuration to a web app via environment variables.
By “environment-specific”, I mean specific to a particular instance of the running web app. That could be the web app running on its production server or the web app running on a developer’s laptop.
For Node.js applications, the most common implementations I’ve seen are:
- Literally using environment variables — usually when deploying to a cloud provider or when running in a Docker container
- Using a config file that gets automatically translated into environment variables — e.g. via the dotenv tool.
For providing configuration during development on my laptop, I’ve found a config file to be the easiest way.
Recently, I’ve started building a web app, and I needed an easy way to provide an SSL certificate to my code. I naturally reached for dotenv. But, to my surprise, there was no easy way to provide strings with multiple lines.
dotenv has its own homegrown configuration format that looks like:
NAME=value
OTHER_NAME=value
It resembles BASH, but in reality, only supports simple string keys and string values, with augmentations nailed on over time.
I got to thinking about prior art for configuration files:
- *nix packages always seem to use fully-featured config formats — many look like TOML.
- Node.js and npm use JSON.
- Rails, and many cloud providers use YAML.
I realized that a minimal KEY=VALUE
syntax is just not good enough. And, neither is, for that matter, JSON, because it’s lacking that first layer of make-my-life-easier features (like multi-line strings or variables.)
So, I set out to implement as YAML version of dotenv: