refactor: centralize server port resolution (#4198)

I took a look at the last remaining FIXME comment in the code - the one
in `js/app.js` pointing to PR #673. It's from 2017 and was already
flagged as a hotfix back then.

The problem: `MM_PORT` got written into a global `global.mmPort` that
was then read inconsistently across the code - sometimes via the global,
sometimes straight from `process.env`, plus separate logic in
`defaults.js`. Three ways to get the same port.

I pulled this into a single `getServerPort()` helper (`MM_PORT` ->
`config.port` -> `8080`) and switched `app.js`, `defaults.js`,
`server.js`, `electron.js` and both serveronly files over to it. The
global is gone now.

Basically the behavior should be unchanged.
This commit is contained in:
Kristjan ESPERANTO
2026-07-08 00:52:17 +02:00
committed by GitHub
parent 0bb9b5ff42
commit df6170c596
7 changed files with 21 additions and 22 deletions
-6
View File
@@ -42,12 +42,6 @@ if (process.env.MM_CONFIG_FILE) {
global.configuration_file = process.env.MM_CONFIG_FILE.replace(`${global.root_path}/`, "");
}
// FIXME: Hotfix Pull Request
// https://github.com/MagicMirrorOrg/MagicMirror/pull/673
if (process.env.MM_PORT) {
global.mmPort = process.env.MM_PORT;
}
// The next part is here to prevent a major exception when there
// is no internet connection. This could probable be solved better.
process.on("uncaughtException", function (err) {
+2 -9
View File
@@ -1,13 +1,6 @@
/* global mmPort */
const address = "localhost";
let port = 8080;
if (typeof mmPort !== "undefined") {
port = mmPort;
}
const defaults = {
address: address,
port: port,
address: "localhost",
port: 8080,
basePath: "/",
useHttps: false, // Support HTTPS or not, default "false" will use HTTP
httpsPrivateKey: "", // HTTPS private key path, only required when useHttps is true
+2 -1
View File
@@ -4,6 +4,7 @@ const electron = require("electron");
const core = require("./app");
const Log = require("./logger");
const { applyElectronSwitches } = require("./electron_helper");
const { getServerPort } = require("#server_functions");
// Config
let config = process.env.config ? JSON.parse(process.env.config) : {};
@@ -101,7 +102,7 @@ function createWindow () {
}
const address = (config.address === void 0) | (config.address === "") | (config.address === "0.0.0.0") | (config.address === "::") ? (config.address = "localhost") : config.address;
const port = process.env.MM_PORT || config.port;
const port = getServerPort(config);
mainWindow.loadURL(`${prefix}${address}:${port}`);
// Open the DevTools if run with "node --run start:dev"
+2 -2
View File
@@ -11,7 +11,7 @@ const { ipAccessControl, socketIpAccessControl } = require("./ip_access_control"
const vendor = require("./vendor");
const { getHtml, getVersion, getEnvVars, cors } = require("#server_functions");
const { getHtml, getVersion, getEnvVars, getServerPort, cors } = require("#server_functions");
/**
* Server
@@ -21,7 +21,7 @@ const { getHtml, getVersion, getEnvVars, cors } = require("#server_functions");
function Server (configObj) {
const config = configObj.fullConf;
const app = express();
const port = process.env.MM_PORT || config.port;
const port = getServerPort(config);
const serverSockets = new Set();
let server = null;
+11 -1
View File
@@ -251,6 +251,16 @@ function getEnvVars (req, res) {
res.send(obj);
}
/**
* Resolves the HTTP server port. The `MM_PORT` environment variable takes
* precedence over the configured port, falling back to 8080.
* @param {object} [config] the configuration to read the port from (defaults to global.config)
* @returns {number} the port the server should listen on
*/
function getServerPort (config = global.config) {
return Number(process.env.MM_PORT || config?.port || 8080);
}
/**
* Get the config file path from environment or default location
* @returns {string} The absolute config file path
@@ -269,4 +279,4 @@ function getConfigFilePath () {
return path.resolve(global.configuration_file || `${global.root_path}/config/config.js`);
}
module.exports = { cors, getHtml, getVersion, getStartup, getEnvVars, getEnvVarsAsObj, getUserAgent, getConfigFilePath, replaceSecretPlaceholder };
module.exports = { cors, getHtml, getVersion, getStartup, getEnvVars, getEnvVarsAsObj, getUserAgent, getServerPort, getConfigFilePath, replaceSecretPlaceholder };
+2 -1
View File
@@ -1,8 +1,9 @@
const app = require("../js/app");
const Log = require("../js/logger");
const { getServerPort } = require("#server_functions");
app.start().then((config) => {
const bindAddress = config.address ? config.address : "localhost";
const httpType = config.useHttps ? "https" : "http";
Log.info(`\n>>> Ready to go! Please point your browser to: ${httpType}://${bindAddress}:${global.mmPort || config.port} <<<`);
Log.info(`\n>>> Ready to go! Please point your browser to: ${httpType}://${bindAddress}:${getServerPort(config)} <<<`);
});
+2 -2
View File
@@ -7,7 +7,7 @@ const path = require("node:path");
const net = require("node:net");
const http = require("node:http");
const Log = require("logger");
const { getConfigFilePath } = require("#server_functions");
const { getConfigFilePath, getServerPort } = require("#server_functions");
const RESTART_DELAY_MS = 500;
const PORT_CHECK_MAX_ATTEMPTS = 20;
@@ -32,7 +32,7 @@ function getServerConfig () {
delete require.cache[require.resolve(configPath)];
const config = require(configPath);
serverConfig = {
port: global.mmPort || config.port || 8080,
port: getServerPort(config),
address: config.address || "localhost"
};
} catch {