Installing on win 2012 server R2

Struggling with this...

What I want to have is node-red working behind iis via iisnode, basically the same setup as one installs on azure, but this is on a standalone (public) server.

What I have done so far:
Installed node - it works
Installed node-red as per the standard install, ie operated via the node-red cmd. - It works
Installed iisnode and its examples - all work.

What I simply cannot do is get node-red and iisnode to work together.

I set it all up on an azure server with this script https://github.com/jmservera/node-red-azure-webapp which works brilliantly, and it is quite clear the file structure it created is quite different to the one the regular installs have done on my server. However, I don't really think there's much mileage in trying to replicate it without really understand what I'm doing, not least because it appears the ,node-red folder is somehow created dynamically but I've no idea how this is controlled.

Any help or guidance would be much appreciated...

Regards

Richard

So the azure-webapp script seems to use a custom Node-RED install. The module simply installs node-red then creates a custom folder for the userDir. It uses a custom Node.JS app to wrap around Node-RED instead of calling it directly.

I did try NR on an Azure web app a long time ago so I've doubtless forgotten most of it.

But it looks to me as though all you need to do in order to use Node-RED with iisnode is make sure that your settings.js picks up the process.env.PORT environment variable. Then you need to configure your app's web.config file to point to Node-RED's initialisation script, red.js.

I'm afraid that I don't have IIS running anywhere right now so it's a bit difficult to give more specifics.

At last I have got this going.

For the benefit of others, this is what I did -

To understand it you must replace zzzzzzzzzzzz with your website url (this forum won't let me repeat url's)

I wanted it all to work below a subfolder of my site, so set up an iis site zzzzzzzzzzzz/xred

First just try 'hello world' in a .htm file to make sure iis is serving something at zzzzzzzzzzzz/xred/hello.htm

Then copy in hello.js and its web.config file from the iisnode examples and try zzzzzzzzzzzz/xred/hello.js to check iis + iisnode + node are all playing correctly together.

Now the hard part, to get node-red to work - this comes from an idea sparked by @TotallyInformation and the source of the azure implementation node-red-azure-webapp on github, and a lot of looking at its result in an azure site I created with it.

  1. The stock install as per nodered.org/docs/platforms/windows is no good to you; Install node-red again NOT as a global module, in, or close to your new website. I installed it in my /xred folder, so in a CMD box, something like:

cd C:\mywebsites\mysite\xred
npm install node-red

This creates a \xred\node_modules\ folder with all the node-red stuff in it.

  1. I also created a folder tree at C:\mywebsites\nodered\.node-red\ for my userDir but this may not be necessary if it makes it itself on first run, but I wasn't sure (see settings.js below.)

  2. \xred\server.js This is a sort of wrapper for node-red to run in

var express = require("express");
var RED=require('node-red');
var app= express();
var http=require('http');

const PORT=process.env.PORT; //||8000;

var server=http.createServer(app);
var settings=require("./settings.js");

RED.init(server,settings);

app.use(settings.httpAdminRoot,RED.httpAdmin);
app.use(settings.httpNodeRoot,RED.httpNode);
 
server.listen(settings.uiPort);
console.log(`listening port:${settings.uiPort}`);
RED.start();
  1. \xred\settings.js (only important settings shown, everything else to your taste)
module.exports = {
    httpAdminRoot:"/xred/",
    httpNodeRoot: "/xred/",
    userDir:"../../nodered/.node-red/",
    uiPort: process.env.PORT, // || 8000
    }

These 2 Root paths caused me a lot of hair pulling, if they're not exactly right then according to the logs node-red runs but all you get on screen is

cannot GET

which is something to do with express being finicky about paths.

  1. \xred\web.config More or less iisnode stock.
<!--
     This configuration file is required if iisnode is used to run node processes behind
     IIS or IIS Express.  For more information, visit:
     https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->

<configuration>
  <system.webServer>
    <webSocket enabled="false" />
    <handlers>
      <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
       <add name="iisnode" path="server.js" verb="*" modules="iisnode" /> 
	  <!--<add name="iisnode" path="hello.js" verb="*" modules="iisnode"/>-->
    </handlers>
    <rewrite>
      <rules>
        <!-- Do not interfere with requests for node-inspector debugging-->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="server.js\/debug[\/]?" />
        </rule> 

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{PATH_INFO}" />
        </rule>

        <!-- All other URLs are mapped to the node.js site entry point-->
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
          </conditions>
          <action type="Rewrite" url="server.js" />
        </rule>
      </rules> 
    </rewrite>
    
    <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <remove segment="bin" />
        </hiddenSegments>
      </requestFiltering>
    </security>

    <!-- Make sure error responses are left untouched -->
    <httpErrors existingResponse="PassThrough" />

    <!--
      You can control how Node is hosted within IIS using the following options:
      See iisnode on github for a full list of options
    -->
    <iisnode watchedFiles="web.config;*.js" loggingEnabled="true" logDirectory="iisnode" debuggingEnabled="true" />
  </system.webServer>
</configuration>
  1. Now you should be able to navigate to www.mysite.com/xred and node-red will start.

If it says

Not started

I think this means it is re-starting after having detected a change in one of your iisnode watchedFiles , so just wait a bit and refresh the page - bob should be your uncle :grinning:

I didn't get the special iisnode debug feature working as in zzzzzzzzzzzzzzzz/xred/hello.js/debug but it didn't work for me in the stock iisnode examples either - you just get a lot of uncaught syntax errors.

Protect your mode-red server with a password at least

iisnode exposes a folder zzzzzzzzzzzzzz/xred/iisnode/ with useful debug info but obviously rather insecure. The recommendation is to change this folder name in iisnode settings to something very cryptic like a uuid

Richard

Glad you got it working. I've bookmarked your post so I can find it again next time someone asks the same question.

As an addenda to this:

  1. Restart
    node-red sometimes needs a re-start, eg after you have installed a new module - but how to do that?

Possibly you could restart the site in iis or something but the simplest way is to simply edit one of your watchedFiles - just add or delete a space in one of them is enough, and then node-red will restart next time you refresh the editor page.

  1. Loading modules in the gui
    Loading modules via npm and CMD is fine but doing it in the gui fails; In the azure site I made there are two more files which may have something to do with this:

\xred\npm.cmd

:: Created by npm, please don't edit manually.
@ECHO OFF

SETLOCAL

SET "NODE_EXE=%~dp0\node.exe"
IF NOT EXIST "%NODE_EXE%" (
  SET "NODE_EXE=node"
)

SET "NPM_CLI_JS=d:\program files (x86)\npm\5.6.0\node_modules\npm\bin\npm-cli.js"
FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
  SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js"
)
IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" (
  SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%"
)

"%NODE_EXE%" "%NPM_CLI_JS%" %*

and \xred\npm_.cmd

:: Created by npm, please don't edit manually.
@ECHO OFF

SETLOCAL

SET "NODE_EXE=%~dp0\node.exe"
IF NOT EXIST "%NODE_EXE%" (
  SET "NODE_EXE=node"
)

SET "NPM_CLI_JS=d:\program files (x86)\npm\5.6.0\node_modules\npm\bin\npm-cli.js"
FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
  SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js"
)
IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" (
  SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%"
)

"%NODE_EXE%" "%NPM_CLI_JS%" %*

Obviously these might need editing to correct the paths, but on the other hand both say Created by npm, please don't edit manually. so before I try them can someone advise on what these do and how they got there and if I should include them in my new iis site?

Thanks

Richard

You can restart Node-RED from within Node-RED by firstly capturing the PID. Use settings.js to save the current process PID to a global variable. Then use exec to kill the process. Hopefully iisnode should auto-restart it.

If the admin gui is failing to install modules. Either npm can't reach the Internet or the userDir folder is not writable. Can't think of anything else off the top of my head. You might need to think about what account is actually running Node-RED. Is it SYSTEM? You might need to adjust some file/folder permissions.

Hmm.

Perhaps I didn't say that I have not put either of these two .cmd files in my new site.

I thought it's all running under the IIS_IUSRS local account which lets it run in iis and also has full permissions in the site's folders - but in the logs, the error is:

[warn] Error: EPERM: operation not permitted, mkdir 'C:\Windows\system32\config\systemprofile\AppData\Roaming\npm'

Does this suggest is is running in the SYSTEM account after all?

I must say I'm reluctant to play with permissions in the \windows... folder, so perhaps there's another way by altering a PATH setting somewhere?

Richard

That warning is certainly telling you that you can't create a new folder in the location listed. But that shouldn't be a surprise since that is a seriously weird location.

Ha, I didn't even know that location existed!! But it does and it does indeed seem to belong to SYSTEM. But given that your installation is failing to write to it, I'd say that IISnode is almost certainly running as a different user and IIS_IUSRS would be sensible.

Sorry, not sure about changing the config. Maybe you could raise an issue in IISnode?

Incidentally, I note from your file listings further up:

Would seem to indicate that perhaps you have a slightly strange installation. Firstly, you should be using a 64bit installation of Node.JS and therefore of npm. You clearly have a 32bit version installed. Secondly, I don't have a separate npm folder. My npm.cmd (on Windows 10) is in C:\Program Files\nodejs which is where I would expect it to be.

:: Created by npm, please don't edit manually.
@ECHO OFF

SETLOCAL

SET "NODE_EXE=%~dp0\node.exe"
IF NOT EXIST "%NODE_EXE%" (
  SET "NODE_EXE=node"
)

SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js"
FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
  SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js"
)
IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" (
  SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%"
)

"%NODE_EXE%" "%NPM_CLI_JS%" %*

You had me confused for a bit too!

The first one, 'C:\Windows\system32\config\systemprofile\AppData\Roaming\npm' is a (weird) path on my server

The second one is from the install on azure, so not the same box, but an illustration of perhaps what a missing .cmd file should look like which would get loading modules in the gui working.

Since it's not critical (can still load modules in the cmd box) I haven't got round to fiddling with it yet, but will update if I find a fix.

Richard