What is dotenv
?
It's a javascript package that reads KEY=VALUE
from a .env
file (example below) and sets each pair as env variables.
// 1. Create a .env file:
DB_ADMIN_USERNAME=techbos
DB_ADMIN_PASSWORD=Pa$$w0rd
// 2. In your node app, load dotenv to read .env and set env variables when app starts
require('dotenv').config();
// 3. You can now use the env variables in your app
connectDatabase({
username: process.env.DB_ADMIN_USERNAME, //techbos
password: process.env.DB_ADMIN_PASSWORD, // Pa$$w0rd
});
Why should I use dotenv
?
dotenv
allows you to separate secrets from your source code. This is useful in a collaborative environment (e.g., work, or open source) where you may not want to share your database login credentials with other people. Instead, you can share the source code while allowing other people to create their own .env
file.
It's also useful for dynamically configure your app without changing the source code. For example, you can set DB_URL
to a dev database for local development. Or, if you want to print logs to console for local development, but not in prod, you can do:
// .env file
ENV=dev
// in your app
if (process.env.ENV === 'dev') console.log(...);
For real-world applications that are deployed to hundreds or even thousands of instances, using dotenv
(or use other similar tech) allows all instances to share the same source code, while each having a different .env
file so they can use different configurations, e.g., connecting to different databases or writing logs to different endpoints.
How to setup dotenv
in my project?
1. Preload dotenv
in node.js
Start your node app with dotenv
preloaded so you don't even need to require dotenv in your source code.
// use this
node -r dotenv/config index.js
// instead of
require('dotenv').config();
2. Add .env
to .gitignore
You should never share .env
file in source control. Instead, create a separate private repo to store your own .env
files, while sharing the rest of the source code with others.
//.gitignore
.env
3. Create as many .env
as you like
It's typical to have multiple .env
files. E.g., you may have one for dev, one for stage and one for prod. After you checkout the source code, copy over the .env
file for your environment and start the app.
3. Start your app
// E.g., use with babel-node for local development
nodemon --exec babel-node -r node_modules/dotenv/config src/index.js
// E.g., run with node in production
node -r dotenv/config src/index.js
4. Run in docker
// Dockerfile
CMD node -r dotenv/config ./build/index.js
Use dotenv-safe
A good alternative to dotenv
is dotenv-safe
, which is identical to dotenv
except that it allows you to create a .env.example
file. This serves two purposes:
- It allows you to specify all required env variables in the example file. At runtime the package checks if a
.env
file has all the required variables defined, and throws if not. - You can share the
.env.example
file with others so everyone knows what env variables are required.
Use in Docker
In some cases, building the .env
file into a docker image is considered a bad practice because if the image is shared with others, the secrets can be leaked.
To fix that, you can map a .env
file into docker at runtime:
volumes:
- /local/file/path/to/.env:/app/.env
Another approach is to use the env_file
docker option. You can read more here
Top comments (3)
Brilliant. Again!
Thank you very much. The .env volume mapping helped to solve the issue I was facing.
In addition to using environment variables I can recommend the tool github.com/dotenv-linter/dotenv-li....
It’s a lightning-fast linter for .env files. Written in Rust.