Deploying ASP.NET Core to App Service on Linux
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
Comments
Jose Parra
Man, you are a genius!! I was banging my head against the walls. I hope MS fixes this issue quickly. Many thanks for sharing
Jarrett Vance (@jarrettv)
Thank-you x1000. This gem of a post was hard to find but it finally explains the problem I was seeing.
Stefan
Thanks for your post. You saved my day! I had to put bash in front of deploy.sh.
To submit comments, go to GitHub Discussions.