node.jsexpress

Node js express project how to add environment variables


I am a java script full stack developer. In the vue js I create two files in the root.

  1. env.development
  2. env.production

In my main.js file, I can access environment variables like this

process.env.VUE_APP_MY_VARIABLE_X

How production and development differs in the vue js is, if I use npm run serve project loaded the development environment variables. If I use npm run build it takes production environment variables. That's all in vue.

But in my expressjs project,

"start": "nodemon server.js --exec babel-node -e js",

This command will always responsible for the run project. I couldn't find two commands like in vue. I go though the tutorials every body says use the package called dotenv.

I couldn't figure out that how could this package identify the environments this is production and this is development.

End of the day I want to set my db password to 123456 in my local machine and root@123456 in the server. How could I achieve this?


Solution

  • Vue.js handles modes automatically, depending on the command (e.g. serve sets NODE_ENV=development, while build sets NODE_ENV=production). Depending on the mode, it also automatically loads files with variables from disk.

    Environment variables in Node.JS

    However, Node.JS does not do that by default, and you have to set up your application to handle environment variables.

    In Node.JS you can pass variables via the shell command, for example: MY_VARIABLE=x node myapp.js (by prepending the command with variables), and that will give you process.env.MY_VARIABLE inside your myapp.js application. Following this behavior, there's a consensus on using NODE_ENV variable for setting up the environment mode. For production use, you'd start your application using NODE_ENV=production node myapp.js, while for development NODE_ENV=development node myapp.js. Of course, if your machine already has these environment variables set up (for instance in .bash_profile) you do not need to prepend your command with them.

    As a practice, in development machines, you'd have these variables already set up on your machine, while production machines (e.g. docker containers, etc) start clean and you pass the environment variables when starting your application. For example, Heroku (and other deployment services) allow you to set up environment variables which are set at machine start.

    There's also the method of storing variables in files (such as the .env, or other files), but those you'd have to read from disk when your application starts. And this is where dotenv (and config package) come in play. What dotenv does, is it reads .env file stored in your application execution path (root of the app), and sets any variables defined there into process.env for Node.JS to use. This is extremely useful for development machines, but on production it's recommended to not have files that store sensitive information in variables, but rather use system environment variables. There is also the option, for production machines, to construct or load into the machine an .env file at machine setup time, into the app directory.

    Note:

    The dotenv approach

    The best way to go about it, would be to use dotenv, and have different .env files, one on your development machine, and a different one on your production machine. That way, when your application starts, it reads the variables that are stored in the adjacent .env. This is the most secure and reliable way, in absence of means to pass environment variables to your production machine from a machine management application/interface.

    The easiest way to set up your app with dotenv would be to set your start command to something like:

    "start": "nodemon --exec \"node -r dotenv/config\" server.js"
    

    and then in the .env file stored on your local/development machine you'd have something similar to:

    DATABASE_PASSWORD=1235
    DATABASE_USERNAME=joe-dev
    ...
    

    and in the .env file on your production machine (server):

    DATABASE_PASSWORD=root@1235
    DATABASE_USERNAME=root
    ...