rewrite requests for always on bot in linux Azure app service - node.js

We are seeing some 404 logs coming from a bot in Azure always On. It trigged every 5min. Our health check is not in the root directory.
We are using Docker image for this, NodeJs 14.x. In documentation, they say to use web.config to redirect some urls but I'm not sure this will work.
<rule name="Redirect AlwaysOn requests from root to custom url" stopProcessing="true">
<match url="^$" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="^AlwaysOn$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/status" logRewrittenUrl="true" redirectType="Permanent"/>
</rule>
and not sure where to put this file in the container. Here's docker file
FROM node:15.0.1-alpine3.10
WORKDIR /usr/src/app
RUN mkdir node_modules
RUN mkdir dist
COPY node_modules node_modules
COPY dist dist
COPY apps/api/.docker/sshd_config /etc/ssh/
COPY apps/api/.docker/init.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/init.sh
ENTRYPOINT ["/usr/local/bin/init.sh"]

404 logs coming from a bot in Azure always On.
Issue can be fixed by rewriting the Always on path.
After a cold start of your application, AlwaysOn will send a request to the ROOT of your application “/”. Whatever file is delivered when a request is made to, / is the one which will be warmed up, it will fail because the root doesn’t exist.
Make AlwaysOn to warmup a specific page instead of the root, implement URL Rewrite rule.
<?xml version="1.0" encoding="UTF-8" standalone="no">
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite AlwaysOn" stopProcessing="true">
<match url="^$" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="^AlwaysOn$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/status" logRewrittenUrl="true" redirectType="Permanent"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
web.config file needs to be added to the node app at the root
If your app has a server.js or app.js file in your Node.js project, the web.config file should be in the same directory.
If you are using Visual Studio Code , then Put web.config file in /public folder, It will then be copied over to /dist folder during build.
I have created the config file in public folder, After running npm run build , web.config file is copied to dist folder.
To create web.config, Right click on the public folder
Add new file, name it as web.config and add the above mentioned code snippet and save.
Go to Azure portal, your Web App =>Advanced Tools=>KUDU - Debug Console =>CMD => site=>wwwroot , check if web.config file exists or not.
If you are using Visual Studio, then select Azure Node.js Express template to craete the Web App, then web.config will be generated automatically.You can edit the settings directly.

Related

Azure web app giving HTTP error 500 when viewed, how can this be fixed?

trying to upload my mobile web application to azure
followed
https://learn.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=windows&pivots=development-environment-vscode
ended up just getting the error unable to handle request HTTP error 500
the web app works locally so i dont know what the issue is
a friend told me it was might be because all webpages in the views folder are .ejs files when they should be HTML.
I have followed the same document which you have provided and able to access the Application without any issues.
Create Node.js Application using the below command.
npx express-generator myExpApp19Dec --view ejs
Navigate to the Application root directory(myExpApp19Dec) and run npm install.
node_modules folder will be created at root of the directory.
Run npm start to start and run the application in local.
Open the Application from VSCode.
Steps to deploy Web App to Azure App Service
Sign into Azure => Click on Azure Icon => Select your Subscription = > App Services.
web app name - ExpressApp19Dec
runtime stack - Node 18 LTS
OS - Windows
Location - East US
Immediately after deployment, when I tried to access the Application, I got the below error.
Added SCM_DO_BUILD_DURING_DEPLOYMENT in Application Setting as suggested in the document.
Navigate to the deployed App folder in VSCode => Your App => Application Settings =>Add New Setting.
We can even add this Application Setting from Azure Portal => App Service => Configuration section. Re-deploy option can be excluded when we add Application Setting from Azure Portal.
Re-deploy the Application to get the latest changes.
Make sure web.config file is created at the root directory of the deployed Application in KUDU Console.
Path to KUDU Console -
https://YourAppServiceName.scm.azurewebsites.net/DebugConsole
My autogeneratedweb.config file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="bin/www" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^bin/www\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{PATH_INFO}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="bin/www"/>
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>
Now Iam able to access the Application.
all webpages in the views folder are .ejs files when they should be HTML.
In VSCode => root folder => app.js file,
app.set('view engine', 'ejs');
This code helps to detect the ejs files. The issue is not with the ejs files.
EJS is an Embedded JavaScript template which is used by Node JS Application.

Subversion behaving weirdly behind reverse proxy

I'm trying to migrate a Subversion server to a different machine, which is also already running IIS. Thus, I configured Subversion to run at port 81, and set up an IIS rewrite rule based on the host name:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="svn.foo.example" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^svn.foo.example$" />
</conditions>
<action type="Rewrite" url="https://svn.foo.example:81/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
In addition, "server proxy settings" are configured as follows (I think I left all of these as defaults):
enable
version pass through
keep alive
120-second timeout
reverse rewrite host in response headers
preserve IP in X-Forwarded-For
(The SVN server is VisualSVN 4.3.4; the IIS is Windows Server 2019 Version 1809.)
Where things get strange is that some stuff works, including on existing working copies. For example, I can:
use an existing working copy
add a file to that folder, and commit it
check that file's log
However:
use an existing working copy
check the log of a folder // works!
check the log of an existing file // does not work!
The latter fails with E160013: File not found. Indeed, if I look in the IIS logs, it returns 404.
If I instead (locally) check out that same file without the reverse proxy, I can get its log, so presumably, it's a problem with the proxying. But then why does it work if I add new files and check their logs?

Deploy on azure continous delivery custom node app

I have a node app that has both a react native front end and a node API
I want to be able to just run npm install for both folders and then just have it run the start command "node server" (node/server/index.js) to have the node app running.
But I can't seem to figure out the release tasks to make this happen.
I am using the preview continous delivery that connects to visual studio online
In my opinion, it has nothing to do with continuous delivery. Since Azure App Service runs on Microsoft IIS, you'll need to have an IIS configuration file named web.config and should include the following section to match your requirement:
<handlers>
<add name="iisnode" path="./node/server/index.js" verb="*" modules="iisnode"/>
</handlers>
This indicates that the node/server/index.js file is a node.js site to be handled by the iisnode module.
<rewrite>
<rules>
<!-- 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="./node/server/index.js"/>
</rule>
</rules>
</rewrite>
These rewrite rules determine where your static content and dynamic content should be located in.
For a completed web.config file you can check this post out.

Deploying react project on Azure

I want to deploy my react project on azure cloud. I already deployed it on heroku and there it was very easy to deploy. I just had to do git push heroku master to deploy it on heroku. But I am clueless on how to do it on azure. So I have a bulid directory in my project which gets generated everytime I run gulp command. It has all the build files. Can anyone please guide me on how to proceed to azure?
This is my project structure
There are many options to deploy your app to azure websites/ web app, such as FTP, Local Git Repository, and Visual Studio IDE, etc. I am not a React expert, here for simplicity, I just use create-react-app tool and FileZilla to deploy my React app to Azure Web App. Here are the steps.
Basically, creating and building React app is as simple as
npm install -g create-react-app
create-react-app my-app
cd my-app/
npm run build
Now, the app is ready to be deployed! Let’s go into Azure portal and create a new website that will host our React app.
Enter a unique app service name, a valid name for the resource group and a new service plan. Then click Save.
To enable FTP publishing, click Deployment credentials under the APP DEPLOYMENT menu. Save the credentials and make a note of the user name and password you create.
Next, click on Properties, and copy the FTP HOST NAME and the USER.
Finally, connect to Azure Web app via FileZilla, then upload the entire content of the my-app/build folder created earlier into the /site/wwwroot/ folder on your Azure Website.
Now we can visit the app in a browser via URL: http://aaronreacttest.azurewebsites.net/,
and it should display the default page.
In addition to steps provided by Aaron, I had to add the web.config file with the content below. It is provided by other techies in their blogs and some forums.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="React Static Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Deploying Express 4.x app to Windows Azure

The new version of Express separates the modules from the "server" file. It now lives in /bin/www and I'd prefer to keep this convention if possible.
In the package.json file, the "start" script clearly points to the right place, but this is seemingly ignored by Azure.
How do I deploy an Express 4.x app without having a server.js file in the root directory? All I need to do is make it automatically call node ./bin/www instead of node server.js. Is there another root configuration file I can add specific to the cloud host (Azure?) This is how I got this working in Heroku, etc.
updated answer
The Azure team has since fixed this internally. A newly deployed express 4 app should work just fine on Azure Websites without any additional changes.
original answer
I'll start with the tl;dr. Create a web.config file in the root of your application and use this xml.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<!--
By default IIS will block requests going to the bin directory for security reasons.
We need to disable this since that's where Express has put the application entry point.
-->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin" />
</hiddenSegments>
</requestFiltering>
</security>
<handlers>
<!-- Indicates that the www file is a node.js entry point -->
<add name="iisnode" path="/bin/www" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^bin\/www\/debug[\/]?" />
</rule>
<!--
First we consider whether the incoming URL matches a physical file in the /public folder.
This means IIS will handle your static resources, and you don't have to use express.static
-->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<!-- All other URLs are mapped to the node.js entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="/bin/www"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
This is a bit of a mess and took a while to track down. I really wish it was smart enough to look at package.json, but this is what we have to deal with for now. Normally Azure determine if it is a Node application by checking for an app.js or server.js file. If it finds that file, it will automatically create a web.config file very similar to what is above. In this case, it will detect app.js, but unlike 99% of other node applications, that's not actually the entry point. What we have to do is change the entry point to /bin/www like shown above.
The other issue we run into is that by default IIS blocks requests to the bin folder for security reasons. We can either rename the express bin folder, or tell IIS to get over it. That's what the hiddenSegments part of the xml file is for.

Resources