# Environment variables outside settings.js file

**URL:** <https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527>\
**Category:** General\
**Created:** [12 May 2020 14:04 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527 "2020-05-12T14:04:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [12 May 2020 14:04 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/1 "2020-05-12T14:04:54Z")

</div>

Hi, after read several messages I still have some troubles, could you please help me?  
I have never used environment variables before.  
Now, in settings.js I've added "env: process.env" just below " functionGlobalContext: {" like this:

> ```
> functionGlobalContext: {
> env: process.env
> 
> ```

Moreover, following other post and documents I've modifided the module.exports = { section like this:

> module.exports = {  
> process.env.HOSTNAME = require('os').hostname();  
> process.env.FOO = 'just another bar';

but in this way it doesn't work. In order to make it works I had to write it as following:

> module.exports = {  
> test1: process.env.HOSTNAME = require('os').hostname();  
> test2: process.env.FOO = 'just another bar';

I don't know if it's correct but is the only way I was able to make it working.  
So, in this way I can use the environment variables set inside the settings.js file.  
But I have 2 more needs:

- I would have the environment variables writes in an external file rather than inside settings.js. How can I do this?
- I would even pass as variables users and passwords, for nodes that requires connection like mysql, mqtt, etc.

Briefly, since I have the some project for several users, I would like to have jast one file where to make these changing and let it read and passed to the flow at load, when node-red starts.  
Thanks

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [18 May 2020 18:04 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/2 "2020-05-18T18:04:41Z")

</div>

I like very much this documentation on Environmental Variables. It explains how to modify the settings.js file to add them. You should add the environmental variables in the beginning of the file, not inside `module.exports`

[https://flows.nodered.org/flow/8a13d11dfe80e279df83341e3e17bcc1](https://flows.nodered.org/flow/8a13d11dfe80e279df83341e3e17bcc1)

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [18 May 2020 23:41 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/3 "2020-05-18T23:41:09Z")

</div>

Thanks a lot Andrei. I already saw it, but I misunderstood where to declare the variables. Thanks for pointing it out again. Now it works perfectly.  
One more thing. It would be really useful for me having this variables within an external file, and not inside setting.js. How can I make this external file read from setting.js at node-red load?

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [19 May 2020 00:26 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/4 "2020-05-19T00:26:52Z")

</div>

Hi @Lupin_III, reading an external file from settings.js is easy but I couldn't possibly explain better than @TotallyInformation did in a previous post (so useful that I saved that post as a reference):

> Simply create another file with a module.exports statement and then `require` that file in the settings file

He explains in details [here.](https://discourse.nodered.org/t/anyone-fancy-writing-a-config-node-that-edits-the-settings-js-file/19185/10)

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [19 May 2020 09:32 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/5 "2020-05-19T09:32:45Z")

</div>

The link doesn't work

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [19 May 2020 09:41 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/6 "2020-05-19T09:41:24Z")

</div>

The link is to a private conversation... perhaps @TotallyInformation would be kind enough to re-post his comment here.

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [19 May 2020 13:12 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/7 "2020-05-19T13:12:05Z")

</div>

Oh sorry, I overlooked that that was a private conversation. So, giving the answer without explaining.

Here is like I did (first time ever, perhaps there is a better way).

1. Create external file named env-external.js (testing in a windows environment), with the following content:

```auto
module.exports = {

hostname : process.env.HOSTNAME = require("os").hostname(),
mqttLocal: process.env.MQTTLOCAL = "192.168.1.50",
mqttPublic: process.env.MQTTPUBLIC = "broker.hivemq.com",
Lat: process.env.LAT = "-25.442414",
Lon: process.env.LON = "-49.236903" ,
friend: process.env.FRIEND = "vercingetorix"
}

```

2- Added this line to the top of settings.js (outside modules.export session):

```auto
var	env_external = require("./env-external");

```

3- Restarted the runtime

4- Tested using a change node to read an environmental variable to msg.payload

![r-01](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/a/fa7f6fe1baa81414a1abddb8357055f45aa9558a.png)

5- Sounds strange for me but it worked well right first time (apparently) 😆

![r-02](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/0/b01ba8fb00959fb0897ab06a0efd207df282499f.png)

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [19 May 2020 14:27 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/8 "2020-05-19T14:27:31Z")

</div>

Your wish is my command!

* * *

If you look at settings.js you will see that all of the settings are contained within a `module.exports`. This is what turns a .js file into a node.js module that you can use `require` on.

So lets say that you wanted to split out the contextStorage settings so that they were easier to change. You might currently have something like this in settings.js

```auto
    contextStorage: {
        default: {
            module:'memory'
        },
        file: {
            module: 'localfilesystem'
        }
    },

```

So now create a new file, lets say contextStorage.js:

```auto
module.exports = {
        default: {
            module:'memory'
        },
        file: {
            module: 'localfilesystem'
        }
    },

```

Then you can change settings.js like so:

```auto
    contextStorage: require('./contextStorage.js'),

```

You can take this further and create more complex objects for export including functions. Lets take a random example. Let's say that you wanted to run lots of instances of Node-RED, you need multiple ports. Perhaps you want to manage those ports in a database. So you could create a module that exports a function that returns a port number perhaps looked up from a db or maybe simply from running a script to check for ports in use.

In this more complex scenario, you are likely to put your require at the top of the settings.js file like you may do with things like `fs`. So your config file might now look like:

```auto
module.exports = {
    freePort: function() {
        ...
    },
    contextStorage: {
        default: {
            module:'memory'
        },
        file: {
            module: 'localfilesystem'
        }
    },
}

```

In settings.js you'd have this at the top of the file:

```auto
const mySettings = require('./mySettings.js')

```

And setting the port and context storage:

```auto
    uiPort: mySettings.freePort(),
    contextStorage: mySettings.contextStorage,

```

As for missing comma's. In JS files, as long as you are using a reasonably up to date version of JavaScript, you can always have trailing commas and I always use them as it saves both time and frustration. Configure you linting tool to require them and you will always spot the missing ones.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [20 May 2020 10:47 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/9 "2020-05-20T10:47:07Z")

</div>

Thanks a lot to all. It works great.  
I add one more step if someone can help me. Actually I ned to read these my own environment variable even within a python script.  
What would be for you the best way? At the moment as suggested I create a new test.js file like this

> module.exports = {  
> mqttLocal: process.env.MQTTLOCAL = "192.168.1.201",  
> mqttPublic: process.env.MQTTPUBLIC = "[test.com](http://test.com)",  
> testPetch: process.env.testPetch = " C:\test\"  
> };

and at the top of setting-js in node-red

> var env\_external = require("./test.js");

I need to read these variable in python, too.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [20 May 2020 11:25 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/10 "2020-05-20T11:25:03Z")

</div>

Well, you could read the file in and manually parse it in Python however the format isnt great for python.

There are a number of options - here are some off the top of my head...

save the file as pure JSON and [read the JSON file into python](https://www.programiz.com/python-programming/json) (easy to parse)

OR

you might be better off storing the env vars in OS environment variables (python and node-red can read these)

Python...

```python
os.getenv('MQTTPUBLIC', default_value)

```

OR

you could transmit them from node-red to an MQTT broker then have your python app subscribe to the env topics e.g. `environment/MQTTPUBLIC`, `environment/MQTTPRIVATE` , etc.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [21 May 2020 09:32 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/11 "2020-05-21T09:32:26Z")

</div>

Thanks Steve.  
I think in my case the best way is your first suggestion, using a json pure file. But How can now pass the variables inside the json file to setting js?  
Now I have the json file like

> {  
> "mqttLocal" : "192.168.1.201",  
> "mqttPublic": "[test.com](http://test.com/)",  
> "testPetch" : "C:\test\"  
> }

I read it in python. Now I would even use these as environment voriables inside node-red. How can I pass them to setting.js?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [21 May 2020 09:39 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/12 "2020-05-21T09:39:49Z")

</div>

same as youre already doing (except using a file name xxxxx.json)

Proof...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/9/2910585faf8622f68f11142f098402ce00484b7d.png)

### IMPORTANT NOTE...

**that is not valid JSON (back slashes should be escaped)**

e.g...

```json
{
  "mqttLocal" : "192.168.1.201",
  "mqttPublic": "test.com",
  "testPetch" : "C:\\test\\"
}

```

---

<div class="post-metadata">

**Author:** ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)\
**Post date:** [21 May 2020 10:32 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/13 "2020-05-21T10:32:29Z")

</div>

A simple dsm use case that outputs `RED.settings`.  
Just in case you'd like to check your settings.

```auto
[{"id":"942c6e6b.a3a76","type":"dsm","z":"ac4aa9f6.c24288","name":"RED settings","sm_config":"{\n \"methods\": {\n \"onTransition\": [\n \"msg.payload = RED.settings;\",\n \"output = true;\"\n]\n }\n}","x":580,"y":80,"wires":[["d3e784c0.4ec658"]]},{"id":"aab96586.c40018","type":"inject","z":"ac4aa9f6.c24288","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":80,"wires":[["942c6e6b.a3a76"]]},{"id":"d3e784c0.4ec658","type":"debug","z":"ac4aa9f6.c24288","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":80,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [21 May 2020 11:16 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/14 "2020-05-21T11:16:22Z")

</div>

Thanks guys.  
At the end I'm able to use these environment variables inside flows, but I don't know if I do it in the correct way. Let me recap.  
this is my test.json file

> {  
> "mqttLocal" : "192.168.1.201",  
> "mqttPublic": "[test.com](http://test.com)",  
> "testPetch" : "C:/test/"  
> }

and this is the beginning of my settings.js

> my\_var\_env = require("C:/test/test.json");  
> module.exports = {  
> MQTTLocal: process.env.MQTTLocal = my\_var\_env.mqttLocal,  
> MQTTPublic: process.env.MQTTPublic = my\_var\_env.mqttPublic,  
> TestPetch: process.env.TestPetch = my\_var\_env.testPetch,  
> ......  
> uiPort: process.env.PORT || 1880,  
> ......

within a function node I call my variables in this way:

> var env = global.get('env');  
> msg.payload={  
> "MQTTLocal": env.MQTTLocal  
> };  
> return [msg];

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [21 May 2020 16:06 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/15 "2020-05-21T16:06:07Z")

</div>

Using the nodes posted by Cflurin I see that in this way these variables are present directly as object properties, plus as environment variables, and looking at my code I think this is correct even if I'm not able to use them as object properties. But there is a better way in order to avoid to duplicate them inside the node-red instance?  
@ Steve. Since I need to pass the path inside the json file in python, where I need backslashes C:\\folder\\ I tryed using it inside the json file end it is correctly read by settings.js and works as well.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 May 2020 18:03 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/16 "2020-05-21T18:03:39Z")

</div>

> [@Lupin\_III](#):
>
> I need backslashes

You should never need backslashes, certainly in any modern app. If you need cross-platform support, best to use a library. node.js has the path library which is built in, not sure if Python has an equivalent. Use `path.join()` in Node.js always rather than using fixed paths, that will also sort out intermediate relative paths as well.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [21 May 2020 19:16 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/18 "2020-05-21T19:16:44Z")

</div>

Thanks TotallyInformation. I set it in setting.js about the path of my test.json file. How can I do the same inside my test.json file? I have path's directories here, too

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 May 2020 22:11 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/19 "2020-05-21T22:11:30Z")

</div>

You can't do it inside a JSON file. However, you might consider using an array instead and then path.join the array when you need it. That way, never any issues 😉

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [21 May 2020 22:31 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/20 "2020-05-21T22:31:07Z")

</div>

Many thanks

---

<div class="post-metadata">

**Author:** ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)\
**Post date:** [22 May 2020 08:32 UTC](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527/21 "2020-05-22T08:32:46Z")

</div>

As an option you could read the file `test.json` and store the settings into a global variable  
without the need to modify settings.js and to restart node-red.

Assuming the `test.json` is in your userdir the JSON object is stored into the golbal `ext_settings`.

```auto
[{"id":"b5583107.705f7","type":"dsm","z":"ac4aa9f6.c24288","name":"","sm_config":"{\n \"currentState\": \"idle\",\n \"states\": {\n \"idle\": {\n \"start\": \"reading\"\n },\n \"reading\": {\n \"done\": \"idle\"\n }\n },\n \"methods\": {\n \"init\": [\n \"sm.fs = require('fs');\",\n \"sm.udir = RED.settings.userDir + '/';\",\n \"sm.filename = sm.udir + 'test.json';\" \n],\n \"start\": [\n \"sm.fs.readFile(sm.filename, 'utf8', function(err, data) {\",\n \"if (err) {\",\n \"node.error(err);\",\n \"} else {\",\n \"var ext_settings = JSON.parse(data);\",\n \"global.set('ext_settings', ext_settings);\",\n \"msg.payload = ext_settings;\",\n \"resume('done', msg);\",\n \"};\",\n \"});\",\n \"output = false;\"\n],\n \"done\": [\n \"sm.fill = 'green';\",\n \"sm.text = 'done';\"\n],\n \"status\": {\n \"fill\": {\n \"get\": \"sm.fill\"\n },\n \"shape\": \"dot\",\n \"text\": {\n \"get\": \"sm.text\"\n }\n }\n }\n}","x":810,"y":300,"wires":[["311049db.f64e26"]]},{"id":"4fb989b1.fe0ae8","type":"inject","z":"ac4aa9f6.c24288","name":"","topic":"start","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":640,"y":300,"wires":[["b5583107.705f7"]]},{"id":"311049db.f64e26","type":"debug","z":"ac4aa9f6.c24288","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":970,"y":300,"wires":[]}]

```

[Next page](https://discourse.nodered.org/t/environment-variables-outside-settings-js-file/26527.md?page=2)
