-
Notifications
You must be signed in to change notification settings - Fork 6
How it works
- General concept
- Basic environment variables and Node
- How dotenv helps
- What you get with dotenv
- Building on dotenv
Here we'll talk about how NestJSConfigManager interacts with the environment. While you control the details of this with a schema and module configuration options, the basic mechanics are built into the module.
Loosely speaking, when your app starts, node
reads the environment and loads it into a hash
that is available
to your app at process.env
. If you dump process.env
, you'll see something like this:
{
LESSOPEN: '| /usr/bin/lesspipe %s',
npm_package_dependencies__nestjs_platform_express: '^6.0.0',
npm_package_devDependencies__types_node: '^10.12.18',
npm_package_devDependencies__types_supertest: '^2.0.7',
npm_package_devDependencies_ts_node: '8.1.0',
MAIL: '/var/mail/john',
USER: 'john',
npm_package_scripts_start_prod: 'node dist/main.js',
npm_package_dependencies_rxjs: '^6.3.3',
HOME: '/home/john',
npm_config_editor: 'vi',
npm_config_timing: '',
LANG: 'en_US.UTF-8',
PWD: '/home/john/',
INIT_CWD: '/home/john/code',
DB_USERNAME: 'john',
DB_PASSWORD: 'mypassword',
DB_NAME: 'mydb'
}
dotenv
provides what I call a shim on the environment. If you want to create environment variables that are
visible inside node, you typically define them in the environment itself:
linux example
export MY_NAME=John
Windows example
set MYNAME=John
This can be a nuisance because:
- environment variables are ephemeral -- they go away when you reboot or open a
new shell/terminal window (unless you make them permanent with something like
a
.bashrc
file, which makes it harder to toggle them with ease) - what if you want to have different environment variable values in development, stage, test, etc.?
dotenv
solves this problem. Instead of using the external environment system shown above, you create a .env
file with these values. To add new environment variables, just add a new value to the file. To have different environment variables on different platforms, just create new .env
files.
// /project/config/development.env
DB_PASS=secret
DB_NAME=mydb
...
Using dotenv
, when you read process.env
, dotenv
will fill in any missing environment variables. There's a sort of "cascade" going on:
Note that dotenv
will never override an environment variable that is present in the actual external environment. In the example above, DB_PASS
appears both in the external environment and in the .env
file. What's visible after dotenv
processes the
environment is the value from the external environment.
NestJSConfigManager builds on top of dotenv
by:
- Making it easy to dynamically locate the actual
.env
file (which can be named anything you want) - Providing a convenient way to validate environment variable values
- Allowing you to make variables required or optional. Optional values (
required
set tofalse
) must have a default value.
We discuss dynamic file location determination in Module Configuration Options.
We discuss validation in Schemas.
We also discuss the required
setting in Schemas, which has an effect
on the cascade. If you read that section now, you'll see a variation on the
diagram shown above that illustrates handling optional environment variables
with default values.