ASPNET Core Zero Downtime Deployment to Linux with Nginx

Probably, most of us, deploy our applications that inside the containers to orchestrator like Kubernetes. The orchestrator can handle all of the scenario about deployment. What if we need to deploy ASPNET Core application as a Linux service without any downtime? We can handle it with a simple bash script.

The script I shared below, works on both API and Web application.

This blog also show you how to configure ASPNET Core application as a Linux service and how to configure the Nginx proxy front of that.

On Your Application:

  • A healthcheck url that returns the version of the application with json format like below.

{ "Version": "1005" }

Important: You should set the number of the version from the environment variable named DEPLOYMENT_VERSION.

Environment.GetEnvironmentVariable("DEPLOYMENT_VERSION")
  • Create your deployment package as tar.gz.
  • Add the file named appsettings.json.tmpl to change the appsettings.json variables for your deployment environment.

Example appsettings.json file:

{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default":"Information",
"Microsoft": "Information",
"System": "Information"
}
}
}

Example appsettings.json.tmpl file:

Just use the variables which you want to change by environment.

{
"Logging": {
"LogLevel": {
"Microsoft": "{{.LOG_LEVEL_MICROSOFT}}",
"System": "{{.LOG_LEVEL_SYSTEM}}"
}
}
}

On Your Deployment Target:

  • ASPNET Core runtime.

https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/runtime-2.2.1

  • Nginx.

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04

  • jq package.

sudo apt-get -y install jq

  • Bonus: Increase the max open file limit for the system.
echo "fs.file-max = 640000" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
  • Bonus: A crontab line to delete the old deployment files that excluded last of 3 version. (every 3 days.)
crontab -l | { cat; echo '0 0 */3 * * $(for folder in /var/aspnetcore/*; do [ -d $folder ] && (cd $folder && ls -t | tail -n +4 | xargs sudo rm -rf --); done)'; } | crontab -
  • Create an ssh connection to Linux machine you want the deploy.
  • Fetch your application package to the machine as a tar.gz file.
  • Replace appsetting.json variables for the environment via the machine environment variables.
  • Run the application and wait until it is up for it up to 3 minutes.
  • Configure and reload the Nginx to rotate incoming requests to the newly deployed one.
  • Wait for the correct version is up while we requesting it via the machine IP. (up to 1 minute.)
  • Destroy the old one.
var
|_ aspnetcore
|_ Example.Application.Name
|_ 1001
|_ 1005
|_ 1005-01
etc
|_ systemd
|_ system
|_ Example.Application.Name-1005-01.service
|_ nginx
|_ sites-available
|_ Example.Application.Name

Configure the variables at the top of the script by your requirements.

Run the script at the same folder of your deployment package.

I hope you enjoy!