11 Feb 2022 - David Baker
Tags: digitalocean linux code angular dotnet breakingnewsbot
This is part 2 of my Breaking News Bot project. This post is mostly on the infrastructure I used to host it. I will walk you through how to set up a .NET 6 Web Api backend and Angular Front end application on a $5/month DigitalOcean droplet running Ubuntu 20.04. More realistically this is going to serve as my own reference when I forget how I configured my server and need to do it again.
My problem was that I had to refer to many different pages and guides to do this. Rather than repeat everything those guides said, this page is going to be a reference and checklist of which guides to follow and what needs to be done. But first I wanted to talk you out of this.
Not really. This was mostly a learning excercise for me. Plus I wanted to move OFF of Azure onto a server I controlled. Essentially all this configuration can be elimited by doing one of the following:
The true benefits I got out of doing this are:
Like I said there are a couple of easier alternatives including the cloud hosted app services. First I wanted to explain why I went with DO and I’m not even being paid to say this.
The giant cloud platforms have so many options that the pricing changes violently when you click anything. Look at what happened when I accidentally clicked “Memory Optimized” while setting up my $5 Google Cloud VM.
This type of stuff annoys the shit out of me. Who is setting up a $38,000 a month server in the same place they set up a $5 / month server?
Anyway, that’s the type of stuff that leads me to the simplicity of Digitial Ocean. Alright, let’s get started.
Recommendations
ufw
. I recommend using the Cloud Digital Ocean networking firewall. Keeps you from locking yourself outsudo apt-get install mysql-server
sudo mysql_secure_installation utility
cd /etc/mysql/mysql.conf.d
nano mysqld.cnf
-- change binding address from localhost to 0.0.0.0 to open up mysql to remote
sudo systemctl start mysql
sudo systemctl enable mysql
sudo systemctl restart mysql
Refert to this documentation: How To Create a New User and Grant Permissions in MySQL
mysql -u root -p
CREATE DATABASE *mydb*;
CREATE USER 'dave'@'%' IDENTIFIED BY 'password';
GRANT ALL ON NEWS.* TO 'dave'@'%';
FLUSH PRIVILEGES;
Recommendations
It’s unclear to me how several guides were able to FTP after setting up their droplet without further configuration. I had to follow this entire tutorial: How To Set Up vsftpd for a User’s Directory on Ubuntu 18.04 to get FTP support. The gist is:
vsftp
/etc/vsftpd.conf
4.1 write_enable = YES;
4.2 chroot_local_user = YES;
4.3 Configure directory
4.4 Configure ports
4.5 Configure and create whitelist/etc/vsftpd.conf
sudo systemctl restart vsftpd
use FTP
and Require Explicit FTP over TLS
Reference this documentation: Deploy our ASP.NET Core 3.1 app to Ubuntu
wget https://packages.microsoft.com/config/ubuntu/21.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y aspnetcore-runtime-6.0
On the Server, create the /var/www/ folder where we will host our apps.
sudo mkdir /var/www/
sudo chown -R dave:www-data /var/www/
Also create the 2 directories we will use to host our WebAPI backend, and Angular front end:
sudo mkdir /var/www/api.domain.com
sudo mkdir /var/www/domain.com
dotnet publish -c Release
ftpuser
and FileZilla to /home/ftpuser/ftp/files
/var/www/api.domain.com
ng build
ftpuser
and FileZilla to /home/ftpuser/ftp/files
/var/www/domain.com
We need to grant all to ourselves, and execute to www-data
sudo chown -R dave:www-data /var/www/api.domain.com
sudo chmod -R 755 /var/www/api.domain.com/
sudo chown -R dave:www-data /var/www/domain.com
sudo chmod -R 755 /var/www/domain.com/
api
subdomain like the one in this example: Install an ASP.NET Core Web API on Linuxsites-available
and sites-enabled
. You can sever the link to disable it but keep the configuration in sites-available
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/example.com
sudo systemctl reload nginx
systemctl
service for the .net core app: How To Deploy an ASP.NET Core Application with MySQL Server Using Nginx on Ubuntu 18.04cd /etc/systemd/system
sudo nano api.domain.com.service
[Unit]
Description=API Domain app
[Service]
WorkingDirectory=/var/www/api.domain.com
ExecStart=/usr/bin/dotnet /var/www/api.domain.com/api.domain.dll
Restart=always
RestartSec=10
SyslogIdentifier=movie
User=sammy
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
Enable:
sudo systemctl enable api.domain.com.service
Start it:
sudo systemctl start api.domain.com.service
Check status:
sudo systemctl status api.domain.com.service
Think your done? Think again. Because Angular handles all url routing within the application itself, if you navigate to your-domain.com/about it’ll thrown an NGINX 404 instead of either your angular about page, or your angular 404 page.
/etc/nginx/sites-available/your-domain
one last time. Replace try_files
with this:try_files $uri $uri/ /index.html;
This may be helpful when debugging errors in the running .net core service:
sudo journalctl -fu {your-service-name}.service
Nginx Access Log: Every request to your web server is recorded in this log file
/var/log/nginx/access.log
Nginx Error Log: Any Nginx errors will be recorded in this log.
/var/log/nginx/error.log:
Done