I want to add a dynamic env var in my node.js app, in other words i wanted the env value to be determined through a function. so i can't add it manually in my .env file.
I'am using webpack as a module bundler and i want to access that env var in my webpack.config file.
Assuming you're running the node server on a linux machine. You need to export all your environment variables manually or via a script like so: export PORT=3000;, then accesses them directly via the node process object like so:
const port = process.env.PORT || 5000;.
Or you could install a dependency like config (https://www.npmjs.com/package/config) and have it manage pulling your environment variables into the code for use.
Related
What is the best way to load environment variables for Vue.js app without using vue-cli? In vue-cli way you just update the .env files and those variables should be available in Vue.js app like this: https://cli.vuejs.org/guide/mode-and-env.html#example-staging-mode
I am using Symfony Webpack Encore and have no vue-cli installed, how could I pass my environment variables into entire Vue application?
just create a .env file and create you variable like this VUE_APP_XXXXX
you notice the VUE_APP make sure all variable has the VUE_APP prefix like.
VUE_APP_API_URL
for development .env.development.
for production .env.production
Currently this looks like a decent way to load the configs: https://github.com/symfony/webpack-encore/issues/567
First install the dotenv package and then use this on my webpack.config.js:
const dotenv = require('dotenv');
.configureDefinePlugin(options => {
const dotenvOptions = {};
const envConfigPath = `.env.${process.env.NODE_ENV}`;
if (fs.existsSync(envConfigPath)) dotenvOptions.path = envConfigPath;
const env = dotenv.config(dotenvOptions);
if (env.error) {
throw env.error;
}
options['process.env'].PMP_API_BASE_URI = JSON.stringify(env.parsed.PMP_API_BASE_URI);
})
If .env.dev.local is needed then provide NODE_ENV=dev.local while running npm run build command.
apply-platform
env-bundle
node_modules
node-client
I have a repo apply-platform that has env variables and node modules, in the node module there is another repo node-client.
When I try to access process.env variables inside node-client project I get following object as process.env
{
\"LANG\":\"en_US.UTF-8\",\"PATH\":\"/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin\",\"HOME\":\"/home/ubuntu\",\"LOGNAME\":\"ubuntu\",\"USER\":\"ubuntu\",\"SHELL\":\"/bin/bash\",\"PM2_USAGE\":\"CLI\",\"PM2_HOME\":\"/home/ubuntu/.pm2\",\"SILENT\":\"true\",\"env_production\":\"[object Object]\",\"instance_var\":\"NODE_APP_INSTANCE\",\"exec_mode\":\"cluster_mode\",\"env\":\"[object Object]\",\"treekill\":\"true\",\"autorestart\":\"true\",\"automation\":\"true\",\"pmx\":\"true\",\"vizion\":\"true\",\"merge_logs\":\"true\",\"cwd\":\"/srv/cbax-apply-platform/\",\"log_type\":\"json\",\"instances\":\"4\",\"name\":\"www\",\"node_args\":\"\",\"pm_exec_path\":\"/srv/cbax-apply-platform/server.js\",\"pm_cwd\":\"/srv/cbax-apply-platform\",\"exec_interpreter\":\"node\",\"pm_out_log_path\":\"/home/ubuntu/.pm2/logs/application.log\",\"pm_err_log_path\":\"/home/ubuntu/.pm2/logs/application.log\",\"pm_pid_path\":\"/home/ubuntu/.pm2/pids/www-13.pid\",\"km_link\":\"false\",\"vizion_running\":\"false\",\"NODE_APP_INSTANCE\":\"0\",\"PM2_JSON_PROCESSING\":\"true\",\"_\":\"/usr/bin/pm2\",\"XDG_DATA_DIRS\":\"/usr/local/share:/usr/share:/var/lib/snapd/desktop\",\"SHLVL\":\"1\",\"PWD\":\"/srv/cbax-apply-platform/\",\"PORT\":\"8080\",\"NODE_ENV\":\"test\",\"REGION\":\"USEastTest\",\"www\":\"{}\",\"status\":\"launching\",\"pm_uptime\":\"1629364026293\",\"axm_actions\":\"\",\"axm_monitor\":\"[object Object]\",\"axm_options\":\"[object Object]\",\"axm_dynamic\":\"[object Object]\",\"created_at\":\"1629364026181\",\"pm_id\":\"13\",\"restart_time\":\"10\",\"unstable_restarts\":\"0\",\"_pm2_version\":\"2.6.1\",\"versioning\":\"null\",\"node_version\":\"9.11.1\",\"exit_code\":\"0\"}
How can I access process.env variables inside the node-module (node-client)
I tried console.log(JSON.stringify(process.env.env)) it still gives me [object][object] as output;
I found this object comes from ecosystem.config.js file of apply-platform , so added these 2 variables and pushed it to the server, but when I console process.env i cant see these 2 variables in node-client
The Node injects the process.env global variable at runtime in our app to use, and it represents the state of the system environment of our app when it starts. So, for example, if the system has the PATH variable set, this will be accessible to you through the process.env.PATH variable you can use to check where binaries are located and make external calls to them if required.
When we write the code, we can never be sure where our app can be deployed. If we require the database in development, we spin up the instance of it, and we link to it via a connection string , something like 127.0.0.1:3306. However, when deploying it to the server in production, we might need to link it to the remote server, 32.22.2.1.
Accessing environment variables in Node.js is supported out of the box. When your Node.js process boots up, it will automatically provide access to all the existing environment variables by creating the env object as a property of the process global object.
Explicitly loading variables from the .env file.
npm install dotenv --save
Afterward, add the following line to the very top of your entry file (index.js or app.js).
require('dotenv').config();
There is a npm module that loads environment variables from .env files into process.env, called dotenv. In your case, you would use it like this:
const dotenv = require("dotenv")
dotenv.config({ path: "/path/to/.env/"})
You could then access the environment variables in Node.js like this:
process.env.MYVAR
If you don't want the variables specified in the .env file to mangle with other environment variables, you can also do this:
const buffer = Buffer.from("PORT=3000") //example
const env = dotenv.parse(buffer) // returns object -> { PORT: 3000 }
// env.PORT would return 3000
dotenv.parse accepts a buffer object and returns an object, instead of binding it to process.env. You could also use the fs module to read the contents of the .env file, and pass it to dotenv.parse.
To learn more, reference the npm page for dotenv: https://www.npmjs.com/package/dotenv
In my code, I have usernames on my config file and when I start my code with "node code.js randomusername" I want to get my password. I tried this code but it got undefined. How can I do that? I'm beginner of nodejs.
var config = require('./config.json');
console.log(config.process.argv[2].password);
console.log(config[process.argv[2]].password);
What your code is currently trying to do is access a field named process.argv[2] in your config object. What you actually want is to access a field whose name is in the variable process.argv[2].
you can use dotenv npm package.
Create a .env file in the root directory of your project. Add environment-specific variables on new lines in the form of NAME=VALUE. For example:
DB_USER=root
DB_PASS=s1mpl3
As early as possible in your application, require and configure dotenv.
require('dotenv').config()
Now you can access your env variable as below
var username= process.env.DB_USER,
var password= process.env.DB_PASS
I am trying to set some environment variables (for making API calls to dev/prod endpoints, keys depending on dev/prod, etc.) and I'm wondering if using dotenv will work.
I've installed dotenv, and I am using webpack.
My webpack entry is main.js, so in this file I've put require('dotenv').config()
Then, in my webpack config, I've put this:
new webpack.EnvironmentPlugin([
'NODE_ENV',
'__DEV_BASE_URL__' //base url for dev api endpoints
])
However, it is still undefined. How can I do this correctly?
Sorry for picking up old question, but
react-scripts actually uses dotenv library under the hood.
With react-scripts#0.2.3 and higher, you can work with environment variables this way:
create .env file in the root of the project
set environment variables starting with REACT_APP_ there
access it by process.env.REACT_APP_... in components
.env
REACT_APP_BASE_URL=http://localhost:3000
App.js
const BASE_URL = process.env.REACT_APP_BASE_URL;
See docs for more details.
The short answer is no. A browser cannot access local or server environment variables so dotenv has nothing to look for. Instead, you specify ordinary variables in your React application, usually in a settings module.
Webpack can be made to take environment variables from the build machine and bake them into your settings files. However, it works be actually replacing strings at build-time, not run-time. So each build of your application will have the values hard-coded into it. These values would then be accessible through the process.env object.
var nodeEnv = process.env.NODE_ENV;
Additionally, you could use the DefinePlugin for webpack which lets you explicitly specify different values depending on your build target (dev, prod, etc.). Note that you have to JSON.stringify all values passed into it.
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),
This is fine for any sort of public details but should never be used for any sort of private keys, passwords or API secrets. This is because any values baked in are publicly accessible and could be used maliciously if they contain sensitive details. For those sorts of things, you need to write some server-side code and build a simple API which can authenticate with the 3rd party API using the secrets, then pass the relevant details along to your client-side application. Your server-side API acts as an intermediary, protecting your secrets while still getting the data you need.
Create .env file
API_URL=http://localhost:8000
Install dotenv npm package
$ npm install --save-dev dotenv
Config webpack to add env variables
const webpack = require('webpack');
const dotenv = require('dotenv');
module.exports = () => {
// call dotenv and it will return an Object with a parsed key
const env = dotenv.config().parsed;
// reduce it to a nice object, the same as before
const envKeys = Object.keys(env).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(env[next]);
return prev;
}, {});
return {
plugins: [
new webpack.DefinePlugin(envKeys)
]
};
Great job! Enjoy React and dotenv.
Actually, you can use dotenv in your React app with webpack. Moreover, there are several ways of doing it. However, keep in mind that it's still a build-time configuration.
A similar way to the answer above. You import dotenv in your webpack config and use DefinePlugin to pass the variables to your React app. More complete guide on how you can inject your .env files depending on current configuration could be found in this blog.
Using a dotenv-webpack plugin. I personally find it really convenient. Let's say you have environments: dev, staging and prod. You create .env file for each environment (.env.dev, .env.staging, etc). In your webpack configuration you need to pick a correct file for the environment:
const Dotenv = require('dotenv-webpack');
module.exports = (env, argv) => {
const envPath = env.ENVIRONMENT ? `.env.${env.ENVIRONMENT}` : '.env';
const config = {
...
plugins: [
new Dotenv({
path: envPath
})
]
};
return config;
};
When you build the app for a particular environment, just pass the environment name to webpack:
webpack --config webpack.config.js --env.ENVIRONMENT=dev
I Just created a config.json in the source folder:
{
"api_url" : "http://localhost:8080/"
}
then required it in the file I needed it
const config = require('./config.json');
and used config.api_url
Right now, whenever I want to deploy a node.js server to my production server, I need to change all the IP/DNS/username/password for my various connection to my databases and external APIs.
This process is annoying, is there a way to verify if the currently running node.js instance is in cloud9ide or actually my production joyent smartmachine?
If I am able to detemrine (in my running code) on which server my node.js instance is running , I'll add a condition that set the values to the prod or dev.
Thank you
Normally you should run a node app in production like this:
NODE_ENV=production node app.js
Applications with Express, Socket.IO and other use process.env.NODE_ENV to figure out the environment.
In development you can omit that and just run the app normally with node app.js.
You can detect the environment in your code like this:
var env = process.env.NODE_ENV || 'development';
loadConfigFile(env + '.json', doStuff);
Resources:
How do you detect the environment in an express.js app?
I think the easiest way to set the environment is to pass command-line argument to your application.
node ./server.js dev
In your script you need to handle this argument and set configuration what you need for it.
var env = process.argv[2] || 'dev';
switch (env) {
case 'dev':
// Setup development config
break;
case 'prod':
// Setup production config
break;
}
Also, i was created module that makes the configuration process a bit easier. Maybe it will help you.
Actually, I would not recommend to store configuration values like database connection information, passwords, access tokens and such inside of actual application code for the following reasons:
Hardcoding those values make it difficult to change them later on. You will have to release a new version of the application to change those values.
This is a serious security violation, because production-grade configuration data and passwords shouldn't be stored in code. It's very easy to leak this sensitive data.
The better approach would be to externalize this data and pass it to your application during execution. This is normally done by means of environment variables. You just need to define unique environment variable for each peace of data that needs to be changeable between different environments.
For example: DB_HOST, DB_USER, DB_PASSWORD. Then you could pass those values to you app in production this way:
$ NODE_ENV=production DB_HOST=1.2.3.4 DB_USER=someusername DB_PASSWORD=somerandompassword /bin/node app.js
Actually, this values could be encrypted and added to the codebase and then decrypted during the deployment. However, make sure that decryption key is stored securely in deployment system or provided interactively by the release engineer. Shippable allows to do this out of the box.
In the development environment it gets simpler, because you can use very convenient dotenv module. Just create a .env file in your project's root directory and add all variables to it:
DB_HOST=1.2.3.4
DB_USER=someusername
DB_PASSWORD=somerandompassword
But, make sure to exclude it from you VCS, because each developer probably would want to have personal configuration. You can create a .env.dist file to contain default configuration, which later could be used as a template: cp .env.dist .env.
For that you can just check it out with the help of environment variables and you can perform any actions.
if (process.env.NODE_ENV === "production") {
//do something in production
}
if (process.env.NODE_ENV !== "production") {
//do something in development
}