# Accessing environment variables

**URL:** https://discourse.nodered.org/t/accessing-environment-variables/86388
**Category:** General
**Created:** [13 March 2024 03:00 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388 "2024-03-13T03:00:16Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [13 March 2024 03:00 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/1 "2024-03-13T03:00:17Z")

</div>

I'm trying to use an MQTT broker to broadcast some data.  
For flexibility, I want to set the MQTT variables in the system environment and then read them  
in my Node-Red flow. It used to work (some years ago) but no longer does. Here's a simple example  
showing this.  
Working context:  
Node-RED version: v3.1.6  
Node.js version: v18.19.1  
Linux 6.1.0-rpi7-rpi-v8 arm64 LE

(1) Check that the environment variables are set:  
`user@RP01:~$ set | grep MQTT`  
which returns

> ```
> MQTT_BROKER=broker.hivemq.com
> MQTT_CLIENT_ID=Client007
> MQTT_NAME=MyName
> MQTT_PORT=1883
> MQTT_TOPIC=ViewMe/Meter01
> 
> ```

(2) Based on what I found searching the Internet (and possibly not the right thing to do),  
here's the (only) change I made to settings.js in the ~/.node-red directory:

```auto
	functionGlobalContext: {
			// os:require('os'), 
			env: process.env,
	},

```

(3) Now start Node-Red  
`user@RP01:~$ node-red-start`  
which returns

```auto
Start Node-RED
    ...[snipped]...
Starting as a systemd service.

```

(4) Run the following flow in a browser.  
Flow to display the MQTT variables:

```auto
[
    {
        "id": "98320a06c471a025",
        "type": "tab",
        "label": "Flow 3",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "179e115a0c5b7eae",
        "type": "function",
        "z": "98320a06c471a025",
        "name": "View MQTT variables",
        "func": "msg.payload = \"MQTT_BROKER: '\" + env.get('MQTT_BROKER') +\"' \\n\";\nmsg.payload = msg.payload + \"MQTT_PORT: '\" + env.get('MQTT_PORT') +\"' \\n\";\nmsg.payload = msg.payload + \"MQTT_TOPIC: '\" + env.get('MQTT_TOPIC') +\"' \\n\";\nmsg.payload = msg.payload + \"--- following are not used ---\" + \" \\n\";\nmsg.payload = msg.payload + \"MQTT_CLIENT_ID: '\"+ env.get('MQTT_CLIENT_ID') + \"' \\n\";\nmsg.payload = msg.payload + \"MQTT_NAME: '\" + env.get('MQTT_NAME') +\"' \\n\";\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 80,
        "wires": [
            [
                "3e6758c2883dfd69"
            ]
        ]
    },
    {
        "id": "3e6758c2883dfd69",
        "type": "debug",
        "z": "98320a06c471a025",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 570,
        "y": 80,
        "wires": []
    },
    {
        "id": "f37e16fcb00b5f1a",
        "type": "inject",
        "z": "98320a06c471a025",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 130,
        "y": 80,
        "wires": [
            [
                "179e115a0c5b7eae"
            ]
        ]
    }
]

```

The result is

```auto
msg.payload : string[178]
"MQTT_BROKER: 'undefined' ↵MQTT_PORT: 'undefined' ↵MQTT_TOPIC: 'undefined' ↵--- following are not used --- ↵MQTT_CLIENT_ID: 'undefined' ↵MQTT_NAME: 'undefined' ↵"

```

I.e., everything is undefined.

Many thanks for help in figuring this out.  
~ThisEndUp.

---

<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: [13 March 2024 03:44 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/2 "2024-03-13T03:44:09Z")

</div>

None of that is necessary. Just enter the parameters in the MQTT config node setup using this syntax `${ENVVAR}`.

it's all in the docs: [Using environment variables : Node-RED](https://nodered.org/docs/user-guide/environment-variables)

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [13 March 2024 14:11 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/3 "2024-03-13T14:11:03Z")

</div>

This might be helpfull, some stuff I only just discovered:

There are several ways to define environment variables for Node-red.  
One approach (on Linux) is to declare them in a file `.node-red/EnvironmentFile` (the filename is specified in /etc/systemd/system/multi-user.target.wants/nodered.service") and restarting Node-red. eg:

```auto
WIBBLE="This variable set in .node-red/EnvironmentFile"

```

Accessing the environment variable - in an Inject node there are two options

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/0/e06d6cd20e006083f2e98a00415ebc6decadaa57.png)

Feeding that to a debug node gives

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/4/644d5936d162368e19321f3d113675bbb60f8a83.png)

---

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [16 March 2024 00:18 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/4 "2024-03-16T00:18:23Z")

</div>

My attempts are still failing. The variables are set in the shell immediately before starting node-red, as confirmed by the command `set | grep MQTT`. I then follow instructions in the [Using environment variables](https://nodered.org/docs/user-guide/environment-variables).  
For example, those instructions state:

> Within a Function node, environment variables get be accessed using the `env.get` function:
> 
> ```auto
> let foo = env.get("FOO");
> 
> ```

But this is essentially what I posted. To follow the instructions more exactly, I changed it to

```auto
let broker = env.get("MQTT_BROKER");
msg.payload = "MQTT_BROKER: '" + broker + "' \n";

```

and the result is still `'MQTT_BROKER: 'undefined' `.

As for the suggestion that I define variables in a `.node-red/EnvironmentFile`, where this file is specified in a `nodered.service` file, there are no `node*` files at all in `/etc/systemd/system/multi-user.target.wants/`.

```auto
root@RP01:/etc/systemd/system/multi-user.target.wants# ls -l node*
ls: cannot access 'node*': No such file or directory

```

If I wanted to add a `nodered.service` file, what would it contain, and what would its format be? And would its name be `nodered.service` or `node-red.service` (with a hyphen)?

So, I'm still lost.  
~ThisEndUp

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [16 March 2024 00:56 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/5 "2024-03-16T00:56:50Z")

</div>

OK my apologies, the Raspberry install script for Node-red does setup systemd but unless you run `sudo systemctl enable nodered` they are not accessible in that directory. Enabling makes a link so that Node-red is automatically started at boot. I always do this.

```auto
pi@zero2green:/etc/systemd/system/multi-user.target.wants $ ls -l nodered.service
lrwxrwxrwx 1 root root 35 Mar 15 00:14 nodered.service -> /lib/systemd/system/nodered.service

```

So the actual file is at /lib/systemd/system/nodered

ps I suspect that even with node-red auto start disabled, if you were to edit /lib/systemd/system/nodered.service and start Node-red with the node-red-start script, it would still use the systemd script. But I have never tried it.

pps It looks like you might be running Node-red as root? This is universally acknowledged to be a Bad Thing.

ppps You can also set environment variables in settings.js, eg this creates an environment variable HOSTNAME (I know, $HOSTNAME _should_ already exist)

```auto
// just above module.exports = {
 hostname = require('os').hostname();
 process.env.HOSTNAME = hostname;

```

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [16 March 2024 01:01 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/6 "2024-03-16T01:01:49Z")

</div>

> [@ThisEndUp](#):
>
> The variables are set in the shell immediately before starting node-red

Are you exporting the variables?

`EVERYTHING=42`  
sets the variable, while  
`export EVERYTHING=42`  
makes it available in subshells

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [16 March 2024 07:41 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/7 "2024-03-16T07:41:11Z")

</div>

If you set an environment variable in a shell window it only affects processes run from that terminal. If you were to start node red using  
`node-red`  
Then it should be accessible in node red. However, by using node-red-start you are telling systemd to start node red, it is not running within your terminal window so the variable is not available.

You will have to define a system wide env var, or set it within the node red systemd script.

---

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [16 March 2024 18:03 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/8 "2024-03-16T18:03:47Z")

</div>

Many thanks. I've found something that does work and some things that don't.

What does work:  
I returned `~/.node-red/settings.js` to its original contents.  
I followed jbudd's advice and ran `sudo systemctl enable nodered` and I created a file to set variables in `~/.node-red/EnvironmentFile`.

```auto
user@RP01:~$ cat ~/.node-red/EnvironmentFile 
export MQTT_BROKER=broker.hivemq.com
export MQTT_PORT=1883
export MQTT_CLIENT_ID=Client007     
export MQTT_TOPIC=ViewMe/Meter01    
export MQTT_NAME=MyName

```

I rebooted the Raspberry Pi to make sure that node-red was started when the system comes up.  
But see (1) below for the results of that (look for _on boot-up_).

I have a file named `~/startNR.sh` with contents:

```auto
#!/bin/sh
export MQTT_BROKER=broker.hivemq.com
export MQTT_PORT=1883
export MQTT_CLIENT_ID=Client007     
export MQTT_TOPIC=ViewMe/Meter01    
export MQTT_NAME=MyName
node-red-stop
node-red

```

When I run this, even asynchronously (i.e.,` ~/startNR.sh &`) , it stops node-red and then restarts it. As Colin suggested, this uses the command `node-red` and not `node-red-start`. Then the variables are defined and display properly. Hooray!

What does not work:  
(1) setting variables in `~/.node-red/EnvironmentFile`.  
And yes, there is a line

```auto
EnvironmentFile=-/home/user/.node-red/EnvironmentFile

```

in `/lib/systemd/system/nodered.service` which is linked as expected.

```auto
user@RP01:~$ ls -l /etc/systemd/system/multi-user.target.wants/nodered.service
lrwxrwxrwx 1 root root 35 Mar 16 12:06 /etc/systemd/system/multi-user.target.wants/nodered.service -> /lib/systemd/system/nodered.service

```

This has no effect, no matter when node-red is started, _on boot-up_, from a shell file, or directly from a command line. I don't understand this.

(2) Confirming Colin's comments, if I were to change `node-red` in the `startNR.sh` file to `node-red-start`, it does not work. Note that whenever the command `node-red-stop` runs, it advises `Use node-red-start to start Node-RED again`. This is not good advice if you want to set environment variables.

(3) Setting the ownership and permissions of ` ~/startNR.sh` -- e.g., to root with setuid -- doesn't help.

Again, thanks for the help.  
ThisEndUp

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [16 March 2024 19:11 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/9 "2024-03-16T19:11:40Z")

</div>

> [@ThisEndUp](#):
>
> What does not work:  
> (1) setting variables in `~/.node-red/`

That's a surprise because as I showed in my first post above, it works for me.  
I don't have "export" in that file though, that's a bashism and I presume this file is interpreted by JavaScript.  
Maybe it only works if node red autostart is enabled

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [16 March 2024 19:55 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/10 "2024-03-16T19:55:48Z")

</div>

What have you got in EnvironmentFile?

---

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [16 March 2024 22:02 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/11 "2024-03-16T22:02:23Z")

</div>

It's listed in my response.

> [@ThisEndUp](#):
>
> ```auto
> user@RP01:~$ cat ~/.node-red/EnvironmentFile 
> export MQTT_BROKER=broker.hivemq.com
> export MQTT_PORT=1883
> export MQTT_CLIENT_ID=Client007     
> export MQTT_TOPIC=ViewMe/Meter01    
> export MQTT_NAME=MyName
> 
> ```

But I did try it once without the `export` at the beginning of the lines.

~ThisEndUp

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [16 March 2024 23:13 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/12 "2024-03-16T23:13:02Z")

</div>

If you will indulge me a little longer, please:

Edit your /home/user/node-red/EnvironmentFile to contain

```auto
MQTT_BROKER='broker.hivemq.com'
MQTT_PORT=1883
MQTT_CLIENT_ID=Client007     
MQTT_TOPIC='ViewMe/Meter01'    
MQTT_NAME='MyName'

```

Import this little flow  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/1/a181bebd94a427ee20895bc038c680b29c9669be.png)

```auto
[{"id":"c0c11435666359ac","type":"inject","z":"2b90ab1f09978dc3","name":"","props":[{"p":"broker","v":"${MQTT_BROKER}","vt":"str"},{"p":"topic","v":"MQTT_TOPIC","vt":"env"},{"p":"port","v":"${MQTT_PORT}","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":170,"y":120,"wires":[["b15b20cf035d36f3"]]},{"id":"b15b20cf035d36f3","type":"debug","z":"2b90ab1f09978dc3","name":"From Environment","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":350,"y":120,"wires":[]}]

```

Stop Node-red  
Start Node-red by either

```auto
sudo systemctl start nodered

```

or

```auto
sudo systemctl enable nodered
sudo reboot

```

Show us what the debug output is.

What I get, on a Raspberry running Node-red 4.0 is  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/3/9355331355469f48db27f15bc12ec7d09fa25b3f.png)

---

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [18 March 2024 20:51 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/13 "2024-03-18T20:51:13Z")

</div>

OK -- success. Here are the details:  
(1) I've now modified the EnvironmentFile contents to remove `export` from the beginning of each line.

```auto
user@RP01:~$ cat ~/.node-red/EnvironmentFile
MQTT_BROKER=broker.hivemq.com
MQTT_PORT=1883
MQTT_CLIENT_ID=Client007
MQTT_TOPIC=ViewMe/Meter01
MQTT_NAME=MyName

```

(2) I've now got the following flow (the code files are in entries above, so I won't repeat them here).

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/a/3ad332a672e5b01a60a4e83f2808c95ef3f68e7d.png)

(3) I make sure node red is not running:

```auto
user@RP01:~$ ps -ef | grep [Nn]ode
root 1264 1208 0 16:16 ? 00:00:00 fusermount3 -o rw,nosuid,nodev,fsname=portal,auto_unmount,subtype=portal -- /run/user/1000/doc
user@RP01:~$ 

```

(4) I then start node red with jbudd's recommended

```auto
sudo systemctl start nodered

```

I've also tried the alternative of rebooting the Raspberry Pi, and it works as well.

(5) The result is

```auto
3/18/2024, 4:23:29 PM
node: 3e6758c2883dfd69
msg.payload : string[183]
string[183]
MQTT_BROKER: 'broker.hivemq.com'    
MQTT_PORT: '1883'    
MQTT_TOPIC: 'ViewMe/Meter01'    
--- following are not used ---    
MQTT_CLIENT_ID: 'Client007'    
MQTT_NAME: 'MyName'    
3/18/2024, 4:23:31 PM
node: From Environment
ViewMe/Meter01 : msg : Object
object
_msgid: "15809db93a2e651b"
broker: "broker.hivemq.com"
topic: "ViewMe/Meter01"
port: "1883"

```

Hooray! The results are the desired ones, i.e.both the function named `View MQTT variables` which uses the `env.get()` function and the `inject` node, which uses TypedInput widgets, successfully access the environment variables in `~/.node-red/EnvironmentFile`.

Takeaway: The two essential changes were steps 1 and 4 above. Thank you jbudd for the actions that solved this and Colin for the explanation of the (IMHO subtle) reason that step 4 is necessary.

~ThisEndUp

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [18 March 2024 21:41 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/14 "2024-03-18T21:41:56Z")

</div>

> [@ThisEndUp](#):
>
> I then start node red with jbudd's recommended
> 
> ```auto
> sudo systemctl start nodered
> 
> ```

Just to note that that is what  
`node-red-start`  
does.

---

<div class="post-metadata">

### Author: ![ThisEndUp](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@ThisEndUp](https://discourse.nodered.org/u/ThisEndUp)
#### Post date: [19 March 2024 16:33 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/15 "2024-03-19T16:33:56Z")

</div>

Thanks for the info.

I did try to test `node-red-start`. When that didn't work, I tried a subsequent `sudo systemctl start nodered`, and that did work. However, there are a number of moving parts -- most particularly `~/.node-red/EnvironmentFile` and open browser pages -- that were involved in all my tests. I tried to be careful, but it's quite possible that the tests that failed booted the Raspberry Pi when the environment file was not available, or that a browser page was stale.

In any case, I've tried `node-red-start` again in a three scenarios:  
(1) with a reboot that started node-red automatically,  
(2) after a reboot with an automatic start followed by a manual stop and then a start, and  
(3) after a reboot after disabling node-red, so it didn't start automatically, followed by a manual start.  
It worked each time. I've even tried it using  
`bash -x node-red-start`  
to see what it actually does, step-by-step. Indeed it does run `sudo systemctl start nodered`, so I don't really understand why it failed in my earlier tests.

I'm glad that the correct information is now out. Thanks again,  
~ThisEndUp

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [19 March 2024 16:47 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/16 "2024-03-19T16:47:38Z")

</div>

> [@ThisEndUp](#):
>
> 'm glad that the correct information is now out.

Unfortunately the Node-red documentation on environment variables is wrong.

[https://discourse.nodered.org/t/error-in-user-guide/86486](https://discourse.nodered.org/t/error-in-user-guide/86486)

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [2 April 2024 16:48 UTC](https://discourse.nodered.org/t/accessing-environment-variables/86388/17 "2024-04-02T16:48:06Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
