Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default documents not serving on node web app hosted on Azure

I've set up an angular4/node app on my local machine and I can ng serve and npm start the app just fine. I've created a web app on azure and used John Papa's guide to deploy it to azure. However; when I visit the site with chrome my index.html is not served up and I get a 404.
I've even eliminated all my documents under Application Settings -> Default Documents to only list index.html and nothing else.

However; when I visit myapp.azurewebsites.com/index.html the site is rendered. When I visit myapp.azurewebsites.com the site is not.

What am I missing?

server/index.js

const express = require('express');
const path = require('path');

const root = './dist';
const app = express();

app.use(express.static(root));
console.log(`server ${root}`);
app.get('*', (req, res) => {
    res.sendFile(`index.html`);
});

const port = process.env.PORT || '3000';
app.listen(port, () => console.log(`API running on localhost:${port}`));

client/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';

import { routes } from './app.routing';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        HttpModule,

        RouterModule.forRoot(routes)
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
export class AppModule { }

client/app/app.routing.ts

import { Route } from '@angular/router';

import { AppComponent } from './app.component';

export const routes: Route[] = [
    { path: '', component: AppComponent }
];

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 http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx 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="index.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="^index.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{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="index.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:
        * 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>
like image 527
gh0st Avatar asked Sep 19 '25 09:09

gh0st


1 Answers

MAY 2020 - You don't have to add any javascript files or config files anywhere. Let me explain.

I was facing this exact same issue and wasted 6 hours trying everything including the most popular answer to this question which didn't work either.

You see, when you just deploy an Azure Web App (or App Service as it is also called), two things happen:

  1. The web app by default points to opt/startup/hostingstart.html

  2. It also puts a hostingstart.html in home/site/wwwroot

When you deploy your code, it replaces hostingstart.html in home/site/wwwroot but the app is still pointing to opt/startup/hostingstart.html. If you want to verify this, try deleting opt/startup/hostingstart.html file and your web app will throw a "CANNOT GET/" error.

So how to change the default pointer? It's simpler than it looks:

Go to Configuration tab on your web app and add the following code to startup script:

pm2 serve /home/site/wwwroot --no-daemon

This will tell the web app to serve wwwroot folder. And that's it.

If this web app is a client-side single-page-app and you're having issues with routing, then add --spa to the above command as follows:

pm2 serve /home/site/wwwroot --no-daemon --spa 

Image for reference: Screenshot explaination

PS: If you only set the startup script without deploying your code, it will still show the hostingstart.html because by default that file lies in the wwwroot folder.

like image 130
DeityWarrior Avatar answered Sep 21 '25 02:09

DeityWarrior