clustering node on iisnode using nodeProcessCountPerApplication - azure

I have a web app in Azure which is using node.js and socket.io, and I decided to use the clustering supported by IISNODE, using nodeProcessCountPerApplication as below in my web.config
<iisnode nodeProcessCountPerApplication="0" />
However, when I apply this, I got 500.1013 internal server error, which states:
Most likely causes:
IIS received the request; however, an internal error occurred during the processing of the request. The root cause of this error depends on which module handles the request and what was happening in the worker process when this error occurred.
IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly.
IIS was not able to process configuration for the Web site or application.
The authenticated user does not have permission to use this DLL.
The request is mapped to a managed handler but the .NET Extensibility Feature is not installed.
I looked for examples but couldn't find anything similar. I am wondering what I am doing wrong here. I want to be able to use all processors of my machine.
Thanks !

I was able to use all processors of my App Service plan by using the following web.config file.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^app.js\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="app.js" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin" />
</hiddenSegments>
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
<iisnode watchedFiles="web.config;*.js" devErrorsEnabled="true" nodeProcessCountPerApplication="0" />
</system.webServer>
</configuration>
As you are using socket.io on Azure Web App, you'll also need to set Web sockets to On in the Azure portal. See Using socket.io-redis on azure web service.

Related

URL Rewrite in case of verbs PUT and DELETE with iisnode

This is a follow-up question to my previous one, focused on the fact that I'm getting a 404 error when I try to call a DELETE or a PUT verb for an Node.JS application on IIS configured with iisnode and URL Rewrite as follows:
<handlers>
<add name="iisnode" verb="*" path="app.js" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="my app rule" stopProcessing="true" patternSyntax="Wildcard">
<match url="*" />
<action type="Rewrite" url="app.js" />
</rule>
</rules>
</rewrite>
The script app.js is not even called, the url is not rewritten.
Is it a well known bug or what else am I supposed to do?
No issues for GET and PUT verbs instead (and of course I've already implemented a workaround using the latter).
That was due to the Request Filtering of IIS (tab HTTP Verbs)
Added there the missing verbs as shown in the screenshot below and problem solved.
As text, directly inside the system.webServer of the web.config:
<security>
<requestFiltering>
<verbs>
<add verb="PUT" allowed="true" />
<add verb="DELETE" allowed="true" />
</verbs>
</requestFiltering>
</security>

Deploying server-side NodeJS app on Windows-based Azure App Service (CI/CD Using Azure DevOps)

Our use case consists of the following aspects:
Ci/CD Using Azure Devops in order to ensure automation and monitoring.
Azure AppService based on windows
Our React projects consists of: Frontend asking a server-side script (server.js) for a url to embed.
server.js performs some authentications and modifications and returns a single url "live" for a specific period of time.
Running on local station using npm start and starting the server using node of course works perfectly.
But when deploying to a windows-based AppService, I cant see how to start the server.js.
My CI is npm installing and ZIPing the artifact.
CD is deploying the artifact and serving the index.js web page.
But I cant seem to see how to start the server.js file.
Feels like I am missing some important piece regarding IIS and web.config
you could try to add the below code in your web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>

Nothing happens when using method history.replaceState

I use azure app services for my nuxt application but when i use history.replaceState it doesnt replace the url. Running it on production on my own pc works fine but when I deploy it to azure it seems like its not doing anything. Maybe I did something wrong in my web.config?
(I also tried using this.$router.replace() which has the same results.)
selectBrand (brand) {
const errors = JSON.parse(JSON.stringify(this.error))
history.replaceState({}, null, window.origin + '/error/'+brand);
this.selectedBrand = brand
this.errorList = this.error.filter(name => name.cBrandname.includes(brand))
}
Here is my web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
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>
<!-- Visit https://azure.microsoft.com/en-us/blog/introduction-to-websockets-on-windows-azure-web-sites/ for more information on WebSocket support -->
<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" 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\/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{REQUEST_URI}"/>
</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"/>
</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:
* watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
* node_env: will be propagated to node as NODE_ENV environment variable
* debuggingEnabled - controls whether the built-in debugger is enabled
See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
-->
<!--<iisnode watchedFiles="web.config;*.js"/>-->
</system.webServer>
</configuration>
Thanks for raising the question and contributing to Stack Overflow.
Reiterating the answer from what Jason has mentioned as this should be solution for the problem you're facing .
Just create a sample Nuxt App and try to publish it again and see if it helps.

Query/headers too large on Azure if auth enabled

I have a node/express app that works great locally. I have uploaded it to Azure Web App and it works fine as long as I do not enable authentication. When I enable AAD auth, the app fails with STATUS 500.1011 "Bad Request". I have quite a few query parameters in the url. If I reduce the length of the parameters sufficiently the app load fine again. It seems there is some limit on the query/headers in Azure?
I have tried for several hours now to fix this, but I think I have to admit defeat. I thought maybe this would fix it, but it does not seems like it.
This is my current web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="true" />
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<requestLimits maxQueryString="32768" maxUrl="65536"/>
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>
I think I found the problem. Node reduced max header size from 80kb to 8kb in November 2018.
There is lots of discussion about it here and here.
I tried increasing max-http-header-size, but could not get it to work on Azure. So my solution for now is to use an older version of node. Hoping there will be a solution posted in those discussions eventually.
just add the --max-http-header-size in the iisnode.yml, as for the details of passing Flag to NodeJS's chrome V8 in Azure Appservice: Pass flags to NodeJS's Chrome V8 engine in Azure Web Apps

Azure AppService NodeJs with virtual directory

I have a website built on Angular7 with server side rendering deployed on an Azure App Service. I had to add a web.config file in order to make the server.js run.
Here's the web.config file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="server.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>
<!-- 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>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>
This site is deployeed to mysite.com and everything works fine.
I now need to create a virtual directory mysite.com/app to hold a different application (on the old AngularJS). Without the server side rendering I just create the virtual directory on Azure Portal and everything works fine. Because of the server side and the "redirection" to server.js the virtual directory is no longer working.
Is there any Rule to put on the web.config file to ignore the requests of /app, not to run the nodejs server?
I got my response on another question (credit to dana) so I've just added the rule
<rule name="ignore app application" stopProcessing="true">
<match url="^app" />
<action type="None" />
</rule>
before the other rules. This way if the url typed is mysite.com/app the node server won't be "activated" and the virtual directory works as expected.

Resources