How to define different vars for different environment in node.js? - javascript

I start to use dotenv for defining my env vars. I can easily specify my common vars for dev and prod environment in one .env file. But how to specify different vars for development and production environment.
For example I want to use DB_NAME = dev_db for development and DB_NAME = prod_db for production. How can I achieve this with dotenv?
I'm working with node.js.
Thank you in advance!

The .env file is supposed to be different on different environments, and hence should not be committed to your source control repo (for Git this would mean .gitignore).
For example, you'd have a config.env on production with this:
DB_NAME=prod_db
And on development, like this:
DB_NAME=dev_db
On both environments, the files would be named config.env and would reside in the same location so that the code will read the correct file.
In my project, the committed file is called config.env.sample that contains all the necessary values so that developers know what they need to add to the config.env in their environment:
# config.env.sample
# Sample configuration file for Project XYZ
# Name of the database
DB_NAME=dev_db
Here is more information from the FAQ:
Should I commit my .env file?
No. We strongly recommend against committing your .env file to version control. It should only include environment-specific values such as database passwords or API keys. Your production database should have a different password than your development database.
Should I have multiple .env files?
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.

Related

What's the difference between exposing environment variables in nextjs through the next.config.js vs with the NEXT_PUBLIC prefix?

According to the nextjs documentation, if I want to expose my environment variables to the browser I can just prefix them with NEXT_PUBLIC in my .env.local file, like so:
NEXT_PUBLIC_VAR=7
However, it looks like I can also expose my environment variables to the browser by using next.config.js, like so:
module.exports = {
env: {
PUBLIC_VAR: process.env.PUBLIC_VAR,
},
}
And this will add to the javascript bundle
What is the difference between these two strategies?
NEXT_PUBLIC is a new feature added. Before, in order to set up environment variables, we had to set up both server and client, separately.
Environment variables that are placed in the .env file would be available only on the server-side, if you want to make your env variables available on the client-side you had to use next.config.js. We follow the separation of concerns principle here.
But setting env variables for the browser in the next.config was too much unnecessary typing. This was an example in next.config.js for the client side env:
module.exports = {
env: {
AUTH0_NAMESPACE: process.env.AUTH0_NAMESPACE,
BASE_URL: process.env.BASE_URL
}
}
With NEXT_PUBLIC, env variables will be available both client-side and server-side. env variables that are set with NEXT_PUBLIC will be exposed to the browser. So make sure that you do not expose sensitive data to the browser.
So in summary, adding the prefix NEXT_PUBLIC to your environment variables will have the same effect of exposing to the browser your environment variables as exposing them through next.config.js.
try this:
place this to .env or env.development file. NOT to next.config.js
MY_VAR=10
then run this:
console.log("MY var",process.env.MY_VAR);
both inside client component and getServerSideProps function.
if you check the browser console, you will get undefined, but on terminal, you will see
MY var 10
The difference between to the two is the one of them uses a .env file whereas the other uses the next.config file. Since Next.js 9.4, loading environment variables with .env files are now supported.
However, to clarify one thing in your question, all environment variables within the .env file don't have to be prefixed with NEXT_PUBLIC, only the ones you want exposed to the browser, any without that prefix will only be accessible on the server.

What's the proper way of setting environment variable in Netlify functions?

What's the proper way of setting environment variables in netlify? I would like to be able to set different values for the variables depending on the environment.
Pseudo code:
let host;
if (process.env.GATSBY_CUSTOM_CONTEXT === 'production') {
host = process.env.PRODUCTION_HOST
} else if (process.env.GATSBY_CUSTOM_CONTEXT === 'development') {
host = process.env.DEVELOPMENT_HOST
}
I have tried passing env variable thru CLI, like GATSBY_CUSTOM_CONTEXT=production gatsby build and I also tried using same command with cross-env.
My other attempt used netlify.toml:
[build]
base = "/"
publish = "public"
command = "yarn build"
functions = "src/functions"
[context.production]
[context.production.environment]
GATSBY_CUSTOM_CONTEXT = "production"
All of these options worked with netlify dev locally, but in production GATSBY_CUSTOM_CONTEXT is always undefined.
The reason you can't resolve the environment variables in your Netlify functions is because as of the time of your question, Netlify does not transfer the environment variables from the netlify.toml file.
You must put them into the admin panel in your site settings in the app.netlify.com dashboard.
Unfortunately, what you're looking to doesn't seem to be currently supported. Though they provide an alternative approach.
I found this snippet on their docs:
CALLING ENVIRONMENT VARIABLES
Using environment variables directly as
values ($VARIABLENAME) in your netlify.toml file is not supported.
However, the following workflow can be used to substitute values in
the file with environment variable values, assuming you are only
trying to change headers or redirects. The rest of the file is read
BEFORE your build — but those sections are read AFTER the build
process.
Add a placeholder like HEADER_PLACEHOLDER somewhere in the netlify.toml redirects or headers sections.
Create an environment variable, for example PROD_API_LOCATION, with the desired value. You can create environment variables in the
toml file or in our UI. You might use the latter to keep sensitive
values out of your repository.
Prepend a replacement command to your build command. Here’s an example for a site using yarn build to build: sed -i
s/HEADER_PLACEHOLDER/${PROD_API_LOCATION}/g netlify.toml && yarn build
Taken from here: https://www.netlify.com/docs/netlify-toml-reference/

How to specify env variables in node app?

It's a lot of references to dotenv library to use when you want to specify env variables. But why? I can just specify my var in a file like this:
var dev = {
}
var prod = {
}
var config = null;
if (process.env.NODE_ENV === 'production') {
config = prod
} else {
config = dev
}
exports.config = config
and assign my var in npm srcipts, like this:
"scripts": {
"start": "NODE_ENV=dev node bin/dev",
"production": "NODE_ENV=production node bin/production"
}
Is my way not secure? Why is dotenv way recommended? Why should I create .env files instead my config.js?
Environment variables is the commonly assumed way to configure the behaviour of a program, across all programming languages. It is also supported out-of-the box in most CI/CD tools, as well working really well with the command line.
In your example, you assume that the complete config of the prd environment will be stored in the config, including db password etc. It is not considered secure to store any secrets in source code.
The.env file is a common utility for bundling environment variables. It is really is easy to create a .gitignore file with this pattern that prevents it from ever being committed so that configuration stays local. Note that the consumer of the package doesn't have to use a .env file but could also have global/local environment vars where the script is ran. Development solid and not so prone to mistakes.
Syntax simplicity. instead of creating an ad-hoc source code file containing configuration, with more complex syntax than key=value and less common to understand.
#Nastro, I'll point a little and simple different approach.
Develop your application 100% agnostic of an environment. In other words, keep away *from versioning files within your code or lots of if assigning different values to globals, sessions attributes and etc.
Favor your environments with the due env vars and values. Usually, the most strategic or special environments will be protected against unwanted access(production, staging and etc), so your secret values will be unreachable.
A single db_password = process.env.DB_PASS will be reusable for any existing and future environment you or your team creates.
This is a simple, yet effective approach, but demands a minimal control over your environment and hosts.

Conditional javascript source code

Background:
I have 3 different URLs, one per environment (dev, test, prod), and I don't want to expose all the URLs in the client (source code).
How can I expose in the client code, just the one corresponding to the environment in context?
Note: As I understand, I need to do something in the build process using environment variables (I'm using node.js). However, I don't want to touch anything related with webpack, as what I'm trying to do is a standalone package that can be imported in any application regardless of the framework they are using. Webpack plugins/configuration are not an option, but I can use any npm package if required.
During your build process, you can check the environment variable and then copy over a config file. For example, you could keep your URIs in /config/<env>.js, and then copy/rename it to /settings.js during the build. Your URL could be exported from that.
The following npm package fits my requirements completely https://www.npmjs.com/package/config , you can load conditional files based on the node environment variable NODE_ENV, so when NODE_ENV=development, the file /config/development.js is used to create the build. you can use different extensions for the config files, also you can customize the config folder path by changing the environment variable $NODE_CONFIG_DIR heres an example:
const config = require('config');
process.env.$NODE_CONFIG_DIR = './' // relative path ./config
const url = config.get('url');
//if NODE_ENV is development will load the file config/development.js
console.log(url);

Managing JavaScript config files for different build environments (like QA, UAT, Production)

So you are building a stand alone Single Page Application in JavaScript that is served statically. It connects to an API.
Your application has a JSON object in its main.js like this:
var config = {
apiPath: 'http://dev.api.example.com',
appTitle: 'hello'
};
You use Grunt to create a release build, this transpiles all your SASS, ES6, AMD Modules etc code into one or two JavaScript files, along with this config object.
Your production API url is http://api.example.com and when you do a release build, you want just this value in the config to change. (Maybe you would want to change other config parameters too). You have a release config
var config = {
apiPath: 'http://api.example.com'
};
How can a JavaScript config file be altered depending on different types of release environments during a build. Notice that I want to merge the release config into the default, not maintain totally seperate files with all the settings. While there are grunt plugins for setting a build mode, I've not found any that have the ability to update config files, only hacks that change which file is pointed to.
ASP.NET has web.config transforms that do exactly this, any property in the release transform for example, will overwrite the 'default' config on packaging. Does such a workflow exist using grunt or something?
In the end I solved the question myself by using a combination of environment variables and an amazing Node called Confidence which where you place all your different envs config settings in a single file, and they are resolved to a single configuration based on filters (such as an environment variable) - these can then be injected into the build process using tools like WebPack.

Categories

Resources