.NET Core and Devops Part 2: Running our first ASP.NET Core Service on Linux

Welcome to the second in a series of articles focused on .NET Core from a devops perspective where I hope to demonstrate how we can practically start developing and deploying .NET Core applications on Linux.

Part 1: Running our first .NET Core application on Linux

Part 2: Running our first ASP.NET Core service on Linux (This Article)

Part 3: Running ASP.NET Core Services on Linux in Docker

Part 4: Setting up a CI build and deploy pipeline for our ASP.NET Core Service using Docker

As a devops engineer working a lot on the Microsoft stack, it is second nature nowadays to automatically setup and configure farms of Windows web servers running IIS and deploy ASP.NET based web sites and services to them. But now with .NET Core and ASP.NET Core it is possible to run those same web sites on Linux.

In my opinion, one of the main motivations to use Linux is cost. In Azure, Linux VMs are approximately half the price of Windows VMs. A D2v2 Windows Server is about £122/month whilst a D2v2 Ubuntu server runs at £62/month. If you are working at scale in the cloud then that is going to equate to a huge cost saving.

In this series of articles I hope to demonstrate that moving to Linux is possible and practical with a real life example including all the automated configuration and deployment processes.

Downcount Service

In the previous article I introduced the Downcount application. Well there is also a Downcount Web API written in ASP.NET Core which exposes the Downcount solution engine. It is in the main github project under Downcount.Service. You can either run it from Visual Studio or better yet run it on your Linux box.

Using the Ubuntu server we set up in part 1 (or any Linux box with .NET Core installed) run the following

mkdir Downcount
cd Downcount
git clone https://github.com/shiningdragon/Downcount.git
cd Downcount/DotNetCore/DownCount.Service

Then restore, build and publish the service

dotnet restore
dotnet build
sudo dotnet publish -o /var/downcount

Publish is going to package up our application and write all the files out to a specific location. Finally we can run our service by calling

dotnet /var/downcount/DownCount.Service.dll

The output should like this


So, what is happening here is, the Kestrel web server is being launched and is hosting our site on port 5000. Kestrel is the web server that comes with .NET Core and is used to host our ASP.NET Core applications. If we were to RDP onto the Linux box and browse to http://localhost:5000/swagger/ui we would see our service.

In the real world we would not want the Kestrel server directly accessible from outside. Kestrel is a very basic web server, and can’t do all the things we would like a public facing web server to do (SSL, caching, serve static data etc). We use Kestrel to host the ASP.NET Core service but that’s all. In practice we would use something like Nginx or Apache to properly expose our service to the outside world. Below are instructions to get things working with Nginx.

Configuring Nginx with ASP.NET Core

We are going to setup and configure Nginx to receive traffic on port 80 and forward it to the Kestrel web server and our Downcount service. First install and start Nginx

sudo apt-get install nginx
sudo service nginx start

Edit the file /etc/nginx/sites-available/default by replacing the contents with

server {
    listen 80;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

If you are new to Linux and are working from a Windows box (via putty or Ubuntu Bash on Windows or similar) then editing your first file might be a little tricky for you. I’m launching VIM to edit the file as follows

sudo vi /etc/nginx/sites-available/default

Here is a good beginners guide to VIM.

Test the updated config and apply it

sudo nginx -t
sudo nginx -s reload

Nginx configurations are of course much more involved than the simple example above. See this article for an in depth look at configuring Nginx in a production scenario.

Ensure the Downcount.Service is running under the Kestrel web server and you should now be able to see the Swagger interface of the service under port 80 (http://mypublicip/swagger/ui)

If you are using an Azure machine, ensure access to port 80 is open via a public ip or similar. Here you can see me use the swagger api to solve a simple Downcount game


Running the ASP.NET process under a service

Its almost ready but we need to ensure the Kestrel server remains running, even if the machine is restarted. To  do this we configure the dotnet process to run as a service using systemd (supervisor is also an option)

First create a startup shell script

sudo vim /var/downcount/startup

and edit it’s contents to be

service nginx start
dotnet /var/downcount/DownCount.Service.dll

Give this shell script executable permissions

sudo chmod 755 /var/downcount/startup

Verify it works by running the startup shell script


Next create a new file /etc/systemd/system/kestrel-downcount.service

sudo vim /etc/systemd/system/kestrel-downcount.service

with the following contents

    Description=Run downcount service



Enable the service, this forces it to startup when the machine boots up

sudo systemctl enable kestrel-downcount.service

Start the service and check it’s status, this will execute the shell script we created previously and run the Downcount Service.

sudo systemctl start kestrel-downcount.service
systemctl status kestrel-downcount.service
● kestrel-downcount.service - Run downcount service
   Loaded: loaded (/etc/systemd/system/kestrel-downcount.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2016-11-26 19:21:36 UTC; 2s ago
 Main PID: 6233 (startup)
    Tasks: 16
   Memory: 33.8M
      CPU: 2.262s
   CGroup: /system.slice/kestrel-downcount.service
           ├─6233 /bin/bash /var/downcount/startup
           └─6234 dotnet /var/downcount/DownCount.Service.dll

The Kestrel server should startup and our ASP.NET Core service is now live.

We can view the systemd logs by running journalctl (use –since and –until for more control)

sudo journalctl -fu kestrel-downcount.service

Jump to Part 3 to see how to use Docker on Linux to host your ASP.NET Core application.


2 thoughts on “.NET Core and Devops Part 2: Running our first ASP.NET Core Service on Linux”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s