Setting Up Custom Environment Variables Using dotenv and Node-config
Tags: javascript, node
Published: 2021-01-22 19:32:54

## The Problem
Mistakes are a great way to learn. Working on [Brad Traversy's MERN Front to Back course](https://www.udemy.com/course/mern-stack-front-to-back/), I wanted to 'green up' my git contributions graph so I decided I would commit after completing each lesson. 

Since it was a tutorial I wasn't worried about any consequences. Shortly after I got an email from a service called GitGuardian about the vulnerability of exposing my database password inside my MongoDB URI because I committed it to GitHub. Now the login credentials are exposed to the world.

I wasn't worried about it because it's a junk database, and believed I would learn how to protect keys and passwords along the journey. It's still important to practice as if it's the real thing.

So as part of good practice, I threw the situation out on Slack for comment by the local [Orlando DEVS](https://orlandodevs.com/) community.

Some documentation searching later, I was led to the solution.

## The Solution
The solution was to store the user database password in an environment variable. For the MERN course, `config` was already being used provide access to the URI, but it uses a `config/default.json` file. Being a JSON file meant that I couldn't access `process.env` because it's a data interchange format and not a file for storing code instructions.

Now onto how it's done.

### Set up dotenv
If you don't have `dotenv` installed, you can [get it here](https://www.npmjs.com/package/dotenv). 

If you want to only require `dotenv` on local setups then you need to encapsulate the require function inside a conditional that checks if your app is not in production mode.

For me this was done within `server.js`.
![carbon](https://dev-to-uploads.s3.amazonaws.com/i/sf2tjq3u7z9iulikrwwo.png)

### Add the environment variable
When I had used environment variables before I was interpolating them inside a url on the front-end. This time I pasted the entire thing, a database URI in this case, inside the `.env` file.

![carbon (1)](https://dev-to-uploads.s3.amazonaws.com/i/a5f5c9ut7g5yvj5caf2f.png)

#### Note
*As I'm writing this I have yet to complete the course. I was curious about how Brad approaches keeping these environment variables from making it into the build (I know this happens in React).* 

*After skipping ahead in the course, it turns out he creates a separate `config/production.json` for production including a separate database (though I think he skips that for the course). Plus deployment is to Heroku, so I'm sure I'll have the opportunity to learn how that plays into keep these sensitive variables a secret.*

### Prevent .env from being committed
Last step here is to add `.env` to `.gitignore`.
 
### Set up config
If you need it, grab `config` [here](https://www.npmjs.com/package/config).

For the MERN course it's instructed to have a `config/default.json` where the MongoDB URI is stored. With the problem of not being able to access `process.env` inside it, that led me to custom environment variables via `config`.

### Create custom config

Create a `custom-environment-variables.json` file inside the `config` folder. Paste the variable as a string into the JSON value field for the key. Then you'll be able to access it from your code via `const db = config.get('mongoURI');`

```
{
    "mongoURI": "DB_ACCESS_KYLE123"
}
```

Note: Custom environment variables take precedence over all other configuration files and will overwrite them. Only command line options can take top precedence.

Hopefully this has been helpful to you in either working with the MERN course or in your own personal or company project.

Thanks for reading!
> [www.kylewcode.com](https://www.kylewcode.com)
> [Reach out to me on Twitter @kylewcode](https://twitter.com/kylewcode)