Breaking news slowpoke

Ya, rly.

I’ve missed the beginning of .NET Core, so I’ve just recently discovered that one can host a .NET Core MVC web-application on a Linux server. I always liked C#/.NET, but I didn’t like to be tied to IIS/Windows platform. And apparently, now I’m not.

The whole setup-from-scratch process takes about 15 minutes. I kid you not! And below I will show you it step-by-step (based on this instruction): how to host a .NET Core MVC application with NGINX and Kestrel on Linux server.

So, we have:

  • Clean, out-of-the-box, remote Linux server running Ubuntu 16.04 (with SSH enabled);
  • Some .NET Core MVC application ready for deployment (even a default template is enough).

And here we go.

Connect to your server via SSH:


Install .NET Core ( (instructions below are for sure obsolete already):

sh -c 'echo "deb [arch=amd64] xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
apt-key adv --keyserver hkp:// --recv-keys B02C46DF417A0893
apt-get update
apt-get install dotnet-dev-1.0.4

Create a folder for your website:

mkdir -p /var/www/YOUR-WEBSITE

Install NGINX:

apt-get install nginx

Open the default config:

vi /etc/nginx/sites-available/default

and edit it like that:

server {
        listen 80;
        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;

Save it and restart NGINX:

nginx -s reload

Create a systemd config for Kestrel instance:

vi /etc/systemd/system/kestrel-YOUR-WEBSITE.service

Edit it like that:


ExecStart=/usr/bin/dotnet /var/www/YOUR-WEBSITE/YOUR-WEBSITE.dll


Now it’s time to deploy your web application. First, prepare it by running dotnet publish in the project’s directory on your machine. Now connect to your server via SFTP (or FTP) and copy the contents of bin/Debug/netcoreapp1.1/publish/ from your machine to /var/www/YOUR-WEBSITE/ on your server. Also note, how fucking awesome it is: everything is collected in a single folder.

Change the owner for your website’s directory so it would belong to NGINX’s user (www-data):

chown -R www-data:www-data /var/www/

Back to our service created on the previous step. Enable and start it:

systemctl enable kestrel-YOUR-WEBSITE.service
systemctl start kestrel-YOUR-WEBSITE.service

You can check its status:

systemctl status kestrel-YOUR-WEBSITE.service

If everything is okay, then it will show something like that:

● kestrel-YOUR-WEBSITE.service - YOUR-WEBSITE
   Loaded: loaded (/etc/systemd/system/kestrel-YOUR-WEBSITE.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-08-10 11:30:09 UTC; 1s ago
 Main PID: 15628 (dotnet)
    Tasks: 14
   Memory: 25.4M
      CPU: 1.380s
   CGroup: /system.slice/kestrel-YOUR-WEBSITE.service
           └─15628 /usr/bin/dotnet /var/www/YOUR-WEBSITE/YOUR-WEBSITE.dll

Now open your web-browser and go to http://YOUR-SERVER-IP/
It fucking works!

P.S. It is also entirely possible to use MySQL database which is quite a nice thing since we are talking about Linux as a hosting platform. I might tell about this in details in one of the next articles.