Load ENV vars with dotenv before node-config
Asked Answered
P

2

6

I want to load environment variables into the general config of my Express app. Locally I work with a .env file, but when deploying, I'll inject the env vars into the docker container.

So, I've got a default.json with some hard-coded config values. Then I've got the custom-environment-variables.json file like so:

  "app": {
    "nodeEnv": "NODE_ENV",
    "port": "PORT",
    "hostname": "HOSTNAME"
  }
  "mongoDb": {
    "connectionString": "MONGODB_CONNECTION_STRING"
  },
  "redis": {
    "connectionString": "REDIS_CONNECTION_STRING"
  },
  "logDna": {
    "key": "LOGDNA_KEY"
  }

and a .env file within the root dir of my project.

In server initiating file I've got:

import * as dotenv from 'dotenv';
dotenv.config();
import * as config from 'config';

console.log(process.env);
console.log(config);

I also tried placing them in a normal order:

import * as config from 'config';
import * as dotenv from 'dotenv';

dotenv.config();

Another thing I tried is to separate the app declaration from the services init and app start. Like so in app.ts:

import * as App from 'express';
import * as dotenv from 'dotenv';

dotenv.config();
console.log(process.env);

const app = new App();
export app;

And then in index.ts:

import app from './app';
import * as config from 'config';

console.log(config);

// app.use() and other inits
app.listen(...);

But to no avail. The .env file is loaded, I can see the vars in process.env, but they do not get loaded by the config in custom-environment-variables.json. F.e. the nodeEnv, port and hostname variables are loaded. But they are loaded into the container before the application is started.

This brings me to the thought that the config loads before the dotenv module manages to load the values from the .env file. Essentially, it seems like the problem will only be existent in DEV env, since it's the only place I'll be loading environment variables from .env file. For any other environment, they'll be present in the container environment before the app even starts.

Can I maybe force re-load config?

Any suggestions how to achieve that?

Popper answered 18/11, 2019 at 9:30 Comment(2)
dotenv will only expose those variables on process.env and will not inject them onto other modules irrespective of the order. Ideally dotenv.config(); should be as soon as the app starts. What do you want to achieve from config module (but they do not get loaded by the config in custom-environment-variables.json) ..what does config doPortative
@Portative config env vars Basically, it finds environment variables with the same name as the ones I've declared in my config files and loads their values.Popper
P
4

Eventually I settled for external loading of the local env vars, alongside the node process startup:

node --require=dotenv/config src/index.js

inspiration from here.

Popper answered 18/11, 2019 at 14:51 Comment(0)
S
1

If you're using Typescript then you should open the file that is the entry point for the app, create a new file where the dotenv commands are ran at the top level, not inside any function, and import it to the main file.

Example:

// index.ts

import './load-env';

// Rest of your imports & code...
// load-env.ts

import * as dotenv from 'dotenv';

dotenv.config(); // Runs before any const declarations in any other file

If your editor keeps reordering your imports, you can rename the load-env file into something that is higher alphabetically, such as a-load-env.ts.

Scarfskin answered 2/10, 2023 at 5:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.