Chris Straw

My Notes – Standup .Net API with Angular on Ubuntu

This is my notes on how I setup a .net core web api with an Angular frontend on a Ubuntu Linux Server


Get the updated list of packages from the Internet

sudo apt update

Install nano editor

sudo apt install nano


Install SFTP (aka SSH) (if not installed)

sudo apt install ssh

Edit the Config

sudo nano /etc/ssh/sshd_config

Paste this at the bottom of the config file (using VIM)

Match group sftp
ChrootDirectory /home
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

Restart the ssh service

sudo systemctl restart ssh

Create SFTP user account (optional)
You can use your regular account to SFTP instead of creating an account

Add a new group called sftp

sudo addgroup sftp

Add a new user call sftpuser

sudo useradd -m sftpuser -g sftp

Create a Password for the new user

sudo passwd sftpuser

Grant permissions to the users home directory

sudo chmod 700 /home/sftpuser/


Install nginx

sudo apt install nginx


Install dotnet

Step 1 – Enable Microsoft PPA (Do this in your home directory)

sudo dpkg -i packages-microsoft-prod.deb 

Step 2 – Install Dotnet Core Runtime

sudo apt update 
sudo apt install apt-transport-https 

Change to match the version of .net you want to install

sudo apt install dotnet-sdk-6.0

Step 3 – Test

dotnet --list-runtimes

Configure app with nginx

Step 1 – SFTP

Set Permission (if need)

sudo chmod 777 /var/www
mkdir /var/www/appname
mkdir /var/www/appname/frontend
mkdir /var/www/appname/api

Open FileZilla SFTP to the server and transfer the files to the directories under /var/www/appname

Step 2 – Configure nginx

This default config
file location: /etc/nginx/sites-available

NOTE: I like editing these files locally and then SFTP to my home directory and copying the file to the nginx directory

sudo cp default /etc/nginx/sites-available/default

Check Config Syntax

 sudo nginx -t

Gracefully stop and restart the service after updating the config

sudo nginx -s reload

My Example of the nginx config. I have the .Net API listing on port 8500.
I originally had several issues with Angular and the browser cache. These cache settings seem to work the best

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  root /var/www/appname/frontend;

  client_max_body_size 30M;

  # X-Frame-Options is to prevent from clickJacking attack
  #add_header X-Frame-Options SAMEORIGIN;

  # disable content-type sniffing on some browsers.
  #add_header X-Content-Type-Options nosniff;

  # This header enables the Cross-site scripting (XSS) filter
  #add_header X-XSS-Protection "1; mode=block";

  #add_header Referrer-Policy "no-referrer-when-downgrade";
  index index.html;

  server_name _;

  gzip on;
  gzip_http_version 1.1;
  gzip_disable "MSIE [1-6]\.";
  gzip_min_length 256;
  gzip_vary on;
  gzip_proxied expired no-cache no-store private auth;
  gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level 9;

  if ($http_user_agent ~* "MSIE ([5-8]{1,}\.\d{0,}\w?\d?);") {
      return 480;
  location / {
    try_files $uri $uri/ /index.html =404;
    # add_header Cache-Control 'max-age=3600'; # one day
    # add_header Cache-Control 'no-store';
    # add_header Cache-Control 'no-cache';
    expires -1;
    add_header Cache-Control "no-store, no-cache, must-revalidate";

  location /api {
      root /var/www/appname/api;
      proxy_pass http://localhost:8500;
      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;

  location /hubs {
      proxy_pass http://localhost:8500;
      proxy_http_version 1.1;
      proxy_set_header   Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header   Host $host;
      proxy_cache_bypass $http_upgrade;



Set the Environment Variables

sudo nano /etc/environment


Step 4 – Test api

cd /var/www/appname/api
dotnet MyApp.WebApi.dll

pull up API URL (assuming SSL disabled and running from root)

Now pull up the Angular app

Step 4 – Create a Service
1) Create a file named kestrel-appname.service locally and copy the text below and save
2) SFTP to your home directory

The Service Definition

Description=AppName.NET Web API App

ExecStart=/usr/bin/dotnet /var/www/appname/api/MyApp.WebApi.dll
# Restart service after 10 seconds if the dotnet service crashes:


Copy file

sudo cp kestrel-appname.service /etc/systemd/system/kestrel-appname.service

Enable Service

sudo systemctl enable kestrel-appname.service
sudo systemctl start kestrel-appname.service
sudo systemctl status kestrel-appname.service

To see the logs

sudo journalctl -u kestrel-appname.service --since "2021-08-08"