How to deploy ASP.NET Core 3.1 app to Digital Ocean Linux droplet
I have a new blogpost on auto deployment an ASP.NET 6.0 application from GitHub to an Digital Ocean App.
You can find the post here
In this tutorial we will deploy and host a simple ASP.NET Core 3.1 demo app on Ubuntu 18.04 droplet in Digital Ocean.
You can download or clone the demo app from my GitHub, or you can deploy your own ASP.NET Core 3.1 application. Just keep in my mind that this demo app doesn't make use of a database. So in this tutorial we don't setup a database. Maybe I'll write another tutorial about implementing an MySql server.
We will break this up in different steps:
1. Create Digital Ocean Ubuntu droplet
2. Create a new user in Ubuntu
4. Deploy our ASP.NET Core 3.1 app to Ubuntu
5. Install and configure NGINX in Ubuntu
Create Digital Ocean Ubuntu droplet
Create Digital Ocean account
First of all, you'll need a Digital Ocean account. If you haven't an DO account than you can create an account with this referral link and you'll get $100 credits to spend in the next 60 days.
Create Digital Ocean project
Once you're logged in, create a new project by clicking on the + New Project link:
In the next screen you'll need to enter an name, description and tell DO what want to do with the project.
When you're done, click on the Create Project button.
On the next screen click on the Skip for now link below.
Now it's time to create our droplet.
Click on the Get Started with a Droplet button
Create Digital Ocean droplet
Now it's time to create a droplet! First we have to choose an image distribution, in our case we choose Ubuntu 18.04.3 (LTS) x64:
We choose the Basic plan for $5/mo (scroll to the left):
We don't need block storage, so we'll skip that.
Choose a data center region close to your hometown, in my case I'll choose Amsterdam:
For the authentication, choose SSH Keys and click on the New SSH Key button:
Then follow the steps described on the right:
Now it's time to finalize and create our droplet. In my case I added backups, but for this demo purposes you don't have to.
Now click on the Create Droplet button.
Now DO will create this droplet (give it some seconds). When everything is done you'll see the droplet and it's IP address. Something like this example:
If you enter the IP address in your browser you'll get an error. This is normal, because we only have a droplet with Ubuntu. But we have to configure our Linux VPS. Let's do this next.
Create a new user in Ubuntu
We need to login into our server. We'll do this through SSH. You can download PUTTY or download PowerShell (Scroll down to assets to download). In my case I'll use PowerShell.
Connect with SSH to the server
Open PowerShell and SSH into your droplet through this command to log in to your server as the root user:
ssh root@
The IP address from my droplet is 167.172.37.58. Change the IP address by your droplets IP address
ssh [email protected]
Type yes if you get this message:
The authenticity of host '167.172.37.58 (167.172.37.58)' can't be established.
ECDSA key fingerprint is SHA256:VodrbvWvtonPzxiFpRiuoq0tTrgZjow+YIGUOXukx7w.
Are you sure you want to continue connecting (yes/no)?
By typing yes the connection closes, so I'll need to login again:
ssh [email protected]
Now you're asked to enter your passphrase. Enter your passphrase (or paste it with the right mouse button) and hit enter:
Enter passphrase for key 'C:\Users\dries.deboosere/.ssh/id_rsa':
Now we're logged in to the server as the root user:
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Aug 9 15:24:27 UTC 2020
System load: 0.0 Processes: 81
Usage of /: 4.0% of 24.06GB Users logged in: 0
Memory usage: 11% IP address for eth0: 167.172.37.58
Swap usage: 0%
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@ubuntu-s-1vcpu-1gb-ams3-01:~#
Create new user
First we'll create a new user on the server:
adduser USERNAME
A little explanation about these commands:
adduser: create a new user with the name of USERNAME
USERNAME: the username for the new user. In my case I'll use dries as the username
Now enter following commands in PowerShell with your username:
adduser dries
The user dries is now created:
root@ubuntu-s-1vcpu-1gb-ams3-01:~# adduser dries
Adding user `dries' ...
Adding new group `dries' (1000) ...
Adding new user `dries' (1000) with group `dries' ...
Creating home directory `/home/dries' ...
Copying files from `/etc/skel' ...
Now your asked to choose a password. Enter the password and confirm your password:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Now your asked about some information. You can fill this in or press ENTER for the default values. In my case I press ENTER and at the end I choose yes by typing y:
Changing the user information for dries
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] y
Give administrator/sudo privileges to our new user
Now our new user needs to get administrator/sudo privileges. So let set this up. To do this we'll need following commands:
usermod -a -G sudo USERNAME
A little explanation about these commands:
usermod: calls the program
-a: to add the user to a group
-G: to specify the group
sudo: stands for 'super user do'. This will execute root commands as an non-root user.
Now enter following commands in PowerShell with your username:
usermod -a -G sudo dries
Now I want the same ssh key for the root user and for the new created user (dries). We can copy this key by following commands (change dries by your username):
cp -r ~/.ssh /home/dries/
sudo chown -R dries:dries /home/dries/.ssh
Now restart the SSH service by following command:
sudo service ssh restart
Now exit the server by typing the exit command:
exit
Now it's time to login as the new created user:
ssh [email protected]
You'll be asked for the passphrase. Because we copied over the ssh key from root user to dries we can now use the same passphrase from the root user. Enter the passphrase:
Enter passphrase for key 'C:\Users\dries.deboosere/.ssh/id_rsa':
Now you should see this in PowerShell:
dries@ubuntu-s-1vcpu-1gb-ams3-01:~$
This means we're now logged in as user dries in the server.
Install .NET SDK in Ubuntu
Now it's time to install .NET on Ubuntu. We can go to the Microsoft documentation website to see which commands we need to install this on our Ubuntu 18.04 server.
First we install the Microsoft package sources:
wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
Then we install the .NET 3.1 SDK:
sudo apt-get update
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install -y dotnet-sdk-3.1
Next we check if it's installed by running following command:
dotnet --info
You should see something similar like this:
.NET Core SDK (reflecting any global.json):
Version: 3.1.302
Commit: 41faccf259
Runtime Environment:
OS Name: ubuntu
OS Version: 18.04
OS Platform: Linux
RID: ubuntu.18.04-x64
Base Path: /usr/share/dotnet/sdk/3.1.302/
Host (useful for support):
Version: 3.1.6
Commit: 3acd9b0cd1
.NET Core SDKs installed:
3.1.302 [/usr/share/dotnet/sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.App 3.1.6 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.6 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download
Deploy our ASP.NET Core 3.1 app to Ubuntu
Now it's finally time to publish our ASP.NET Core app to the server. But first we need to make some arrangements. We'll going to be using the instructions from the Microsoft documentation to host our ASP.NET Core app on Linux to deploy our app.
For this tutorial I'll use a simple demo ASP.NET Core 3.1 web application. You can use your own application or else you can clone/download my demo application from my GitHub repository.
There are many ways to deploy the files to a server. In this case we will deploy our files through an FTP connection to our server. We can do this through the build in FTP client in Visual Studio or with an FTP client of choice (FileZilla, ...)
Create application folder on our server
We'll deploy our app to the /var/www/ directory from our server. But this doesn't exist yet, so we have to create this folder. We also need to give access to our user we've created and to the www-data user. This www-data user will be used to run the app.
Type in following commands in PowerShell and replace
sudo mkdir /var/www/
sudo mkdir /var/www/
sudo chown -R dries:www-data /var/www/
Install an FTP server on Ubuntu
We will install an FTP (File Transfer Protocol) server on Ubuntu so we can transfer our files to Ubuntu.
Make sure that our system packages are up to date by running following command:
sudo apt-get update
Now it's time to install an FTP server. We will using the common open-source FTP utility vsftpd. To install vsftpd enter the following command:
sudo apt install vsftpd
Enter Y to continue
Now start vsftpd by entering following command:
sudo systemctl start vsftpd
To make sure that vsftpd is launched and enabled at startup entering following command:
sudo systemctl enable vsftpd
Open your FTP client of choice (for me this is FileZilla) and make a connection by entering the IP address from your server and your credentials (in my case user dries). Now check if you have access to the following path: /var/www/
Now we need to config vsftpd so we can upload files. At this moment we can only read files from the server but not upload any file. Open the vsftpd configuration file through PowerShell:
sudo nano /etc/vsftpd.conf
Find the entry write_enable=YES and uncomment this line. Don't forget to save this configuration.
Now restart the vsftpd service:
sudo systemctl restart vsftpd.service
Publish our web application
Now open a new PowerShell window and navigate to your solution folder:
Type in the following command:
dotnet publish
You should see something similar like this:
Now open your Windows Explorer and navigate to the following folder:
These files and folders need to be uploaded to our server. Select all the files and folders and move/drag them to the /var/www/
If everything worked correctly, our app is now ready to run. But if you enter the IP address of your server in a web browser, you will see that this is not working (yet!).
We are almost there! We just need to install a web server on Ubuntu. Let's do that next.
Install and configure NGINX in Ubuntu
Now it's time to install a NGINX webserver and setup a reverse proxy. A reverse proxy will forward requests made to our server to our app. As a webserver we will use NGINX and for the configuration of our reverse proxy server we will follow the Microsoft documentation.
Install NGINX
We follow the NGINX documentation to install NGINX on our Ubuntu release.
We first need to add the repository to our source.list file:
sudo nano /etc/apt/sources.list
At the bottom of the file add following lines:
deb http://nginx.org/packages/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/ubuntu/ xenial nginx
Exit and save the file. Then enter following commands:
sudo apt-get update
sudo apt-get install nginx
Run NGINX though following command:
sudo service nginx start
Enter the IP address from your server in your browser. You should see the default NGINX welcome page:
Add an SSL certificate with Certbot (if you have a domain name!)
When you have a domain name that you can redirect to your IP address then you can secure your website with an SSL certificate from Let's Encrypt by using Certbot.
If you haven't a domain name, then skip this step.
Add the Certbot PPA and install with following commands:
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx
Next run the following command and enter your e-mail address when asked. Agree with the Terms of Service by typing A and add your domain name.
sudo certbot --nginx
Forward requests to our app
Now it's time to forward the requests to our app instead of the NGINX welcome page.
Enter following command to configure this:
sudo nano /etc/nginx/sites-available/default
Replace the content of that file with following text:
server {
listen 80;
server_name ;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Now we need to enable the site by linking it to /etc/nginx/sites-enabled/default with following command:
sudo ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
We now need to ensure that the default site is included in the http section of the NGINX config file. Edit the file with the following command:
sudo nano /etc/nginx/nginx.conf
And below, where you'll find
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
Add the following line below:
http{
...
include /etc/nginx/sites-available/default;
}
Now restart NGINX:
sudo service nginx restart
Now start the app by the following command:
dotnet //.dll
In my case this command will be:
dotnet /var/www/driesdeboosere-dev-demo-web/DriesDeboosere.Dev.Demo.Web.dll
Type in your browser your IP address now and you should see your website:
Create service
The next task is to set up our web application to run as a service, so you don't have to be logged in to your server for your application to run. Ubuntu uses systemd by default for managing services. So first we need to create a service file (remember the name of the file as this is what you will reference to control it) by entering following commands:
sudo nano /etc/systemd/system/.service
In my case:
sudo nano /etc/systemd/system/driesdeboosere-dev-demo-web.service
Enter the service information:
[Unit]
Description=My application service
[Service]
WorkingDirectory=/var/www/
ExecStart=/usr/bin/dotnet /var/www//.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
In my case:
[Unit]
Description=My application service
[Service]
WorkingDirectory=/var/www/driesdeboosere-dev-demo-web
ExecStart=/usr/bin/dotnet /var/www/driesdeboosere-dev-demo-web/DriesDeboosere.Dev.Demo.Web.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=driesdeboosere-dev-demo-web
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
Give read, write and execute rights to the folder:
sudo chown -R : /var/www/
sudo setfacl -R -d -m u::rwx,g::rwx,o::r /var/www/
In my case:
sudo chown -R dries:dries /var/www/
sudo setfacl -R -d -m u:dries:rwx,g:dries:rwx,o::r /var/www/
Then start the service with following command:
sudo service start
Or in my case:
sudo service driesdeboosere-dev-demo-web start
Check if it's running:
sudo systemctl | grep
Or in my case:
sudo systemctl | grep driesdeboosere-dev-demo-web
That's it! Now your web server will keep running your ASP.NET Core app, even if you exit the server.