Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nestjs configuration with dotenv

Referring to official NestJS documentation, it is recommended to use ConfigService in order to use environment variables.

So in the code, we access all vars defined in an .env file with something like:

config.get('PORT')

But it is not recommended to use .env in production environment. So how to deploy in that way?

Why not just use the standard method with dotenv and process.env.PORT?

like image 535
Fairydhwen Avatar asked Aug 07 '18 08:08

Fairydhwen


2 Answers

There are two problems that make the ConfigService less useful.

First

When no .env file is present in any environment, readFileSync in

dotenv.parse(fs.readFileSync(filePath))

will fail:

[Nest] 63403 [ExceptionHandler] path must be a string or Buffer
TypeError: path must be a string or Buffer
    at Object.fs.openSync (fs.js:646:18)
    at Object.fs.readFileSync (fs.js:551:33)
    at new ConfigService (../config/config.service.ts:8:38)

Even if e.g. process.env.API_KEY is available

this.configService.get('API_KEY')

will not return anything. So the ConfigService forces you to use a prod.env file, which dotenv advocates against:

No. We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. Your config should vary between deploys, and you should not be sharing values between environments.

https://github.com/motdotla/dotenv#should-i-have-multiple-env-files

Second

You have to import the config module and inject the service in order to use it. When you use env variables like this

imports: [
  MongooseModule.forRoot(process.env.MONGO_URI, { useNewUrlParser: true }),
  ConfigModule,
],

the config service is useless.

Read more about config in the environment here: https://12factor.net/config

like image 144
UpCat Avatar answered Nov 15 '22 11:11

UpCat


But this is not recommended to use .env in production environnement. So how to deploy that way ?

Actually, it is not recommended to commit your .env files. It's perfectly fine to use them in production :-).

Why not use the standard method with dotenv and process.env.PORT?

It allows decoupling your core code from the code responsible for providing configuration data. Thus:

  • The core code is easier to test: doing some manual changes/mocking of process.env is such - a - pain, whereas mocking a "ConfigService" is pretty easy
  • You can imagine using anything else than environment variables in the future by just replacing a single method (or a few getters) in a dedicated class, instead of replacing all the occurrences of process.env.* in your code // to be fair, this is unlikely to happen, as using env. variables is the most common way to load configuration data, but still.
like image 28
VinceOPS Avatar answered Nov 15 '22 13:11

VinceOPS