node.jsexpressenvironment-variablesdotenvnode-config

Load ENV vars with dotenv before node-config


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?


Solution

  • 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.