Rapture in Everything

Hosting a .NET Core 2 app on Ubuntu


A few months ago I'd started a fun side-project of moving my personal web apps from various Windows-based services to a single Ubuntu VM because of the release of Ghost 1.0. Later, I'd managed to replace my Bonobo Git Server with Gitea. The last piece was to move a custom app - which was written in .NET and needed to be re-written to run on Ubuntu. (And it took forever to find time to do that.)

So after I had my app re-written with .NET Core 2[1] MVC, using Vue, Bulma, TypeScript and some arcane Webpack stuff that was thankfully mostly pre-generated, I needed to deploy it. (It's irrelevant here, but it was my tool to generate passwords in Slovak.)

First I had to install .NET itself, which required me to add Microsoft's signing key and package source.

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-get update
sudo apt-get install dotnet-sdk-2.0.2

I created a place for the app to live and moved it there.

sudo mkdir /var/www/netcore/
sudo mkdir /var/www/netcore/zble.sk

Then I wrote a .service unit for systemd, to have my server run on VM startup and reboot on crash if necessary. (Pretty much stolen from here.)

Description=Kestrel service running .NET Core

ExecStart=/usr/bin/dotnet /var/www/netcore/zble.sk/zble.sk.dll
RestartSec=10 # restart after 10 sec if crashed


I saved that file to /etc/systemd/system/kestrel-server.service, then set its permissions and enabled it.

sudo chown root:root kestrel-server.service
sudo chmod +x kestrel-server.service
sudo systemctl enable kestrel-server.service

So now the Kestrel server is running and listening to requests - on localhost:5000. I need to put it behind a reverse proxy to make it accessible from the web. Here is the pertinent part of my nginx config (at /etc/nginx/sites-available/):

    location / {
        allow all;
        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;

That's it. It not only seems to run, but even to start automatically after VM reboot. What more can one want? 😁

  1. 2.0.2, to be exact ↩ī¸Ž