configuration for azure

env vars

It is well worth defining your node and npm versions within the application settings in Azure > your app > application settings rather than within the package.json or iisnode.yml files.

WEBSITE_NODE_DEFAULT_VERSION : 8.11.1

WEBSITE_NPM_DEFAULT_VERSION : 5.6.0

If you decide to add the engine versions in package.json:

package.json

"engines": {

"npm": "5.6.0",

"node": "8.11.1"

}

Note that Azure treats all of these methods of defining engine versions differently. If you use a iisnode.yml file to define the engines it should overwrite the package.json and application settings definitions.

While you’re in the application settings adding the following will turn on debugging

web.config

The web config file is required for the application to run on Azure, it allows you to define the entry point that the IISnode module should pipe requests to. This can be slightly finicky to setup, the basic premise is that you want to direct all requests to the main.app for your nuxt application.

The below is an example of my current web.config file, including comments.

web.config

<configuration>

<system.webServer>

<webSocket enabled="false" />

<handlers>

<!-- Indicates that the main.js file is a node.js site to be handled by the iisnode module -->

<add name="iisnode" path="main.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="^main.js\/debug[\/]?" />

</rule>



<!-- <rule name="Redirect to https" stopProcessing="true">

<match url="(.*)"/>

<conditions>

<add input="{HTTPS}" pattern="Off"/>

<add input="{REQUEST_METHOD}" pattern="^get$|^head$" />

</conditions>

<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/>

</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="main.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

-->

</system.webServer>

</configuration>

kudu

A note on kudu as full disclosure: Microsoft support technicians highly recommended to me NOT to run custom deployment or build scripts, I ignored them. The Microsoft recommendation was to pre-build the application and commit all /build and .nuxt to the application repository.

Kudu performs pre-build through to post build scripts for your Azure application, it is fairly simple to work with. Add a .deployment file that simply contains a definition of a bash script to run.

.deployment

[config]

command = bash deploy.sh

This tells kudu to run the deployment.sh file as a custom deployment script as opposed to the stock standard script that Azure uses by default.

The deploy.sh content depends on your specific build, my configuration is below.

deploy.sh

#!/bin/bash



# ----------------------

# KUDU Deployment Script

# Version: 1.0.17

# ----------------------



# Helpers

# -------



exitWithMessageOnError () {

if [ ! $? -eq 0 ]; then

echo "An error has occurred during web site deployment."

echo $1

exit 1

fi

}



# Prerequisites

# -------------



# Verify node.js installed

hash node 2>/dev/null

exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment."



# Setup

# -----



SCRIPT_DIR="${BASH_SOURCE[0]%\\*}"

SCRIPT_DIR="${SCRIPT_DIR%/*}"

ARTIFACTS=$SCRIPT_DIR/../artifacts

KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"}



if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then

DEPLOYMENT_SOURCE=$SCRIPT_DIR

fi



if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then

NEXT_MANIFEST_PATH=$ARTIFACTS/manifest



if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then

PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH

fi

fi



if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then

DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot

else

KUDU_SERVICE=true

fi



if [[ ! -n "$KUDU_SYNC_CMD" ]]; then

# Install kudu sync

echo Installing Kudu Sync

npm install kudusync -g --silent

exitWithMessageOnError "npm failed"



if [[ ! -n "$KUDU_SERVICE" ]]; then

# In case we are running locally this is the correct location of kuduSync

KUDU_SYNC_CMD=kuduSync

else

# In case we are running on kudu service this is the correct location of kuduSync

KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync

fi

fi



# Node Helpers

# ------------



selectNodeVersion () {

if [[ -n "$KUDU_SELECT_NODE_VERSION_CMD" ]]; then

SELECT_NODE_VERSION="$KUDU_SELECT_NODE_VERSION_CMD \"$DEPLOYMENT_SOURCE\" \"$DEPLOYMENT_TARGET\" \"$DEPLOYMENT_TEMP\""

eval $SELECT_NODE_VERSION

exitWithMessageOnError "select node version failed"



if [[ -e "$DEPLOYMENT_TEMP/__nodeVersion.tmp" ]]; then

NODE_EXE=`cat "$DEPLOYMENT_TEMP/__nodeVersion.tmp"`

exitWithMessageOnError "getting node version failed"

fi



if [[ -e "$DEPLOYMENT_TEMP/__npmVersion.tmp" ]]; then

NPM_JS_PATH=`cat "$DEPLOYMENT_TEMP/__npmVersion.tmp"`

exitWithMessageOnError "getting npm version failed"

fi



if [[ ! -n "$NODE_EXE" ]]; then

NODE_EXE=node

fi



NPM_CMD="\"$NODE_EXE\" \"$NPM_JS_PATH\""

else

NPM_CMD=npm

NODE_EXE=node

fi

}



##################################################################################################################################

# Deployment

# ----------



echo Handling node.js deployment.



# 1. KuduSync

if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then

"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh"

exitWithMessageOnError "Kudu Sync failed"

fi



# 2. Select node version

selectNodeVersion



# 3. Install npm packages and build

if [ -e "$DEPLOYMENT_TARGET/package.json" ]; then

cd "$DEPLOYMENT_TARGET"



echo "NPM_CMD is: $NPM_CMD"

echo "NODE_EXE is: $NODE_EXE"



echo "Running $NPM_CMD install --production"

eval $NPM_CMD install --production

exitWithMessageOnError "npm install failed"



echo "Running $NPM_CMD run build"

eval $NPM_CMD run build

exitWithMessageOnError "build failed"



#Copy build back to root

eval cp build/* .



# echo "Running $NPM_CMD run dev"

# eval $NPM_CMD run dev

# # eval npm run build

# exitWithMessageOnError "dev failed"



cd - > /dev/null

fi







##################################################################################################################################

echo "Finished successfully."

It is also worth mentioning that running npm install and npm build within Azure is excruciatingly slow — a small app with few dependencies has easily taken over 400 seconds to deploy.