5

I have the following node.js/express file index.js.

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var port = process.env.PORT || 1337;
app.listen(port);
console.log("Server running at http://localhost:%d", port);

When I run the server locally and access http://localhost:1337/ on my browser, I get "Hello World!" as expected. I deployed the index.js on my Azure Web App but when I try to access it, I get a "ERR_CONNECTION_TIMED_OUT".

What am I doing wrong?

I have already installed express on Azure.

Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
G. Werner
  • 199
  • 2
  • 14

2 Answers2

2

G.Werner, firstly,you could enable debugging for error details, please follow the steps:

1) Create file iisnode.yml in your root folder (D:\home\site\wwwroot) if not exists.

2) Add the following lines to it.

loggingEnabled: true

logDirectory: iisnode

After that done, you can find logs in D:\home\site\wwwroot\iisnode.

Please refer to my working steps.

app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.set('port', process.env.PORT || 5000);

console.log("+++++++++++++++"+ app.get('port'));

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

app.listen(app.get('port'), function(){
          console.log('Express server listening on port ' + app.get('port'));
          });

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="app.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="^app.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="app.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>

routes/index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

Access Result:

enter image description here

More details ,please refer to this case: Running Node.js on Azure Web App.

In addition, you could also take a shot on the express template called "Basic Azure Node.js Express 4 App" in the Visual Studio 2017 Tool.

Any concern, please let me know.

Jay Gong
  • 23,163
  • 2
  • 27
  • 32
2

I had the same problem, have you tried deploying to a Linux App Service plan, this should work like a Charm, however, if you are using windows plan ensure you have added the web.config file check this out hope it helps. For others facing similar issues, please ensure that you have port being called from process.env.PORT || XXX as the cloud hates hardcoded port values