Feature Request: Easier Ability to use Environment Variables in Configuration
See original GitHub issueI’ve been using Magic Mirror 2.8.0 and want to store secrets (e.g., OpenWeather API keys) outside of my configuration file so I can commit the file to source control. This would also allow for easier Docker image creation where you could poke in some environment variables rather than full config files.
Doing this has been a challenge.
- The
config.js
is used in both a server and a client context. That is, instead of the Electron client app retrieving configuration from the/config
endpoint of the server, theconfig.js
is used directly. This means any references toprocess.env
don’t work because… - Electron doesn’t provide the process environment on the server to the running client. [This issue shows an example of that.]
process
doesn’t exist by default, and even if you enablenodeIntegration
, the process that Electron is running under isn’t the same as the process the server started under. Instead, you need torequire('electron')
and access theelectron.remote.process.env
to get those variables marshaled over. But… - Electron
nodeIntegration
is off by default. It’s also turned off in the main electron.js. This can be overridden by config.
There is a discussion where I raised this over in the forum.
A working config.js with environment variables looks like this:
const owApiKeyName = "OPENWEATHER_API_KEY";
var remote = null;
if (typeof window !== "undefined") {
remote = window.require("electron").remote;
}
var readEnvironment = function (name) {
if (typeof process !== "undefined" && process.env[name]) {
// process is undefined in the Electron app.
return process.env[name];
}
if (remote && remote.process.env[name]) {
// remote is null if the Electron nodeIntegration value isn't set to true.
return remote.process.env[name];
}
};
var config = {
address: "localhost",
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 24,
units: "imperial",
electronOptions: {
webPreferences: {
nodeIntegration: true
}
},
modules: [
{
module: "alert"
},
{
module: "updatenotification",
position: "top_bar"
},
{
module: "clock",
position: "top_left"
},
{
module: "calendar",
header: "US Holidays",
position: "top_left",
config: {
calendars: [{
symbol: "calendar-check",
url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics"
}]
}
},
{
module: "compliments",
position: "lower_third"
},
{
module: "currentweather",
position: "top_right",
config: {
location: "Hillsboro",
locationID: "5731371", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: readEnvironment(owApiKeyName)
}
},
{
module: "weatherforecast",
position: "top_right",
header: "Weather Forecast",
config: {
location: "Hillsboro",
locationID: "5731371", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: readEnvironment(owApiKeyName)
}
},
{
module: "newsfeed",
position: "bottom_bar",
config: {
feeds: [{
title: "New York Times",
url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"
}],
showSourceTitle: true,
showPublishDate: true,
broadcastNewsFeeds: true,
broadcastNewsUpdates: true
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}
The idea is that you have to fall back from process
to remote.process
before you can get to the environment.
I’d like to propose a couple things that would make environment variable usage easier:
- Separate client and server configuration such that…
- The client only needs the endpoint to query and the Electron options.
- The server has the endpoint to serve on and the module configuration.
- Change the Electron app to query module configurations from the server rather than directly using config.js.
From a backwards compatibility perspective, you could treat config.js as something that both use and the difference would be that the module settings on the Electron side that are read from config.js would be ignored in favor of retrieved settings.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:49 (4 by maintainers)
It appears this is still something that would be helpful.
May I write this more than once: I still think we should have this feature …
But I can also understand avoiding breaking changes. May we have to talk about MagicMirror v3 where we do things better and we accept breaking changes. And e.g. realize the idea to load the config from the server. And I want to share my mm with a public url to others without publishing all secrets.