As mentioned in Formalising reusable functions with autocompletion, parameter hints, click-through-navigation - #16 by TotallyInformation
One thing that seems to be less than ideal, for anyone wanting to run more than 1 instance of Node-RED on the same device, is that you have to do something to change the Node-RED port number. This can be done in settings.js (after first run) or by setting a PORT environment variable prior to launch (which is a different process on Windows to Linux/Mac).
Now, node.js does have all the tools available to be able to work out a free port. However, from a user perspective, the only place you can put some extra tooling is in settings.js and that runs as a commonJS, synchronous module so it does add some complexity.
The real question I have is - is there any interest in having a built-in solution to automate discovery of a free port (starting with the default 1880 of course)?
For reference, here is an example of code you can add to settings.js to automatically set a viable port.
Add this to the top of your settings.js:
const { spawnSync } = require('child_process')
/** Find a free http port
* Has to spawn a child process because it needs to run asynchronously to the main process
* @param {number} startPort - the port to start searching from
* @returns {number} - the free port
*/
function getAvailablePort(startPort = 1880) {
const code = `
const net = require('net')
function isPortAvailable(port) {
return new Promise((resolve) => {
const server = net.createServer()
server.once('error', () => resolve(0))
server.listen(port, '0.0.0.0', () => {
server.close(() => resolve(port))
})
})
}
(async () => {
let port = ${Number(startPort)}
while (!(await isPortAvailable(port))) { port++ }
process.stdout.write(String(port))
})()
`
// const output = execSync(`node -e "${code.replace(/\n/g, ' ')}"`, { encoding: 'utf8' })
const output = spawnSync(
process.execPath,
['-e', code]
)
return parseInt(output.output[1].toString(), 10)
}
Then replace the line that says uiPort: process.env.PORT || 1880, and replace with:
uiPort: process.env.PORT || getAvailablePort(1880),
