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