Publishing an ASP.NET Core website to a Linux host

I recently move my web site to a Linux host, remember, .NET Core is multi-platform 😃 This choice is mainly motivated by the price. Indeed, you can find many cheap VPS providers (Virtual Private Server) on the internet. For instance, you can choose OVH. They have great VPS for about 3€ per month (I'm not paid by them, but I've been using their services for a few years without any issue).

Hosting a site on Linux is not as easy as hosting on Windows, at least for me. I think this is mainly because I don't use Linux on a daily basis 😃

So, this is the steps I followed to deploy my websites on Ubuntu 16.04 and use Let's Encrypt for SSL.

I use vim to edit files. If you are not familiar with it, you may prefer nano. Just replace vim by nano in the commands lines.

Step 1 - Connect to the VPS using ssh

Once you get your VPS, you should have an IP address and the password of the root user. This allows to connect to the machine using SSH. If you are running Windows 10, you can enable the Windows subsystem for Linux (WSL) feature. Then, you can use the native SSH command.

bash
ssh root@ip

Step 2 - Change the root password

For obvious security reasons, you must change the password of the root user using the passwd command:

passwd

Then, enter the new password.

Step 3 - create a non-root user

Using the root user is not a good practice. Instead, you should create a new user:

adduser myuser          # you'll be prompt for the password
usermod -aG sudo myuser # Add the user to the sudo group to be able to use admin commands
exit                    # terminate the session

Then, reconnect to the server using the new user:

ssh myuser@ip

Step 4 - Update the server

Before doing anything, you should install updates:

sudo apt-get update        # Fetches the list of available updates
sudo apt-get upgrade       # Strictly upgrades the current packages
sudo apt-get dist-upgrade  # Installs updates (new ones)
sudo reboot

If you prefer updates to be installed automatically, you can use unattended-upgrades:

sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Step 5 - Configure the firewall

By default, all ports are opened. For a web server, you only need to open the ports 80 and 443. Don't forget to leave the port 22 opened, or you won't be able to use SSH anymore.

sudo ufw default deny           # deny all incoming connections
sudo ufw default allow outgoing # allow all outgoing connections
sudo ufw allow ssh              # allow the incoming ssh port
sudo ufw allow 80/tcp           # allow the incoming 80 port
sudo ufw allow 443/tcp          # allow the incoming 443 port

sudo ufw enable                # enable the firewall
sudo ufw status verbose        # check everything is ok

Step 6 - Copy your site to the server

If you don't have an ASP.NET Core app yet, you can easily create one using only one command:

dotnet new mvc

You should use the Microsoft.AspNetCore.HttpOverrides package and app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }) to get the actual url instead of localhost:5000 in the application as the web site behind a reverse proxy.

Then, copy the publish output to /var/www/mysite using filezilla, scp or rsync:

 # compile and generate the website files
dotnet restore
dotnet publish -c release

# Copy the files to the server (replace ip by the actual ip address)
scp -r ./bin/release/netcoreapp1.1/publish/* myuser@ip:/var/www/mysite

Step 7 - Install .NET Core

To run the website, you must install the .NET Core shared runtime (unless you create a self-contained application).

# If not Ubuntu 16.04, read the doc https://www.microsoft.com/net/core#linuxubuntu
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

# Replace 1.1.1 by the version your application need
sudo apt-get install dotnet-sharedframework-microsoft.netcore.app-1.1.1

Step 8 - Start the web site

You must configure systemd to start dotnet as a service.

sudo vim /etc/systemd/system/kestrel-mysite.service
[Unit]
    Description=MySite

    [Service]
    WorkingDirectory=/var/www/mysite
    ExecStart=/usr/bin/dotnet /var/www/mysite/mysite.dll
    Restart=always
    RestartSec=10    # Restart service after 10 seconds if dotnet service crashes
    SyslogIdentifier=dotnet-mysite
    User=www-data
    Environment=ASPNETCORE_ENVIRONMENT=Production

    [Install]
    WantedBy=multi-user.target
sudo systemctl enable kestrel-mysite.service # register the service
sudo systemctl start kestrel-mysite.service  # start the service
sudo systemctl status kestrel-mysite.service # check the service is running

Now you can access the website on the port 5000. You can test it using the wget command:

wget http://localhost:5000

Step 9 - nginx

Kestrel is a good web server. However, Microsoft advices to not expose it directly to the internet. Instead, you should place it behind a reverse proxy such as nginx.

sudo apt-get install nginx
sudo vim /etc/nginx/sites-available/default

Replace everything 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;
    }
}

Test the configuration:

sudo nginx -t

And reload the configuration:

sudo nginx -s reload

Now, the website is visible on the internet. You can open your favorite web browser, and navigate to http://ip.

Step 10 - Viewing logs

For debugging purpose, you can view the logs of the dotnet process using the following command:

sudo journalctl -fu kestrel-mysite.service

Conclusion

Your website is now online on the 80 port. Don't hesitate to leave a comment if I forgot something. Again, I'm not a Linux expert 😃

The next post is about securing the website using a free SSL certificate provided by Let's Encrypt.

Enjoy this blog? Buy Me A Coffee Donate with PayPal

Comments

Nawaraj Subedi -

Thanks for the article. It is very useful for me. How to deploy multiple .net core app in same machine with Apache

austinsistercities.weebly.com -

Nice blog here! Also your website loads up very fast! What web host are you using? Can I get your affiliate link to your host? I wish my site loaded up as fast as yours lol

Leave a reply