DEV Community

Hosting a Node.js application on Windows with IIS as reverse proxy

Peter Eysermans on March 27, 2019

Unfortunately a lot of companies are still stuck with Windows servers. Nobody ever got fired for choosing Microsoft, right. As a developer this can...
Collapse
 
emilmarlo profile image
Emil Marlo Red

Hi Peter, I came across this post because I want to deploy my node app in our windows server. Luckily this article looks great for my requirement. I'm just having a difficulty with the configurations of the bindings of my site. May I look on your site bindings? Should it be the same with the port I'm running on my Node App?

Collapse
 
petereysermans profile image
Peter Eysermans • Edited

The bindings of your site should be on port 80 for http and port 443 for https. Setting the same port as your node.js app in the bindings will not work. The port of the node.js app should only be set in the reverse proxy rules of IIS as you can see in the screenshot of the article.

Collapse
 
emilmarlo profile image
Emil Marlo Red • Edited

Oh, I see. Thanks for replying Peter. However, I don't think that URL Rewrite is working fine for me because I get a DNS_fail error. I am sure that I have followed and installed ARR and URL Rewrite and included the inbound rule for my site. As you can see in the image below, I'm running my node express server on port 3030. How about the physical path? As far as I know, I should point it to the folder where it contains my app.js, node_modules, etc. right?

Thread Thread
 
emilmarlo profile image
Emil Marlo Red

Also, how do I attach an image here? LOL. I'm just a new member here :c

Thread Thread
 
petereysermans profile image
Peter Eysermans

Yes, the physical path is pointing to the folder where the application is. In my case there is a web.config file in there with some rewrite rules, for example a redirect from http to https. Maybe if I see the exact error I will get an idea of what the problem is.

Adding an image is a bit cumbersome, I had to search for it myself. First you upload the image via the 2nd button in the left bottom corner. Then you can reference the url you get next to the icon in markdown. But you have to write the markdown yourself, otherwise your image will not be included.

Thread Thread
 
emilmarlo profile image
Emil Marlo Red • Edited

Wow! Ok, so this is the error that I receive. Hopefully I've attached the image properly. Thanks for assisting me.

error

Thread Thread
 
petereysermans profile image
Peter Eysermans

This rather looks like a DNS problem. Is there a DNS record for rlcnodetesting.rlc.corp.jgsummit.com pointing to the IP of the server where IIS is running? And is the subdomain in the bindings of IIS itself on port 80?

I would turn off the reverse proxy first and point the IIS website to a physical path with a static HTML file. That way you can ensure that the IIS binding and the DNS settings for that subdomain are working. Once that is verified, you can add the reverse proxy and go from there. It will be easier to troubleshoot where the problem resides.

Thread Thread
 
emilmarlo profile image
Emil Marlo Red

Dude! I think it's working, my problem would be the DNS itself. I'll ask our network administrator regarding this. But definitely, the URL rewrite is working. I just made it blank on my hostname to make it work. Thanks so much!!

site-binding

Thread Thread
 
petereysermans profile image
Peter Eysermans

Great, well done. I'm glad you figured it out.

Collapse
 
scottermonk profile image
ScotterMonk • Edited

Hi Peter -
Thanks for responding to my last question.
OK... I started over. Reinstalled node.js on my Windows 2016 Server.
When I do "pm2 show," I see app.js is running.
"node app.js" worked great from the command prompt. As in, it outputs what it should, within the command prompt window.
I set up the reverse proxy rule in iis for my test site's domain name "amonkeymarket.com".
If you go to amonkeymarket.com/app.js, you will just see the code, not execution of the code. This happens whether I go there with a local browser on the server or remote.
Ideas?
THANK YOU!

Collapse
 
petereysermans profile image
Peter Eysermans

So the reverse proxy kind of works as you are seeing the app.js file which is part of the node.js application. Does it work if you directly go to the node.js application on the server? I mean opening a browser on the server and going to localhost:3000 (or the port you used), does that work?

Collapse
 
scottermonk profile image
ScotterMonk

Thanks, Peter!
Yes, when I use "localhost:3000/app.js" it works; returning "Hello world" to the browser.

Thread Thread
 
petereysermans profile image
Peter Eysermans

It is strange that you append app.js to the end of the url. I would expect that the command to run your application is node app.js and that you access your application via the url localhost:3000. Not via localhost:3000/app.js, is this a typo?

Thread Thread
 
scottermonk profile image
ScotterMonk • Edited

Oh sorry for the added confusion. It makes no diff whether I add that /app.js or not (just re-tested). I was doing so because I had a few .js files there to try different tests. Thanks for hanging with me on this, Peter! Deadline approaching and I'm worried.

Thread Thread
 
petereysermans profile image
Peter Eysermans

Unfortunately at the moment I don't have any more input to give you without being able to see the code and the configuration. Most of the time it helps to check every part independently but it looks like you double checked every part and setting. If I can help any further please let me know.

Thread Thread
 
scottermonk profile image
ScotterMonk • Edited

I hear you. Thanks for the amount you tried to help.
UPDATE: Got it working!
I had set up the URL Rewrite redirect rule wrong.
THANK YOU SOOO MUCH!
I was lost [in iisnode hell] before finding your article.

Collapse
 
scottermonk profile image
ScotterMonk

Hey Peter -
Having a new issue I wonder if you can help with.
When I change the code of my "sign_in.js" file, then go to the site, the old "Hello World" coming up. I'm betting I have something misconfigured. Hoping you are up for looking at this stuff:
ecosystem.config.js:

module.exports = {
  apps : [{
    name: 'API',
    script: 'sign_in.js',

    // Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
    args: 'one two',
    instances: 1,
    autorestart: true,
    watch: true,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'development'
    },
    env_production: {
      NODE_ENV: 'production'
    }
  }],

/*  deploy : {
    production : {
      user : 'node',
      host : '212.83.163.1',
      ref  : 'origin/master',
      repo : 'git@github.com:repo.git',
      path : '/var/www/production',
      'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production'
    }
  }
  */
};

Enter fullscreen mode Exit fullscreen mode

and for PM2, here's an image:
clearsay.net/images/2019-09-05-pm2...
I'll also try to use their "upload image" option here that didn't work in the past for me.

Collapse
 
petereysermans profile image
Peter Eysermans • Edited

Did you already figured it out? I have not encountered this problem before. Maybe kill all the processes and just start the sign_in.js app and test what IIS is serving? You probably already tried it but I would start with the simplest case and try to get it to work.

Totally unrelated but you can name your applications in pm2 when you start them with the --name <app_name> parameter. It makes it easier to identify them.

The image upload worked.

Collapse
 
scottermonk profile image
ScotterMonk

Hey Peter -
I didn't. Then I realized - after having some other issues with Node.js and then studying Python some - that I would switch gears and learn Python instead. Proved to be easier to set up on Windows Server AND easier to write code in.
Thanks for checking in!
Scott

Thread Thread
 
snehati24742628 profile image
sneha tiwari

Hey @scottermonk I need to serve flask APIs on HTTPS in windows server. Can you help me ? I am unable to find any solution.

Collapse
 
nybondasto profile image
Tomas Nybondas

Thanks for this great article!

It filled one big gap in my puzzle... :) In turn, I'd like to share with you an article: "The easiest way to install a node.js script as a windows service" here: github.com/tallesl/qckwinsvc and here: npmjs.com/package/qckwinsvc

I think that would be a good solution to keep application running in a managed and standardized fashion on a Windows server. At least administrators would thank you for this! :D

With best regards, Tomas.

Collapse
 
petereysermans profile image
Peter Eysermans • Edited

Thanks for the suggestion, I like it. I've solved this by using a task in the Task Scheduler to restart pm2 whenever the server restarts. I use pm2 resurrect for this.

Collapse
 
nybondasto profile image
Tomas Nybondas

That'll do just fine as well! ;)

Collapse
 
balasani profile image
Raghavender Balasani

Can you help more on this steps.

Collapse
 
stelco profile image
Steven Collins

Hi, I found this tutorial very useful with getting the production version of our React/Express app working. We can now access localhost:5000 via localhost and our external domain.
One issue I am having is that every time I do a new build on the dev server, I get this error: EPERM: operation not permitted, unlink 'F:\inetpub\wwwroot\build\web.config' and I have to delete the web.config file and add the rule again in IIS.
Is there a way to avoid this do you know?
Thanks.

Collapse
 
petereysermans profile image
Peter Eysermans

Is there a reason why the build touches the web.config? The web.config is configure once and then forget. You could build your node.js application in another folder to avoid the build changing the web.config file for the reverse proxy.

I have not encountered this problem myself.

Collapse
 
stelco profile image
Steven Collins • Edited

Yes because I have IIS pointing to the build folder to run the app. There is a reverseProxy URL rewrite rule set in IIS which gets saved in the build folder.

web.config in build folder looks like this...
thepracticaldev.s3.amazonaws.com/i...

Could it be moved into the root of the project..? Im not sure how to edit it to do this.

Thread Thread
 
petereysermans profile image
Peter Eysermans

It might work if you move it into another folder and change the basic settings of the IIS website to the new folder? That way the node application can run via pm2 from the build folder and IIS is pointing to the other folder. The web.config is then never changed by the build.

Thread Thread
 
stelco profile image
Steven Collins • Edited

OK thanks I will try this when I get a chance.
Another issue im having which you may be able to help with is that we use a Virtual Machine to host the front end of our website. After installing PM2 globally under my login (the one I use to log on remotely to start a session), I am finding that PM2 only runs once I start a new session because the servers are only available up until 10pm and then restart at 7am. This means I have to start a new session each morning before PM2 starts and therefore starts the Express server. Ive also tried installing PM2 as a dependency in my project but not having much luck with it. Thanks.

Thread Thread
 
petereysermans profile image
Peter Eysermans

I am currently looking into this myself. There is a npm package but I still have to try it out myself. This Stackoverflow question might also give some answers.

Collapse
 
superdistros profile image
Kevin Williams

Hi Peter,

This was the single best resource for quickly resolving/troubleshooting errors related to running a NodeJS app and another application both over SSL. Many other resources–even for Windows–point to using NGINX which wasn't required at all.

Thanks, much appreciated.

Collapse
 
petereysermans profile image
Peter Eysermans

Thank you for the kind words, Kevin. Glad to hear that the post was helpful.

Collapse
 
jmanuel_velasco profile image
JManuel • Edited

Hello, this is a great solution and help me to deploy the API following IT restrictions I have. Thanks for sharing it!. However, I found a problem I don't know if it is posible to solve, if it is, I need help to figure out how.

I have a non-node API published under a domain (api.example.com) listening on 443 (on IIS, that is why I am here :/)
We need to publish a node API and since IT doesn't allow to open different ports than 80 and 443, I have found the reverse proxy a great solution. I have achieved to set up everything and serve the API correctly. In the root folder where api.example.com is I added the following rewrite rule

            <rule name="ReverseProxyInboundRule1" stopProcessing="true">
                <match url="^my-node-api/(.*)" />
                <action type="Rewrite" url="http://localhost:3000/{R:1}" />
            </rule> 
Enter fullscreen mode Exit fullscreen mode

And I am able to request:
api.example.com/my-node-api/
endpoints perfectly.

Now the problem:
In the web.config where I set up the rewrite rule, I need to have customHeaders section to define CORS, besides the rewrite section I also have the following section in the web.config file:

    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="https://www.example.com" />
            <add name="Access-Control-Allow-Methods" value="PUT,GET,POST,HEAD,DELETE" />
            <add name="Access-Control-Allow-Headers" value="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" />
            <add name="Access-Control-Allow-Credentials" value="true" />
        </customHeaders>
    </httpProtocol>
Enter fullscreen mode Exit fullscreen mode

The problem is the node-api can't manage the "Allow-Origin" by its own because it is taking the web.config definition from its main domain "api.example.com" too, so at the end there are two different allow origin values and it is blocked by CORS when trying to consume my-node-api from another domain than example.com.

I can't use * because I need Allow-Credentials set to true, and * is not valid in this case.

I think if the httpProtocol customHeaders settings could be not inherit from child applications (I mean following the description I shared, "my-node-api" application) it will work, since I will be able to manage the allowed origin in the node-api without getting the customHeaders defined in the parent application (api.example.com)

Is that possible ?
how can I do it if this is the case?

I will appreciate any hint/advice, even a confirmation what I am trying to achieve is not posible, having this reverse-proxy solution working restricted to a site only.

Thanks for your time!
·_-

Collapse
 
petereysermans profile image
Peter Eysermans

Is there a reason why your node api is in a subfolder of your non-node api? The node api can perfectly reside in a different folder and be run from there. Next to that, the folder where the IIS website for the reverse proxy is pointing to does not have to be the node api folder. You can put the web.config in a separate folder and point the reverse proxy website to that folder. Hope this helps you further.

Collapse
 
jmanuel_velasco profile image
JManuel

Hello,

oops, I am late... I didn't realised I had a comment

Yes. We have only certain domains allowed to use due to WAF protection and only 80 and 443 ports are enabled, so I only have one IIS Site binding to publish different APIs.

api-domain.example.com

What I have done is to publish the initial API binding to the domain in a separate internal IIS site, and from the api-domain.example.com site definition I have another reverse proxy rule for it.

<rule name="Backend API ReverseProxyInboundRule" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://my-backend-api.example.com/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode

together with the ones for my node APIs

<rule name="NodeAPI ReverseProxyInboundRule1" stopProcessing="true">
<match url="node-api-1/(.*)" />
<action type="Rewrite" url="http://localhost:3000/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode
<rule name="NodeAPI ReverseProxyInboundRule2" stopProcessing="true">
<match url="node-api-2/(.*)" />
<action type="Rewrite" url="http://localhost:8000/{R:1}" />
</rule>
Enter fullscreen mode Exit fullscreen mode

Like so I can apply the site httpprotocol definitions only to my-backend-api.example.com site binding definition, and let node to manage the CORS from the application.

At least this has been my final undertanding and how I have deployed,
If something is not correct, happy to know.

If this helps someone, glad to know.

Cheers,
·_-

Collapse
 
nightzsze profile image
nightzsze • Edited

Really thank you Peter.
I still can't believe it's so easy to solved, I have struggling in so called iisnode for hours.
By the way, the rules and patterns can be used for reverse multiple requests, in my case I host dozens websites on express, but only one website in IIS with several rules and patterns to reverse proxy them all.
It's quite easy even compare with Nginx...

Collapse
 
petereysermans profile image
Peter Eysermans

Glad it worked out for you.

Very interesting, are you using the rules and patterns to route the request to the correct node.js app based on the web address/domain name the user is requesting? I am curious how it works.

Collapse
 
nightzsze profile image
nightzsze • Edited

Yea, it's works like kind of gateway proxy.

I have about 10 sites host in node.js, each of them has different name like entity identity logger, so in server they look like 'localhost:9000/entity', 'localhost:9000/identity'.

Then is the magic part, in the IIS reverse rule I added some regex expression, basically it will match the request with '/entity' or '/identity', and the match result can be used in redirect action like that: 'localhost:9000/{R:1}', so I am able to host as much as possible app in node.js, and just host a website with the specify regex expression for reverse all requests.

Collapse
 
kirvt profile image
kirvt

Hi! Thnx for the article. Seems that there will be some troubles with res.redirect('example.com'). I've got succeed with res.redirect('../local_route'), but everything with external URIs not working.

Collapse
 
petereysermans profile image
Peter Eysermans

Hi, I would have to try it out. If I have the time I'll do some testing.

Collapse
 
vv619perf profile image
vv619-perf

Hi Peter,
We have configured the IIS server with pm2 for nodeJs and configured as suggested in the post but when we try to do a res.redirect('') from the nodeJs code, it's not allowing us to redirect.
For example, calling API URL api-example/redirect it should redirect to
angular-website/success?type=1 but the URL is shown as api-example/success?type=1
Thanks for any help you can give!

Thread Thread
 
petereysermans profile image
Peter Eysermans

Without code it's hard to determine the problem. Is the nodejs application redirecting to the internal URL instead of the actual URL that is used to access it via IIS?

Collapse
 
brunoarcoverdediniz profile image
BrunoArcoverdeDiniz • Edited

Hi Peter,

I have a nodeJS app with a express server running on port 443. I followed your steps and my index.html seems to work using hostname:443 in the Url. but when i login and it redirects to home.html (as supposed to) page. But it starts using localhost:443/home.html once again. How to i get rid of the localhost:443 in the home.html pages as well?

Collapse
 
brunoarcoverdediniz profile image
BrunoArcoverdeDiniz • Edited

I added a second reverse proxy rule with localhost:443/home.html... But didn't work
What else would i need to do to make the other pages in my app change as well ?

Collapse
 
petereysermans profile image
Peter Eysermans

If you use IIS as a reverse proxy you should not see the port of the nodejs application in your URL. IIS forwards the request to the nodejs application without the user noticing. Port 443 is the default port for https connections, I would not use it as the port for the nodejs application. I recommend changing the port to a port that is not commonly used, somewhere in the 3000 range for example.

Collapse
 
ahardworker profile image
Ayman • Edited

Hello Peter,

What a great article, thanks for sharing. PM2 is definitely nice to know. Everything works great and have now hosted my nodejs server on Windows.

However, I keep getting a 502.3 Bad Gateway whenever my request takes more than 2 minutes. So i'm guessing its a timeout issue. However, I can't seem to find where to change the timeout... Do you have any clue?

Collapse
 
petereysermans profile image
Peter Eysermans

Hello Ayman,

I haven't encountered this myself but I think you should try to determine where the timeout is happening. Is it IIS that is giving the timeout or is it node.js. Can you execute the request on the local machine directly to the node.js process? If it is giving a timeout then the first thing to do is increase the timeout for the node.js process.

Collapse
 
thrinesh11 profile image
Thrinesh11

Hi peter,Luckily i found this article to deploy the nodejs i had followed the same steps you had mentioned it is working fine but only thing is it is not working in internet it is working only in internet can you please help me on that.

Collapse
 
akintolastephen profile image
AKINTOLA STEPHEN IYANU

Please I still have issues accessing what I deployed following your every steps.
Only condition here is on what section or path would I do the Site Binding on IIS ?
I guess a screnshot will help.

Thank you

Collapse
 
kamilcglr profile image
kamilcglr

Hello, I am new to IIS and I have a little problem. I don't know if I'm missing something.

Here is my problem :
I want to redirect traffic from outside (mynewapp.domain.fr) to this app.
So I created a site, with the following link:
type : https
name of host: mynewapp.domain.fr
port : 9998
IP address : *

And in reverse proxy I have this adress : localhost:3000
But it doesn't seem to be working, thank you in advance for your help.

There is already an asp site running on :
app.domain.fr:9999

Collapse
 
petereysermans profile image
Peter Eysermans

Can you elaborate on what error message you are receiving? Is the node.js application accessible on the server when you go to localhost:3000? I would first troubleshoot the IIS configuration and the node.js website separately to ensure that they work. After verifying you can try to configure the reverse proxy and check if it works.

Collapse
 
erik_borgen profile image
Erik Borgen

Hi,
Works perfect for me using app.send. Now I need to use SSE (app.write) and having an open HTTP-connection. Is that possible?
The ap I am testing does work when I test using localhost from the browser.
I have tried without changing anything in the IIS setup. And that does not work.

Collapse
 
petereysermans profile image
Peter Eysermans

Hi Erik, I have not used it in that scenario yet. I'm afraid I can't really help you further in this matter. If I have the time I will try it out. If you find a solution let me know.

Collapse
 
herbert2122 profile image
Herbert2122

Peter I did everthing explained on the article, and my node.js application it's running just on the intranet, trough the internet it's not working, but the port can be seen by the web I already test it, and if I put a regular website on the folder, it's showing in the web,but my node.js aplication won't, don't give a error, just a timed out connection, What Am I doing wrong?

Collapse
 
petereysermans profile image
Peter Eysermans

Hey Herbert,

The node.js port should not be exposed to the web. It is served on port 80 by IIS as the reverse proxy. The node.js port should only be accessible internally on the server. Maybe something went wrong there?

Collapse
 
scottermonk profile image
ScotterMonk • Edited

Hi Peter -
Thank you for giving me hope!
I'm getting a 502 Bad Gateway error:
"Web server received an invalid response while acting as a gateway or proxy server."
Windows Server 2016.
Please see attached image of pm2 status of the app.
Oh and how do you determine that port of 3000?
Should I have put "localhost:3000" in that rule or the physical path to my app?
Thanks for any help you can give!

Collapse
 
petereysermans profile image
Peter Eysermans

Hi,

I can't see the image, I think you forgot to link it in your comment. Is the node application accessible on the server itself from localhost:3000? When exactly are you receiving that error?

The port is configured in node. The app.listen statement takes the port on which the node application will listen.

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

If you change that number, the application will listen and be accessible on a different port.

Collapse
 
abhishekhingu profile image
abhishekhingu

How can I host two different expressjs app using IIS

Collapse
 
petereysermans profile image
Peter Eysermans

I have not tested this out but the express js apps would both run on a different port. For example one app would run on port 3000, the other on port 3001. In IIS you'd have to create two websites with the reverse proxy settings from one website pointing to localhost:3000 and the other pointing to localhost:3001.

Collapse
 
jmanuel_velasco profile image
JManuel

Yes, this is exacly how it works.
You can have both API published from the same main domain as well.

your-api.domain.com/api1
your-api.domain.com/api2

By defining the reverse proxy rules in the same IIS site.

Collapse
 
maarlon1 profile image
Maarlon1 • Edited

Hi Peter

I have spent over a week to make Vue SPA / Node application work on MS 2016 IIS 10 server and after countless hours of painful searching and trial and error I luckily found your excellent article. Thank you very much for saving me! It shows again that simplest solutions are the smartest.

Dan

Collapse
 
petereysermans profile image
Peter Eysermans

Hi there, glad you liked it!

Collapse
 
jesben profile image
jesben

Hi Peter

Great article, thanks! :)

I also spent many hours on getting iisnode to run well.

Challenges I had with iisnode:

  • Node js app shuts down about an hour after if no one is using the site, even if I preload, autostart and always running turned on it it didn't help. So it took a few seconds to start up again for the first visit after shutdown.
  • When using websocket, only xhr polling works, websocket ws/wss is not working.
  • Unstable when using Windows authentication (A lot of http 400 errors).

I'm only using reverse proxy (ARR 3) now :)

I'm also a fan of PM2, also running it as a Windows service.

In my setup I need Windows Authentication and Websocket

Windows Authentication

Have tried with NodeSSPI is not working behind a reverse proxy.

URL rewrite is running before Windows authentication, so impossible to attach LOGON_USER in the header that way.

The solution here is:
ISAPI_Rewrite 3 LITE (Freeware)
helicontech.com/isapi_rewrite/down...

C:\Program Files\Helicon\ISAPI_Rewrite3\httpd.conf

RewriteBase /
RewriteCond %{REQUEST_URI} ^/.*
RewriteHeader X-Remote-User: .* %{REMOTE_USER}

E.g. for Express middleware

app.use(function (req, res, next) {
    if (req.headers.hasOwnProperty('x-remote-user')) {
        req['user'] = req.headers['x-remote-user'];
    }
    next();
});

The IIS site has Windows authentication enabled and with these providers: Negotiate, NTLM.

It gave me unfortunately these challenges when users visit the site for the first time (Tested with Chrome, Edge. In IE the error was constant)

401 
400 (X-ARR-CACHE-HIT=0&X-ARR-LOG-ID=7f1e3067-1a02-4405-b275-000f06952bc2&SERVER-STATUS=400)

This was driving me insane, then I turned off "Negotiate" as a provider, leaving only "NTLM" back and then the error was gone!

WebSocket

To use real websocket and not XHR polling, install IIS role "Websocket protocol" and add server variable "HTTP_SEC_WEBSOCKET_EXTENSIONS" to allowed server variables under URL rewrite.

Then add the server variable to your rule:

<rule name="ReverseProxyInboundRule1" stopProcessing="true">
    <match url="(.*)" />
    <serverVariables><set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" /></serverVariables>
    <action type="Rewrite" url="http://localhost:3000/{R:1}" />
</rule>
Collapse
 
petereysermans profile image
Peter Eysermans

Great info, thanks for taking the time to write it down.

Collapse
 
eduardo03049547 profile image
eduardo mass

Hello.
We started a new migration from ASP.NET to HTML+React Pages and from MVC.NET to the same
My question is, can we serving in the IIS the aspx or Controller MVC pages and the HTML via NPM? How can I achieve that?
Thank you !

Collapse
 
petereysermans profile image
Peter Eysermans

Hello Eduardo,

In theory you can run any node application this way. I only know React as a client-side framework and I don't have any experience running it on the server. It's hard to give a solution just via a comment but if React should run on the server as well I would create a separate site in IIS for the ASP.Net API project and another site for the React application. That way the API project can run via IIS and the React application uses IIS as a reverse proxy to the node webserver. If you can give more information how the different applications work I might be able to help further.

Collapse
 
joe441 profile image
joe441

Hi peter
I deployed a node app on my ip say myip:3000,
and in the index file on my IIS server ,i gave a href to this nodeapp
It aint working
But if i do the same in my browser it works!!
Please do advice

Collapse
 
petereysermans profile image
Peter Eysermans

Hello Joe,

You can't link to the node webserver from IIS, it will only work on the server itself. If you want to access the node website from the outside you will have to set up IIS as a proxy and use that address to link to the node website.

If you give a more detailed explanation I might be able to help you more.

Collapse
 
moroangular profile image
moroAngular

Hi Peter, great article, thanks for sharing.
However, if I logoff from my IIS Web Server and try to connect from my client I keep getting a 502 Bad Gateway (Web server received an invalid response while acting as a gateway or proxy server). If I logon to iis web server again, I find my deamon down (no pm2 process running).

Collapse
 
srini794 profile image
Srinivas Prabhu

Hi Peter,

I have this issue where the res.locals that is being set in the nodejs server, are not available in the pug engine when I do a reverse proxy.

More details I have put in this SO question. Please let me know if you know can we fix this issue.
stackoverflow.com/questions/612313...

Collapse
 
juliocesarpg92 profile image
Julio César

Hello Peter, your post helped me, thanks. However i have another requirement in my project, I use socket.io for chat. Have you deploy node with socket successfully? Thanks in advance.

Pd: sorry for my English, is not my mother language.😁

Collapse
 
jaypoc profile image
Jason Bauman

My team is running into an issue with a site that we set up on one of our Windows Servers under PM2. PM2 is set up as a service, but only the user who installed it has the ability to start/stop the site. Is there any recommended way to allow multiple users to control the same pool of apps?

Collapse
 
harshil123456 profile image
harshil123456 • Edited

Hi Peter, I have created hello world app and when I run the localhost:3000 it is runnig fine but when I am adding the reverse proxy to it then it is giving an error of the dns. I may be missing silly thing but i am new and i followed this article but did not hit the end result.

Collapse
 
jainilparikh profile image
Jainil viren parikh • Edited

Hi @petereysermans
Isn't it a bad choice to run the node js program on a terminal? I mean the terminal might hang ( usually the case with windows terminal when there is too much load ).

ANother thing, whats the use of IIS in this case, when the requests are finally served by the windows terminal? I understand that we are using it as a reverse proxy but isn't reverse proxy used for load balancing( which is only useful when we have multiple instances of the node.js application running in the backend?)

Collapse
 
abhishekhingu profile image
abhishekhingu

how we can do window authentication for angular app that served from express application running behind proxy

Collapse
 
jesben profile image
jesben

Windows Authentication

Have tried with NodeSSPI is not working behind a reverse proxy.

URL rewrite is running before Windows authentication, so impossible to attach LOGON_USER in the header that way.

The solution here is:
ISAPI_Rewrite 3 LITE (Freeware)
helicontech.com/isapi_rewrite/down...

C:\Program Files\Helicon\ISAPI_Rewrite3\httpd.conf

RewriteBase /
RewriteCond %{REQUEST_URI} ^/.*
RewriteHeader X-Remote-User: .* %{REMOTE_USER}

E.g. for Express middleware

app.use(function (req, res, next) {
    if (req.headers.hasOwnProperty('x-remote-user')) {
        req['user'] = req.headers['x-remote-user'];
    }
    next();
});

The IIS site has Windows authentication enabled and with these providers: Negotiate, NTLM.

It gave me unfortunately these challenges when users visit the site for the first time (Tested with Chrome, Edge. In IE the error was constant)

401 
400 (X-ARR-CACHE-HIT=0&X-ARR-LOG-ID=7f1e3067-1a02-4405-b275-000f06952bc2&SERVER-STATUS=400)

This was driving me insane, then I turned off "Negotiate" as a provider, leaving only "NTLM" back and then the error was gone!

Collapse
 
petereysermans profile image
Peter Eysermans

It's hard for me to point you in the right direction. Can you give some more information what exactly goes wrong? Do you have an error message?

Collapse
 
abhishekhingu profile image
abhishekhingu

I have created an angular 2 application. Now, these are the requirements for windows authentication.

1) If any user within the organization access this application, he should not get the login prompt and should be able to login directly into the application.

2) If any specific user within the organization tries to access the application, then he should get the specific role(Like admin, Manager) and able to login directly.

3) If any user outside the organization tries to access the application, he should get the login prompt.

Backend will also play the significant role. I have created rest API using node js and express. So will this passport package help in my case? I have implemented the passport.js on my node js rest API, but now how to validate that thing on the angular side.

I hope this text helps you to understand my query.

Thread Thread
 
petereysermans profile image
Peter Eysermans

I don't have experience with Windows Authentication in combination with passport.js. There are a lot of frameworks and parts you're mentioning so it is difficult to solve this in a simple reply. There is an NPM package which mentions passing the user from IIS to node but that uses iisnode: npmjs.com/package/passport-windows.... So I guess you need to find a way for IIS to pass that the user to node running via pm2. Let me know if you find a solution.

Collapse
 
randall72096766 profile image
RandallArmstrong

Hello Everyone,

Are you looking for a node.js application on windows with IIS as a reverse proxy for your business website?

Now, there are many hosting node.js applications on windows with IIS as reverse proxy available in the market. But choose the best one for our business website is a very important part. We help you to select the cheap or best web hosting company for Node.js.

DomainRacer is an affordable web hosting company for the node.js platform. If you are looking for another one then don’t waste time searching because DomainRacer is the best hosting option for Node.js applications.

Thank You….!

Collapse
 
simon_luah profile image
Simon Luah • Edited

Hi Peter,

Thanks for the great article!

May I check with the reverse proxy rules in your steps, it actually affects all subfolders as well.
Is it possible to restrict just to root folder? In addition, may we include and/or exclude selected subfolders as well?
If yes, how can I go about setting it?

Collapse
 
andreybushman profile image
Andrey Bushman

Hi Peter.

Thank you for your article. I have the problem with pm2 using. I described it here: stackoverflow.com/questions/573822...

Do you know how to solve it?

Thank you!

Collapse
 
petereysermans profile image
Peter Eysermans

I'm afraid I don't have a solution. I did some googling but only found the Stackoverflow question you already mention in yours. In that question there is also a link to a Github issue, but it is still unresolved.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
petereysermans profile image
Peter Eysermans

Are you running the node.js application via pm2 or are you testing it via a command prompt? Going on your error message, it looks like your node.js application is not running.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
niteshrkukreja profile image
Nitesh kukreja

Helo peter
Greetings for you,Hope you are doing well

Here im facing one issue when i uploaded my project on iis server we are getting directory back when i fired the url for more im attaching below screenshot for your reference
Image description

Collapse
 
niteshrkukreja profile image
Nitesh kukreja

Hello peter
Greetings for you, Hope you are doing well

Im facing one issue while deploying nodejs express api on iis server when I'm Fired the url im getting directory back on screen im attaching screen for your information or references please let me know or help

Thanks
Image description

Collapse
 
juanmarino_ profile image
Juan Marino

Hi Peter! thanks for sharing these easy steps.

Been going at it for a while now trying to figure out how to deploy my node js app on the server so it can serve my front end (angular app)

I followed your tutorial and it worked pretty well and easy. Where I can't get past is how do I go about routes?

So the app takes you to the login page when you first access it, from there, once the user puts the credentials in and presses submit, the front end sends a post to webpage/api/users/login. I get a response with the auth token and re-direct to the main page.

How do I add those routings to your approach. Obviusly my node app is listenting on port 3000

Thank you!!

Collapse
 
seleshabani profile image
seleshabani

Thank you! it very usefull

Collapse
 
rsgilbert profile image
Gilbert

Thanks

Collapse
 
yeya profile image
yeya

You should explain how to make pm2 start on system boot to complete this guide.

Collapse
 
enetc profile image
enetc

Is there any additional set up on the domain? mine got nothing site cant be reached.

Collapse
 
petereysermans profile image
Peter Eysermans

The domain should be in the bindings of the website in IIS. In the same way as you would configure the domain of another website.

Collapse
 
vigneshlaksh profile image
vigneshlaksh

Hey Peter , Thank you so much for this document. With this URL write I am unable to pull public folder of NODE JS application , is there any web config changes needed to pull complete application

Collapse
 
petereysermans profile image
Peter Eysermans

Not that I know of, except for some rewrite rules I don't have any other settings in my web.config file.

Collapse
 
parthp7493 profile image
Parth Parikh

Hi Peter,
I have read your post and follow all steps. I'm having problem HTTP Error 502.3 - Bad Gateway.
Can you please help me how can I fixed this problem?

Collapse
 
bommojuvishu profile image
Vishu

you might have given http in the reverse proxy .

Collapse
 
parthp7493 profile image
Parth Parikh

I have fixed this problem now I'm getting error "This site can’t be reached"

Collapse
 
petereysermans profile image
Peter Eysermans

Hi, have you double checked that you can reach the node.js web application via localhost on the machine itself? It's hard to pinpoint the problem without more information. I've had most success by first troubleshooting the different parts separately. All I can say for now is to double check that the node.js application is running and that the IIS configuration is using the correct address to redirect the traffic to.

Collapse
 
abhishekhingu profile image
abhishekhingu

what about http response header, how could I set it

Collapse
 
petereysermans profile image
Peter Eysermans

I would assume you can set it in our node application and that it will be send back to the client. I haven't encountered problems with this yet.

Collapse
 
davidwhit profile image
DavidWhit • Edited

I can confirm iisnode is a pain in the rear. I think fiddled with it for 2 weeks 3 years ago and finally managed to get it working. Have you tried using the iis http platform handler plugin?

Collapse
 
petereysermans profile image
Peter Eysermans

I haven't tried it yet but it looks interesting. Thanks for mentioning it.

Collapse
 
ionline247 profile image
Matthew Bramer

I have built a cmdlet that will install a Windows Service and run the NodeJS script you choose. Let me know what you think...

github.com/iOnline247/Install-Node...

Collapse
 
petereysermans profile image
Peter Eysermans

Looks interesting, thanks. I've gotten mixed results with trying to install the node.js script as a Windows service but I'll check it out when I have the chance.

Collapse
 
bommojuvishu profile image
Vishu

How to do url re write ( reverse proxy) to multiple node js application running on the same server with different port?

Collapse
 
petereysermans profile image
Peter Eysermans

If you want to expose them all to the outside via IIS, you create a website in IIS for each node application and configure each website to point to the different node applications with the correct port.

Collapse
 
ashr profile image
Ash

I'm getting the exact index.js file in the browser.

Collapse
 
atulsharmasdei profile image
atulsharma-sdei

Hi Peter,
this is really a helpful article, But I have a doubt, using a reverse proxy, won't make an application slower?
Will it impact the performance of the application?

Collapse
 
sajan123529 profile image
Sajan KC

i am getting problem with enabling the reverse proxy it shows "The process creation has been blocked" message. can somebody help??

Collapse
 
amitkrgupta2422 profile image
Amit Kr Gupta

Hi Peter, your article fulfill my requirement. I am following step by step your article but it given some error as attached. If you have any alternate solution kindly share.

Thanks!

Collapse
 
petereysermans profile image
Peter Eysermans

Unfortunately I can't see your attachment. If this is still relevant, can you give more details about the error and how the different applications have been setup? That way I might be able to help you troubleshoot the problem.