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?
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}`));
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 { }
import { Route } from '@angular/router';
import { AppComponent } from './app.component';
export const routes: Route[] = [
{ path: '', component: AppComponent }
];
<?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>
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:
The web app by default points to opt/startup/hostingstart.html
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With