Use dotenvx with Nx
Use dotenvx with Nx
Find code examples for this guide on GitHub.
Initial setup
Create a new monorepo.
npx create-nx-workspace --preset=express
This will create a handful of files and a couple workspaces (apps).
$ ls -1
README.md
apps/
jest.config.ts
jest.preset.js
node_modules/
nx.json
package-lock.json
package.json
tsconfig.base.json
Edit apps/app/src/main.ts
to include process.env.HELLO
– to say 'Hello World'.
apps/app/src/main.ts
import express from 'express';
import * as path from 'path';
const app = express();
app.use('/assets', express.static(path.join(__dirname, 'assets')));
app.get('/', (req, res) => {
res.send(`Hello ${process.env.HELLO}`);
});
const port = process.env.PORT || 3333;
const server = app.listen(port, () => {
console.log(`Listening at http://localhost:${port}/`);
});
server.on('error', console.error);
Run dotenvx
Install dotenvx
.
brew install dotenvx/brew/dotenvx
see other installation options
Create a .env
file under apps/app
.
apps/app/.env
# apps/app/.env
HELLO="World"
Run nx serve
prefaced by dotenvx
.
$ dotenvx run --env-file=apps/app/.env -- npx nx serve app
[[email protected]] injecting env (1) from apps/app/.env
> nx run app:serve:development
...
Visit localhost:3333.
Your app will say Hello World
. The values from your .env
file were successfully injected into your env.
Add production environment
Create a .env.production
file under apps/app
.
apps/app/.env.production
# apps/app/.env.production
HELLO="production"
Modify your dotenvx run
command to use the .env.production
file.
$ dotenvx run --env-file=apps/app/.env.production -- npx nx serve app
[[email protected]] injecting env (1) from apps/app/.env.production
> nx run app:serve:development
...
Your app will say Hello production
, simulating production. Solid. Let's encrypt your secrets next.
Encrypt secrets
Use dotenvx
to encrypt your apps/app
secrets.
dotenvx encrypt apps/app
Also run
dotenvx gitignore
to make sure your.env.keys
file is gitignoreddotenvx gitnore
This generates a .env.vault
and .env.keys
file.
.env.vault
#/-------------------.env.vault---------------------/
#/ cloud-agnostic vaulting standard /
#/ [how it works](https://dotenv.org/env-vault) /
#/--------------------------------------------------/
# development
DOTENV_VAULT_DEVELOPMENT="V4NYVn0Pow6Uf2ez2mbHEzTrYURloHL6VDAFRLqnQBppA/OmHI5x5AXoxCMVor7wOg=="
# production
DOTENV_VAULT_PRODUCTION="YZkhtbh1IlzBgIamAAsG5nzGPfH6p8Zbuj9egXoziviVu/eYIyNjJWtIYyhiW/vHhFbqbsvo5+P9b27OC6ZC7qU="
The .env.vault
file contains encrypted (AES-256-GCM) versions of your secrets, and the .env.keys
file contains the decryption keys.
.env.keys
#/!!!!!!!!!!!!!!!!!!!.env.keys!!!!!!!!!!!!!!!!!!!!!!/
#/ DOTENV_KEYs. DO NOT commit to source control /
#/ [how it works](https://dotenv.org/env-keys) /
#/--------------------------------------------------/
DOTENV_KEY_DEVELOPMENT="dotenv://:key_e507c60efa8841d8d5bbb85bd701ee92406cf3b06506d1d80f1553c2a72791e4@dotenvx.com/vault/.env.vault?environment=development"
DOTENV_KEY_PRODUCTION="dotenv://:key_10283719af6a30ef49050048617f4fea10c23a38021fbebeb9fd858caa01852e@dotenvx.com/vault/.env.vault?environment=production"
You SHOULD commit .env.vault
to code. It is safe and recommended to do so. But DO NOT commit .env.keys
to code. Keep them somewhere safe like 1Password or dotenvx hub.
We're ready to simulate production by using the DOTENV_KEY
.
Set DOTENV_KEY
Set DOTENV_KEY
using the production key in your .env.keys
file.
DOTENV_KEY='dotenv://:key_10283719af6a30ef49050048617f4fea10c23a38021fbebeb9fd858caa01852e@dotenvx.com/vault/.env.vault?environment=production' npx nx serve app
Your script starts and env
is successfully injected using the encrypted contents of .env.vault
.
[[email protected]][INFO] Loading env from encrypted .env.vault
Listening at http://localhost:3333/
You will also see a noisy output like [[email protected]][WARN] You set DOTENV_KEY but you are missing a .env.vault...
. You can safely ignore these. It is a result of how nx traverses .env*
files using dotenvx
.
Visit your url and it says Hello production
.
You succesfully used the new .env.vault
standard to encrypt and deploy your secrets. This is much safer than scattering your secrets across multiple third-party platforms and tools. Whenever you need to add or change a secret, just re-encrypt .env.vault
and redeploy.
Great job! That's pretty much it. See the bonus section(s) below to go a little deeper.
Bonus
Try changing the value of .env.production
to your name.
apps/app/.env.production
# apps/app/.env.production
HELLO="Mot"
Re-encrypt it.
dotenvx encrypt apps/app
Commit .env.vault
safely to code and re-serve the app.