Naming convention for environment variables files? - node.js

I was just wondering if there was any standardized convention for .env environment variable files. If I had multiple setups (e.g. development, staging, production), what should they be titled?
I've seen:
.env.development, ...
development.env, ...
settings.development.env, ...
.env, .env.staging, .env.production, ...
If there isn't a standard, are there arguments for which to use (kinda like "" vs '' for strings in JS)? Which do you use and why?

I prefer .env at the end ex: .production.env because last word after . indicates extension. VSCode does not recognize the file as .env file if you do .env.production
VSCode Documentation:
https://code.visualstudio.com/docs/python/environments#_environment-variables

There is only one standard in node ecosystem - use production in NODE_ENV variable for production. It's used by different tools for optimizing.
The rest is on you. But personally, I don't see reasons to make it complex. If you need to differentiate instances further than just production, development, you can use other environment variables.
Also you need to be careful when using different NODE_ENV for staging and production. Because the main purpose of staging is to test everything as close to production as possible. So changing NODE_ENV can be a reason to production fail.

I'm using this convention since I can't find any other suggestions: https://rubyonjets.com/docs/env-files/
.env
.env.development
.env.test
.env.production
I like maintaining the .env at the front and this seems reasonable to me.

Related

Deploy Dockerized NodeJS application with the respective .env files

I am working on a NodeJS application which is a containerized application. I use Jenkins to build and deploy it. I have an environment .env file and along with this, also have .env files based on environments.
For example: .env.DEV, .env.SQA, .env.STG and .env.PROD.
Each file has different values for the variables based on environments.
When I am deploying my application, it always fetches variables from the .env file instead of specific environment file i.e. .env.DEV (if deploying on DEV server).
How do we use specific environment file while doing the deployment on Jenkins?
Note - I followed this great content on dotenv library but I didn't find anything helpful for my use-case. I even Googled a lot but didn't find much on this. Any help would be greatly appreciated.
You can use dotenv-flow which does exactly this, given the value of NODE_ENV environment value it will load the expected environment.
You also will need to make sure that the container receives the proper environment values from jenkins, this might help.

How can I deploy firebase function as 'NODE_ENV = development'

I'm developing an application with my team with Firebase, and I want to deploy my app both in development and production environments.
To achieve this, I have done several things. (Details are below)
But NODE_ENV keeps set as 'development' when I deploy it to firebase functions app.
How can I deploy it as 'development' to firebase?
Those are what I have done to achieve my goal.
Make another firebase project and function for 'production' (Use current firebase project as 'development')
firebase console
Edit .firebaserc file and set aliases for my projects (to use firebase --use command)
.firebaserc
Separate RDS Instance and Slack Monitoring app
Separate .env files with .env.dev and .env.prod and use secrets based on NODE_ENV
set .env files
Add 'dev' script to package.json to deploy as 'NODE_ENV = development'
package.json scripts
This is the code I wrote to find out is which environment my server is running
node_env console.log
And this is from my github actions log and firebase console log
github actions and firebase console log
When I run my app in local with 'serve' command, console.log prints 'development' as I expected.
I guess 'firebase deploy' command automatically changes my NODE_ENV to production when it is deployed.
Or did I make some mistakes to do this?
The recommended way to have a development and production environment is to have two separate Firebase projects, which you are already making use of. For the sake of an example, let's assume you have hyositive-app as your production project and hyositive-dev as your development project.
Defining Deployed Environment Variables
Use of environment variables with Cloud Functions for Firebase are based on .env files compatible with the dotenv package. By default, the following files are supported (ignoring others!):
Name                             
Purpose
.env
Environment variables common to all environments
.env.<projectID>
Environment variables used when deployed to the named project (e.g. .env.hyositive-app)
.env.<alias>
Environment variables used when deployed to the aliased project (e.g. .env.dev).Note: default is the only alias configured out of the box. dev/prod/etc. are not defined.
.env.local
Environment variables used when using emulating functions on your system using the Cloud Functions emulator.
To use .env.dev and .env.prod, you will need to define them as project aliases in your .firebaserc file (or you can continue using development and production aliases and just update the filenames to match):
{
"projects": {
"default": "hyositive-dev",
"dev": "hyositive-dev",
"prod": "hyositive-app"
}
}
This then allows you to use .env.dev and .env.prod instead of .env.hyositive-dev and .env.hyositive-app respectively.
Using Environment Variables
The Cloud Functions runtime (the process that runs your deployed code) defines a number of built-in environment variables that have various purposes (such as allowing you to use initializeApp() with no arguments).
In addition to these variables, a handful of language-specific variables are also defined by the runtime to aid in painless deployment of code. However, the Cloud Functions documentation states to not rely on their values unless you set the values yourself.
The Node.js Cloud Functions runtime is built using the Cloud Functions Framework (however, it is not guaranteed to perfectly match this open source version). Because this runtime executes using Node.js and makes use of other packages such as express, it sets NODE_ENV to production, to minimise unexpected behaviour that depends on its value. But as mentioned above, this behaviour should not be relied on even though it is unlikely to change.
To override NODE_ENV to development, you would add it into .env.dev, .env.hyositive-dev and/or .env.local (as appropriate). Similarly, you should also define NODE_ENV as production in .env.prod or .env.hyositive-app (as appropriate).
Rather than rely on NODE_ENV, I would recommend defining behaviour around another variable that you have complete control over (such as HYOSITIVE_ENV) or compare against the executing project ID to determine whether it is running in the production project or not.
const PROD_PROJECT_ID = "hyositive-app",
// DEV_PROJECT_ID = "hyositive-dev",
PROJECT_ID = JSON.parse(process.env.FIREBASE_CONFIG).projectId,
isProduction = PROJECT_ID === PROD_PROJECT_ID;
Note: This other thread may have some useful background information.

Node-config: How to pick environment specific config file

In our Node.JS application, we have been specifying application environments (dev, qa, stage, prod, etc.) in package.json as below:
"start-prod": "NODE_ENV=prod node ./bin/www",
"start-qa": "NODE_ENV=qa node ./bin/www"
etc.
However, we have realized recently that using NODE_ENV in this manner to specify app environments is not a good practice. So, I am trying to use the npm package node-config
for this purpose as well as for loading environment-specific configuration which is currently coming from AWS Parameter Store since there seem multiple advantages of using overriding config files over repeated configuration in AWS Parameter Store.
Therefore, I have created different config.json files, e.g., dev.config.json, qa.config.json, etc. But I am not sure how to specify/read the environment (qa, dev, stage, prod, etc.) and load configuration from the corresponding config.json file.
It may be a very stupid question but I am not able to find a good implementation example for node-config. Any help will be highly appreciated.
As documented on the node-config wiki, you can create:
default.js
prod.js
dev.js
qa.js

Is using dotenv necessary if environment variables already declared with Docker

If I have declared a port variable or anything in the Dockerfile of a nodejs project as ENV PORT=8080. Is it still necessary or maybe best practice to use the dotenv package to load the environment variables as require('dotenv').config()?
Most of the Node.js applications relies heavily on environment variables.
It is a common thing to load these variables from a .env file with your mentioned library, however this is only a good practice and not a strict rule.

Environment Variables in App Engine for local dev

What's the best way to set environment variables when developing nodejs on a local machine for App Engine Flex environment? If they're set in app.yaml then they don't get set during local development. Is there a way to force this, or should I use something like dotenv and keep track of the same environment variables in 2 places?
Sensitive data (e.g. API Keys) should not be committed to source code.
The way I went around that is storing a .env file in Google Storage. Then you can use #google-cloud/storage to download it in production (using a prestart hook) and dotenv to load variables into memory.
You may find a full guide here: http://gunargessner.com/gcloud-env-vars/
PS: I would go for Aidan's answer for storing any data that is not sensitive. I have myself used dotenv satisfactorily in the past.
Similar to that, there's nconf, the package that gcloud itself uses for examples. Pretty neat!
Option 1:
require('dotenv').config({path: '/custom/project/root/app.yaml'})
Option 2:
Maintain both a .env file and a .yaml file with the same keys but different values (local and GAE, respectively). In app.yaml, I make sure not to deploy my .env file by adding the following line:
skip_files : .env
You will then need to add a check on ('dotenv').config() to make sure that it doesn't error or overwrite your process variables if no .env file is detected.
Aidan's suggestion is good.
As configurations should be different on GAE and local, I would suggest option 2 is best - a separate .ENV for local and .YAML for GAE environments.
One minor point though. I'd suggest to add a .gcloudignore files, something like the below:
.gcloudignore
.git
.gitignore
.env
staging.yaml
node_modules/

Resources