Node.js in Azure, let the pain begin

I’m currently employed at a large company that primarly use microsoft products, this allows me to get some free credits in Azure and for my new project I had the brilliant idea to use those credits to host a small node.js application. The application is written in koa and React.

The pain begins

Linking Visual Studio online to Azure subscription

Previously I’ve used Github for continous deployment, but this time I decided to use my own Visual Studio Online account.

The solution is simple but if you don’t know what you’re looking for you’re in for a lot of googling.
What you need to create is a Resource Group. That will allow you to link your Visual Studio Online account to your Azure AD account and use it for continous deployment!

After you’ve done this, you should be able to select your project in the Azure portal as deployment source.

Running npm scripts

The installation of npm packages is being handling behind the scenes in Azure Web Apps.
But this process can be brought into light, by installing the Azure commandline package and then generating the required files to override the default process.

npm install azure-cli -g

Next up we need two files .deployment and deploy.cmd, you can create these by running

azure site deploymentscript --node

The deploy.cmd file can be edited so we can add our custom steps, for example adding a build step for your frontend.

The structure of my app is

Server
Server/App
Server/App/Dist

Where app is the frontend, and I’m using React and ES6, this needs to be compiled before being put in my dist folder which then in turn is served by the server.

So you want to be a player? But your ES5 ain’t fly, you better call us up to Ecmascript all night. -’Script-Zibit aka JZibit

This is how I managed to run a the build-scripts in the app project

::Build front-end since it uses ES6 and react
echo calling front-end build.
pushd "%DEPLOYMENT_TARGET%\app\"
call :ExecuteCmd !NPM_CMD! install
call :ExecuteCmd !NPM_CMD! run build-all
popd

build all is a script that is defined in my package.json in my app folder
After this, I’ve been able to do continous deployment! It works kinda sweet when I look back at it!

App settings

You want to have specific settings for your environments. I ended up defining these via the Azure UI. Azure will populate these values during runtime in

process.env.YourCoolPropertyName

To access these settings I wrote the snippet below, which tries to get the setting from the

process.env

if it can’t find it, it’ll try to take it from the object that was passed along as a backup.

'use strict'
module.exports = function(azureAppSettings, defaultSettings) {
let settings = {}
for(let i = 0; i < azureAppSettings.length; i++) {
const name = azureAppSettings[i]
if(!process.env[name]) {
settings[name] = defaultSettings[name]
} else {
settings[name] = process.env[name]
}
}
return settings
}

The pain goes away?

Setting these things up for the first time sure is a challenge, but once you've done it, it is awesome to just push to the master branch and see that it's automatically building and deploying a new version of your application.

Hopefully will this help some people that are struggling with Azure and node.js!

Port update

Recently I was struggling with getting an application up and running. I checked the files on the application servers folder via FTP.

/LogFiles/Application/

The index.html file will give you a list of errors that occured.

Application has thrown an uncaught exception and is terminated:
Error: listen EACCES 0.0.0.0:80
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at Server._listen2 (net.js:1221:19)
at listen (net.js:1270:10)
at Server.listen (net.js:1366:5)
at Application.app.listen (D:\home\site\wwwroot\node_modules\koa\lib\application.js:74:24)
at Object. (D:\home\site\wwwroot\server.js:36:5)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)

Apparently you're not allowed to run on ports lower than 1024. So you can't just specify port 80 and be happy.

app.listen(80)

to

const port = process.env.PORT || 80
app.listen(port, () => console.log('Server listening on', port))

reference Stack overflow post regarding this

Like what you read? Give Andreas Lindgren a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.