.Net Core – How to publish an ASP.NET core application to Linux host

With the growth of many cheap Linux VPS providers and the new releas of .NET core, we have a possibility to host our applications with a low cost. In this post, I would like to write down the steps how I published a ASP.NET core application to a Linux VPS. The application is just a simple “Hello World!” ASP.NET core. The code will be compiled and deployed manually on the Linux VPS. In praxis, you can automatically deploy your app over FTP or use Git to check out the release branch, build and deploy.

1. Prerequisites

– I use a fresh Linux VPS Ubuntu 16.04 LTS for this demo. You can use any Linux distribution but the syntax maybe different.

2. Steps

2.1 Add user

Don’t be root. Let’s create a user with sudo priviledge

adduser dotnetcore
usermod -aG sudo dotnetcore

usermod is used to modify or change any attributes of an already existed user. The commands above create a user dotnetcore and add him to group sudo as supplementary as well as secondary group.

-G = To add a supplementary groups.
-a = To add anyone of the group to a secondary group.

2.2 Install .Net Core

An updated full instruction for installing .NET Core is available at https://www.microsoft.com/net/core#linuxubuntu. I suggest you to following the instructions on Microsoft’s site. Just select your OS and follow step-by-step instructions there.

In my case, for a fresh Ubuntu 16.04 LTS, I have to install apt-transport-https first on my server.

sudo apt-get install apt-transport-https

Then execute these commands to set up the apt-get feed that hosts the package .NET core.

sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
sudo apt-get update

Now I can install .NET core

sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177

Test if it’s installed successfully. In terminal, execute

dotnet --version

2.3 Create app

We create our app folder and an ASP.NET core application

mkdir hwapp
cd hwapp
dotnet new -t web

2.4 Install development dependencies

The ASP.NET core uses npm, gulp and bower to manage Javascript and CSS packages and enhance the build process. We have to install them so that ASP.NET core application can be built.

sudo apt-get install npm
sudo npm install -g gulp
sudo npm install -g bower

2.5 Read settings from command line

As default, the ASP.NET core application will run on port 5000. If we let all settings default, we can only host only one app at the same tim because the port 5000 is reserved for the first running app. Therefore we’ll modify the code a little so that we can configure the port at starting.

Open project.json file, add Microsoft.Extensions.Configuration.CommandLine to dependencies section.

"Microsoft.Extensions.Configuration.CommandLine": "1.1.0"

Open Program.cs file, extend the code by using the config from CommandLine.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace WebApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var config = new ConfigurationBuilder()
                            .SetBasePath(Directory.GetCurrentDirectory())
                            .AddCommandLine(args)
                            .Build();
                
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseConfiguration(config)
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

Then in terminal run

dotnet restore

To restore all dependencies and then

dotnet build

to be sure if the app is able to be compiled and then

dotnet run --server.urls=http://*:5123

to start hosting our app at local.

If there’s no error, the app has run smoothly within code directory. Just make a curl to test if you get a response.

curl http://localhost:5123

However the app shouldn’t run from code folder, we have to publish it to deploy folder and host it to internet from there

dotnet publish
sudo cp -a /home/dotnetcore/hwapp/bin/Debug/netcoreapp1.1/publish/ /var/hwapp

2.6 Expose our app to the outside

Our app can now run on any port (given over command line) and accessible at local (if we start it manually with dotnet run command), but we need to expose it to the outside so that we can access it over internet. If we try to access our Linux VPS now, there’s nothing happen even if we start our app manually. We could tell Kestrel (.NET web server) to run directly on port 80 but then we can host only one app with our server. Therefore I use nginx to make a reverse proxy to forward all requests to correct internal running app.

sudo apt-get install nginx
sudo service nginx start

Edit nginx config at /etc/nginx/sites-available/default to forward all requests to our app

server {
    listen 80;
    location / {
        proxy_pass http://localhost:5123;
        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;
    }
}

Then test our changes with

sudo nginx -t 

-t 	Don’t run, just test the configuration file. NGINX checks configuration for correct syntax and then try to open files referred in configuration.

If no error happens then nginx should reload the new config

sudo nginx -s reload

-s signal 	Send signal to a master process: stop, quit, reopen, reload. (version >= 0.7.53)

2.7 Start website

We have set up our app to be ready. The website is still not running because we’ve started it yet. You can manually start it by running command dotnet run, I’ll use supervisor to start and watch our app.

sudo apt-get install supervisor

Create a config for our hwapp

 
sudo nano /etc/supervisor/conf.d/hwapp.conf
[program:hwapp]
command=/usr/bin/dotnet /var/hwapp/hwapp.dll --server.urls "http://*:5123"
directory=/var/hwapp/
autostart=true
autorestart=true
stderr_logfile=/var/log/hwapp.err.log
stdout_logfile=/var/log/hwapp.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data
stopsignal=INT

Save the config file, and start our app with following commands

sudo service supervisor stop
sudo service supervisor start
sudo tail -f /var/log/supervisor/supervisord.log

Then in the browser, browse to your vps. You’ll see your website running.

If our app somehow crashes, supervisor will try to restart our app automatically.

3. Conclusions

It’s pretty simple to deploy ASP.NET core application to Linux VPS. Because of security reasons the setup above is not secure enough. However, for testing purpose or for individual developers, this easy setup can speed up the deployment process. We can also use a single VPS with Nginx to host multiple apps. If I can find a free domain, I’ll make another demo to show how we can host multiple apps on a single Linux VPS.

Leave a Reply

Your email address will not be published. Required fields are marked *