Deploying ASP.NET Core to App Service on Linux

4 minute read

When you attempt to deploy an ASP.NET Core project to App Service on Linux, you may run into an error during the build process - Object reference not set to an instance of an object. When you try to deploy the project to App Service on Windows, everything works, so where is the issue?

So apparently, when you include a Solution (.sln) file with your project, Kudu is going to have a hard time to parse it on App Service on Linux since it requires to load some assemblies to parse the .sln, however those are not present on ASL yet. There are multiple ways to go around this:

You can either remove the .sln file from the whole repository, which will result in the build to succeed, the application will deploy and we are safe and sound, however, it will be harder to use Visual Studio, since it kind of requires the solution file to be present.

If you don't want to do that, you can include a custom deployment script with your code by adding a .deployment file into the project's root and specifying the deployment script in it:

[config]
command = deploy.sh

Then you need to also include the deploy.sh script along with the .deployment file, the script can look like this (this is what gets autogenerated when you don't include the solution file, don't forget to rename the WebApplication1 to your .csproj):

#!/bin/bash

# ----------------------
# KUDU Deployment Script
# Version: 1.0.13
# ----------------------

# 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

if [ "x$DEPLOYMENT_TEMP" = x ]; then
    DEPLOYMENT_TEMP=/tmp/`date +%s`
    CLEAN_LOCAL_DEPLOYMENT_TEMP=true
fi

if [ "x$CLEAN_LOCAL_DEPLOYMENT_TEMP" = xtrue ]; then
    rm -rf "$DEPLOYMENT_TEMP"
    mkdir "$DEPLOYMENT_TEMP"
fi
##################################################################################################################################
# Deployment
# ----------

echo Handling ASP.NET Core Web Application deployment.

# 1. Restore nuget packages
dotnet restore "WebApplication1/WebApplication1.csproj"
exitWithMessageOnError "dotnet restore failed"

# 2. Build and publish
dotnet publish "WebApplication1/WebApplication1.csproj" --output "$DEPLOYMENT_TEMP" --configuration Release
exitWithMessageOnError "dotnet publish failed"

# 3. KuduSync
"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_TEMP" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh"
exitWithMessageOnError "Kudu Sync failed"


##################################################################################################################################
echo "Finished successfully."

And last, but not least, you can build the source code somewhere else, like in Visual Studio Team Services, and then just publish it to he App Service on Linux.

Additionally, it is quite important to mention, that you will need to set the startup command for the container in order for the application to start successfully, else it is going to attempt searching for .csproj in the root, which it won't be able to find and therefore the container will keep crashing (you will see it in the logs). The startup command will look like this: dotnet /home/site/wwwroot/WebApplication1.dll

startupcommand_dotnetcore

Comments

Leave a Comment

Your email address will not be published. Required fields are marked *

Loading...