Logo

dev-resources.site

for different kinds of informations.

From dotenv to dotenvx: Next Generation Config Management

Published at
6/25/2024
Categories
dotenv
node
Author
dotenv
Categories
2 categories in total
dotenv
open
node
open
Author
6 person written this
dotenv
open
From dotenv to dotenvx: Next Generation Config Management

The day after July 4th πŸ‡ΊπŸ‡Έ, I wrote dotenv's first commit and released version 0.0.1 on npm. It looked like this.

In the 11 years since, it's become one of the most depended-upon packages worldwide 🌎 – adjacent ubiquitous software like TypeScript and ESLint.

It's an example of "big things have small beginnings". The README was short and the code was humble, but today it's beloved by millions of developers.

It's one of the few security tools that improve your security posture with minimal fuss.

  • a single line of code - require('dotenv').config()
  • a single file - .env
  • a single gitignore append - echo '.env' > .gitignore

It's aesthetic, it's effective, it's elegant.

But it's not without its problems! And that's what I want to talk about.

The problems with dotenv

In order of importance, there are three big problems with dotenv:

  1. leaking your .env file
  2. juggling multiple environments
  3. inconsistency across platforms

All three pose risks to security, and the first does SIGNIFICANTLY.

But I think we have a solution to all three today - with dotenvx. In reverse problem order:

Let's dig into each. I'll do my best to show rather than tell.

Run Anywhere

dotenvx works the same across every language, framework, and platform – inject your env at runtime with dotenvx run -- your-cmd.

$ echo "HELLO=World" > .env
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ node index.js
Hello undefined # without dotenvx

$ dotenvx run -- node index.js
Hello World # with dotenvx
> :-D
Enter fullscreen mode Exit fullscreen mode

The .env parsing engine, variable expansion, command substitution, and more work exactly the same. Install dotenvx via npm, brew, curl, docker, windows, and more.

This solves the problem of inconsistency across platforms. βœ… You'll get the exact same behavior for your python apps as your node apps as your rust apps.

Multiple Environments

Create a .env.production file and use -f to load it. It's straightforward, yet flexible.

$ echo "HELLO=production" > .env.production
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ dotenvx run -f .env.production -- node index.js
[dotenvx][info] loading env (1) from .env.production
Hello production
> ^^
Enter fullscreen mode Exit fullscreen mode

While everything in dotenvx is inspired by community suggestions, this multi-environment feature particularly is. There were suggestions many times for something similar before I came to understand its usefulness. I'm convinvced now it cleanly solves the problem of juggling multiple environments when built into the command line. βœ…

You can even compose multiple environments together with multiple -f flags.

$ echo "HELLO=local" > .env.local
$ echo "HELLO=World" > .env
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ dotenvx run -f .env.local -f .env -- node index.js
[dotenvx] injecting env (1) from .env.local, .env
Hello local
Enter fullscreen mode Exit fullscreen mode

Handy! But it's the next feature, encryption, that is the real game changer (and I think merits dotenvx as the next generation of configuration management).

Encryption

Add encryption to your .env files with a single command. Run dotenvx encrypt.

$ dotenvx encrypt
βœ” encrypted (.env)
Enter fullscreen mode Exit fullscreen mode
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/            public-key encryption for .env files          /
#/       [how it works](https://dotenvx.com/encryption)     /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY="03f8b376234c4f2f0445f392a12e80f3a84b4b0d1e0c3df85c494e45812653c22a"

# Database configuration
DB_HOST="encrypted:BNr24F4vW9CQ37LOXeRgOL6QlwtJfAoAVXtSdSfpicPDHtqo/Q2HekeCjAWrhxHy+VHAB3QTg4fk9VdIoncLIlu1NssFO6XQXN5fnIjXRmp5pAuw7xwqVXe/1lVukATjG0kXR4SHe45s4Tb6fEjs"
DB_PORT="encrypted:BOCHQLIOzrq42WE5zf431xIlLk4iRDn1/hjYBg5kkYLQnL9wV2zEsSyHKBfH3mQdv8w4+EhXiF4unXZi1nYqdjVp4/BbAr777ORjMzyE+3QN1ik1F2+W5DZHBF9Uwj69F4D7f8A="
DB_USER="encrypted:BP6jIRlnYo5LM6/n8GnOAeg4RJlPD6ZN/HkdMdWfgfbQBuZlo44idYzKApdy0znU3TSoF5rcppXIMkxFFuB6pS0U4HMG/jl46lPCswl3vLTQ7Gx5EMT6YwE6pfA88AM77/ebQZ6y0L5t"
DB_PASSWORD="encrypted:BMycwcycXFFJQHjbt1i1IBS7C31Fo73wFzPolFWwkla09SWGy3QU1rBvK0YwdQmbuJuztp9JhcNLuc0wUdlLZVHC4/E6q/K7oPULNPxC5K1LwW4YuX80Ngl6Oy13Twero864f2DXXTNb"
DB_NAME="encrypted:BGtVHZBbvHmX6J+J+xm+73SnUFpqd2AWOL6/mHe1SCqPgMAXqk8dbLgqmHiZSbw4D6VquaYtF9safGyucClAvGGMzgD7gdnXGB1YGGaPN7nTpJ4vE1nx8hi1bNtNCr5gEm7z+pdLq1IsH4vPSH4O7XBx"

# API Keys
API_KEY="encrypted:BD9paBaun2284WcqdFQZUlDKapPiuE/ruoLY7rINtQPXKWcfqI08vFAlCCmwBoJIvd2Nv3ACiSCA672wsKeJlFJTcRB6IRRJ+fPBuz2kvYlOiec7EzHTT8EVzSDydFun5R5ODfmN"
STRIPE_API_KEY="encrypted:BM6udWmFsPaBzlND0dFBv7R55JiaA+cZnbun8DaVNrEvO+8/k+lsXbZQ0bCPks8kUsdD2qrSp/tii0P8gVJ/gp+pdDuhdcJj91hxJ7nzSFf6h0ofRb38/2WHFhxg77XExxzui1s3w42Z"

# Logging
LOG_LEVEL="encrypted:BKmgv5E7/l1FnSaGWYWBPxxagdgN+KSEaB+va3PePjwEp7CqW6PlysrweZq49YTB5Fbc3UN/akLVn1RZ2AO4PyTVqgYYGBwerjpJiou9R2KluNV3T4j0bhsAkBochg3YpHcw3RX/"
Enter fullscreen mode Exit fullscreen mode

A DOTENV_PUBLIC_KEY (encryption key) and a DOTENV_PRIVATE_KEY (decryption key) are generated using the same public-key cryptography as Bitcoin.

Now, even if you leak your .env file, it's ok. An attacker needs the DOTENV_PRIVATE_KEY to make sense of things. This effectively solves the problem of leaking your .env file βœ….

Bonus: This approach additionally makes it possible for contributors to add config while simultaneously being unable to decrypt config. I anticipate this will be useful for open source projects where you want to allow for contribution of secrets without decryption of prior secrets.

1.0.0 Release

With that, we're pleased to announce the release of dotenvx version 1.0.0 πŸŽ‰.

It is the next generation of configuration management, and I'm looking forward to what you do with it. The next decade (like the last) is bright for dotenv! 🌟


If you enjoyed this post, please share dotenvx with friends or star it on GitHub to help spread the word.

dotenv Article's
30 articles in total
Favicon
Load Environment Variables using dotenv-local
Favicon
Hashicorp Vault Agent Tutorial: Generating .env from Vault Secrets
Favicon
Flutter Web | Build with .env File
Favicon
Learn .env in Express.js for Beginners (Effortless Setup)
Favicon
How to Hide Only API Keys Instead of Entire Files on GitHub and From Its Commit History
Favicon
Practical Introduction to Environment Variables Using Node.js
Favicon
From dotenv to dotenvx: Next Generation Config Management
Favicon
How to use `.env` file v:20.6.0 `dotenv` npm package do not use.
Favicon
Community Spotlight: David Cochrum
Favicon
Node.js 20.6.0 includes built-in support for .env files
Favicon
What is a .env.vault file
Favicon
Environment variables and configuration anti patterns in Node.js applications
Favicon
Dotenv: Python app environment variable vs. Linux environment variable
Favicon
Node.js includes built-in support for .env files
Favicon
How does python-dotenv simplify Configuration Management?
Favicon
Env::Dot
Favicon
How do you set up .env variables in your NextJS project ?
Favicon
Using ENV file in React & Webpack
Favicon
A simple trick for your dotenv files
Favicon
dotenv and typescript
Favicon
Environment variables & Its best practices
Favicon
Password Manage your environment and secrets with bitwarden
Favicon
5 reasons why your .env environment variables don't work
Favicon
Creating a DotEnv Loader in PHP
Favicon
NextJS - Get rid of DotENV
Favicon
Setting-up a Django project for production
Favicon
Stop using Dotenv in your front-end
Favicon
Supercharge your .env powered projects!
Favicon
Ways to load env variables for your script
Favicon
Doppler: The Triumph and Tragedy of .env Files

Featured ones: