Node on Azure App Service how does it start up? - node.js

I have an Angular Universal app that I am deploying to Azure App Service (Windows).
When the app runs locally on my Windows 10 PC it works fine but in the cloud it seems like the process.cwd() is different than when I run it locally. This is causing Express.js to look in the wrong place for some view files.
The process pwc should be based on how I executed node, in my case I have a start script in my package.json that executes "node dist/server.js". But I can remove this script and Azure will still start my app. So I think the root of my pwc problem is in how Azure starts up my node app.
Unfortunately Microsoft thinks that some code snippets and a couple John Papa videos is good enough documentation for developers to resolve issues.
Questions
Does documentation exist that explains any configuration or
conventions that the App Service uses to init my node app? Where is
it?
Given the script "start": "node dist/server.js" why would process.cwd() be different on my local host versus Azure App Service? The file structure is the same in both places.
const DIST_FOLDER = join(process.cwd(), 'dist');
app.set('views', join(DIST_FOLDER, 'browser'));
Error: Failed to lookup view "index" in views directory "D:\home\site\wwwroot\dist\dist\browser"
root
package.json
dist
server.js
browser (client app)
server (server app)

Documentation: Not an exhaustive guide, but this is what I found useful on MSDN forums:
Windows Azure Websites uses IISNode to host the Node process inside of IIS. Your Node site is actually given a Named Pipe which receives the incoming requests, not a TCP port like you would use when running locally or hosting yourself.
...
As a node.js application running on Azure Web Apps, needs a server.js or app.js file as the entrance in the root directory with a web.config file to control the iis
Working Directory: When web.config and iisnode are used to run server.js, the rules rewrite the directory to point to where server.js resides. That is why it isn't able to find a subfolder 'dist'.
I had to change the line above to this, in order for it to work on Azure:
const DIST_FOLDER = process.cwd();
Another thing I found important was to set the right version of node for your App Service, using WEBSITE_NODE_DEFAULT_VERSION in App Settings. Here's a bit more info on that from a blog on MDSN - NodeJs and NPM versions on Azure App Services

Since I am used to hosting Node apps on Linux this totally slipped my mind. The answer is...
see web.config

If anyone else finds themselves here put this in your server.ts file to work both locally and on azure
import * as fs from 'fs';
const distFolderExists = fs.existsSync(join(process.cwd(), 'dist'));
const DIST_FOLDER = distFolderExists ? join(process.cwd(), 'dist') : process.cwd();
big thanks to KayS for their answer - really helpful.

Related

Microsoft.WindowsAzure Exception: The remote server returned an error: (503)

After I deploy my web app to window Azure.I access my web app,the server return error 503.
it look like the server did not start, the file starter.cmd is empty(only #%*).
log:
2019-08-19T03:23:55.2310991Z,Using start-up script start.js from package.json.,,0
2019-08-19T03:23:55.2310991Z,The iisnode.yml file explicitly sets nodeProcessCommandLine. Automatic node.js version selection is turned off.,,0
2019-08-19T03:23:55.2467314Z,Selected npm version 6.4.1,,0
2019-08-19T03:23:55.2623494Z,The syntax of the command is incorrect.,,1
2019-08-19T03:23:55.2936133Z,The syntax of the command is incorrect.\r\nD:\Program Files (x86)\SiteExtensions\Kudu\84.10807.4030\bin\Scripts\starter.cmd deploy.cmd,,2
You could use Kudu console (https://yoursite.scm.azurewebsites.net) - Review the logs to fetch more on the error -Node.exe crashed – check d:\home\LogFiles\logging-errors.txt for stack trace and check win32 error code for more details.
In Azure App Service, the app is run in IIS using iisnode. To enable the app to run with iisnode, the root app directory contains a web.config file. The file is readable by IIS, and the iisnode-related settings are documented in the iisnode GitHub repository.
You could download the sample Node.js project from https://github.com/Azure-Samples/nodejs-docs-hello-world/archive/master.zip and extract the ZIP archive and change based on your requirement.
Open index.js and find the following line:
const port = process.env.PORT || 1337;
App Service injects process.env.PORT into your application, so the code uses the variable to know which port to listen.
NODE.exe has a setting called NODE_PENDING_PIPE_INSTANCES. On Azure App Service, this value is set to 5000. Meaning that node.exe can accept 5000 requests at a time on the named pipe. This value should be good enough for most node applications running on Azure App Service. You should not see 503.1003 on Azure App Service because of the high value for the NODE_PENDING_PIPE_INSTANCES.
Kindly let us know, I have answered your similar question here.

Serving Node Server and Angular 4 application in one command

I am starting a new project which is using Angular 4 for frontend designing and the application will need some rest api's for which I have decided to use node. I am using angular cli for creating angular app and I know how to create angular app and node server but I want to know how will I connect these two things such that when I do ng serve both the server and angular app gets compiled and run. What basic changes in the project structure or some file is needed to be done?
I'm currently building a full-stack Angular app with a Node/Express backend and was wondering the exact same thing. However, despite what that scotch.io tutorial tells you, creating both the Express server and the Angular app in the same directory is NOT the best way to go about it.
What you want to do is set up your Express server in one project and serve it in one terminal window, then serve your Angular app in a separate terminal window but have it point to your locally-running Express server instead of the default dev server that's included with the Angular CLI (the ng-serve command).
Here's a Stack Overflow answer and also a Medium article that answered all of my questions for how to set this up (fortunately, it's not too hard).
Here's what I did Shubham. I went into the Angular-Cli and changed "outDir": to "../public"in other words it will look like "outDir": "../public". The ../public folder is my Express static folder set in my app.js file with app.use(express.static(path.join(__dirname, 'public')));
Keeping in mind I have nodemon installed globally, and in my package.json file, "start": "node app" I simply run nodemon from this dir to start my server and both Angular and Express run on the same server.
I have seen some people say it's not good to run static filed on the Node/Express server, but for development I'm not sure it matters. Although I'm a novice when it comes to js frameworks etc. Here's the project files on my github acct: https://github.com/chriskavanagh/angularauth.
Edit: You must run ng-build (in your Angular dir) whenever you change code.
First, in Angular project do ng build, it will create dist folder (static folder).
Second step, paste the following code in backend servers entry point file.
app.use(express.static(path.join(__dirname, 'dist/')));
app.get('*', (req, res) =>{
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
And after the above thing is done run backend server: node filename
Note: in give proper path where your index.html file is located in dist folder.
The node server and the Angular app are two different things.
In order to run the node server you should use the command:
node ServerName.js
In order to run the angular app you should use the command:
npm start OR ng serve
In your case, the connection between the two is made by http requests.
For example you could use 'express' in order to implement rest services in your node server and then send an http request to the server in the current route.

App Dynamics for Angular 2 App in IIS - Node.js Agent Installation and Configuration

I am trying to assist in setting up AppDynamics with an Angular 2 app that is hosted in IIS. The app is already up and running. There is a part I am having trouble on, the instructions for that part say say:
1) From the root directory of your Node.js application, run this command:
npm install appdynamics#4.3.5
For every Node.js application you are instrumenting, insert the following call in the application source code at the first line of the main module (such as the server.js file), before any other require statements:
require("appdynamics").profile({
controllerHostName: '<controller host name>',
controllerPort: <controller port number>,
controllerSslEnabled: false, // Set to true if controllerPort is SSL
accountName: '<AppDynamics_account_name>',
accountAccessKey: '<AppDynamics_account_key>',
applicationName: 'your_app_name',
tierName: 'choose_a_tier_name',
nodeName: 'choose_a_node_name'
});
2) Restart you application
I did step 1 locally in the console, but I don't know what to do for step 2. If I add that script to the page I get "The Reference error: require is not defined".
I learned that that function is not meant to run on the browser. It's meant to be run server-side, but I do not see node js or any server.js files on our dev web server.
Does anyone have any suggestions on where to put that snippet. Will it even work with the current setup?
It turns out the code I was given was completely wrong for angular 2 implementation. The code they gave me is for running on the web server's side with node js. Since angular 2 is an SPA that runs on the browser, it would never work.
I did some research and found this example application that I added a few tweaks to: https://github.com/derrekyoung/appd-sampleapp-angular2

vue files without NodeJS?

I want to host my app outside of node JS, but I want to use .vue files and possible npm as build system (if it's needed). Is it's possible to do?
I do not need any backward compatibility and if it work on latest Chrome dev it's ok for me.
Is there any examples how it can be done?
I tried to build some webpack template, but it's work only inside NodeJS. On other server I am getting 404 when I am accessing to URLs that placed in .vue files. It's seems that they can't be handled by the other server.
VueJS app is not NodeJS app.
VueJS app is interpreted by the browser.
You just have to build your app on computer and host files as any static website, so any server can serve html and files.
To build your app use e.g. Webpack (https://github.com/vuejs-templates/webpack )
NodeJs only use to build *.js files in front-end, your WebApp dosen't have to run on Nodejs.
1, You can create a index.html file that requires *.js file when webpack built it.
2, Use Chrome to open your index.html file so you can see it works.
You don't need to use vue-cli or other servers if you only want a static page.
But you have to know how to set your webpack.config.js, you can look that doc https://webpack.js.org/guides/getting-started/
Your starting point is wrong. Vue + node.js can build a complete site. Vue is the front-end framework, node's server language. The two can be used in combination. But not vue must rely on node to use. The two of them can be perfect to achieve the front and back separation of the development model.
In projects that use vue, individuals do not recommend configuring webpack and vue-loader separately. You can directly use vue official scaffolding, vue-cli. Do not have to consider these configurations, automatically configured.
Vue-cli
If you just started learning Vue, here's an entry-level demo. Although it is only a small application, but it covers a lot of knowledge points (vue2.0 + vue-cli + vue-router + vuex + axios + mysql + express + pm2 + webpack), including front-end, back-end, database and other sites Some of the necessary elements, for me, learning great significance, would like to encourage each other!
Vue Demo
Best way to develop Vue app is run dev server, and after all just build static assets. You don't need use vuex files, even better is use static template because you can easily integrate it with some back-end (WordPress or whatever).
Helpfully will be use some starter, for ex. Vue.js starter
It's true that vue will create static html pages when you run the build script. However, you will need to serve the files from a small server for the site to work. If you notice, when you run npm run build, the terminal will print a notice...
Tip:
Built files are meant to be served over an HTTP server.
Opening index.html over file:// won't work.
You can create a simple http server in your /dist directory with express and then host your site somewhere like Heroku.
Take a look at this article https://medium.com/#sagarjauhari/quick-n-clean-way-to-deploy-vue-webpack-apps-on-heroku-b522d3904bc8#.4nbg2ssy0
TLDR;
write a super simple express server
var express = require('express');
var path = require('path');
var serveStatic = require('serve-static');
app = express();
app.use(serveStatic(__dirname));
var port = process.env.PORT || 5000;
app.listen(port);
console.log('server started '+ port);
add a postinstall script in a package.json within /dist
{
"name": "myApp",
"version": "1.0.0",
"description": "awesome stuff",
"author": "me oh my",
"private": true,
"scripts": {
"postinstall": "npm install express"
}
}
push only your /dist folder to heroku after you've compiled your site.
proof: I've followed these steps to host my vue.js project
using vue files without NodeJS (nor webpack) is possible with vue3-sfc-loader.
vue3-sfc-loader
Vue3/Vue2 Single File Component loader. Load .vue files dynamically at runtime from your html/js. No node.js
environment, no (webpack) build step needed.
vue3-sfc-loader will parse your .vue file at runtime and create a ready-to-use Vue component.
disclamer: author here
Could you try something as simple as an S3 bucket setup for web serving? How big is your project? How much traffic do you think you'll get? If it's very small, you may be able to host on S3 and use webpack, etc.

I have a very basic world koajs web app that i need to test on azure

I need to test koajs support on azure. since koajs uses --harmony flag with node to take advantage of generators its very hard to tweek node on azure.
following is the code for server.js file.
var koa = require("koa")
var app = koa();
app.use(function * () {
this.body = "Hello World!";
});
app.listen(80);
console.log("The app is listening. Port 80");
I have a web app on azure that use git local publising to push code online. how can i configure node to use --harmony switch?
You can control the node command line by using the nodeProcessCommandLine configuration setting which can be specified in an iisnode.yml config file as detailed in the "advanced scenarios" section of this post. This allows you to pass additional command line switches, choose your node version, point to your own deployed node build, etc.
For example:
nodeProcessCommandLine: "D:\Program Files (x86)\nodejs\0.10.18\node.exe" --harmony
Your specific issue is discussed in more detail in this github issue.

Resources