Installera dotnet 5.0 och NGINX på Ubuntu 20.04

Förkrav

Denna installation kräver att du har tillgång till en Ubuntu server med root access, antingen direkt eller via sudo. Om du kör servern lokalt eller i molnet är ditt eget val. Jag utgår här ifrån att du satt upp en separat användare med root behörighet och kommer därför att köra alla kommandon med sudo. Är din server nyinstallerad kan du givetvis köra direkt som root.

Installera NGINX

Jag kommer att använda NGINX som webbserver i denna guide eftersom jag föredrar den konfigurationen över Apache. Föredrar du att använda Apache går det givetvis bra. Vi börjar som vnaligt med att uppdatera repositoryt:

sudo apt update

Därefter installerar vi NGINX:

apt install nginx

Om du har UFW påslaget så lägg till regler för att släppa igenom trafik på port 80 och 443

sudo ufw app list

Detta kommer att ge dig en lista med installerade färdiga applikationsregler för installerade program. Du bör se Nginx HTTP, Nginx HTTPS och Nginx full i listan.

Http öppnar port 80, https öppnar port 443 och full öppnar båda dessa portar för trafik. Jag rekommenderar att du använder full i detta fall.

sudo ufw allow "Nginx Full"
sudo ufw status

Du bör nu se både Nginx regeln och OpenSSH.

Pröva nu att gå till din domän eller ip i en webbläsare och kontrollera att du ser Nginx startsida. Om servern inte svarar kan du pröva att starta om Nginx med sudo service nginx restart

Installera ASP.NET 5.0 Runtime

Nu är det dags att installera .NET runtime. Du kan installera SDK på samma sätt om du behöver kunna bygga och publicera applikationer på servern.

.NET 5 finns inte i de ursprungliga paketlistorna som följer med Ubuntu, men Microsoft har ett deb paket för att lägga till detta.

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update

INstallera apt-transport-https och kör sedan apt update igen.

sudo apt install apt-transport-https
sudo apt update

Nu är det dags att installera Runtime eller SDK. I detta lägger installerar jag bara runtime för ASP.NET core för att kunna köra webbapplikationer. Du finns även en vanlig dotnet core runtime om du inte tänker köra webbapplikationer.

sudo apt install aspnetcore-runtime-5.0

Kontrollera installationen med dotnet –list-runtimes

Skapa en enkel .NET core applikation

Skapa en enkel asp.net applikation för att testa ha ett sätt att testa din installation. Vi kommer att behöva göra fler inställningar i NGINX, men det är lika bra att ha detta ur vägen. I mitt fall väljer jag att skapa en enkel Blazor server applikation.

OBS! Detta visar inte alla steg.

Öppna startup.cs och lägg till följande överst i Configure.

            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

Detta skickar headers vidare när du använder en reverse proxy vilket vi ska göra i detta fall. Mer om detta senare.

Vill du läsa mer om detta så hänvisar jag till Microsoft dokumentationen (Se nedan).

Observera att ovanstående kräver att du lägger till en using Microsoft.AspDotNetCore.HttpOverides.

Kontrollera nu att appen fungerar lokalt. Ändra sedan target till release och kör publish på din applikation genom att högerklicka på projektet och välj publish.

Under konfigurationen för publicering välj Folder som i bilden nedan.

När du konfigurerat din publicering dyker följande bild upp.

Du kan här välja att klicka på pennorna och göra ytterligare inställningar. Försälra dig om att aplikationen är konfigurerad för release och att target är Linux. Du kan även välja att använda någon av inställningarna jag använt i bilden nedan.Notera även att du kan göra en build utan att ha .NET 5 installerat på servern. Eftersom vi precis installerat detta väljer vi dock att använda ”framework dependent” för att spara server resurser. Jag har inte själv prövat att publiscera builds som inte kräver förinstallerat framework, så pröva gärna detta när du har möjlighet och se vad skillnanden blir.

När du är nöjd med inställningarna, tryck på ”Publish”.

Ladda nu upp din applikation till servern på valdritt sätt. Jag brukar använda WinSCP för detta, men de flesta moderna SFTP klienter kan ansluta via ssh/SFTP så vad som helst fungerar. Tänk bara på att ladda upp applikationen någonstans där du har skrivrättigheter, eller där du tänker köra den. I det här fallet laddar jag upp min applikation under /var/www/mytestapp.

Det är bara innehållet i Publish katalogen (som standard \bin\release\net5.0\Publish) som behöver laddas upp.

Konfigurera NGINX som reverse proxy

Nu när vi har vår applikation uppladdad på servern skulle vi i princip kunna starta den, men eftersom vi tidigare installerat NGINX är tanken att vi ska använda denna som reverse proxy. Detta gör det möjligt att köra flera webbapplikationer på samma server, eller till och med köra applikationen på en annan server med en webbserver framför som hanterar inkommande och utgående trafik. Detta bör även minska lasten något på applikationen eftersom du kan hantera caching och statiska filer direkt i NGINX. Just nu körs inte vår .NET applikation alls. Vi kan gå in i katalogen den ligger i och starta den med dotnet följt av namnet. Pröva att starta din app med dotnet appnamn.dll bara för att se så att den fungerar. Om du inte har någon brandvägg installerad bör du även kunna anropa den på den bort som anges. När du ser att den fungerar, stoppa den med CTRL+C.

Jag föredrar att lägga varje webbplats eller åtminstone varje domän i en separat konfigurationsfil för NGINX, detta gäller även min nya testapplikation för dotnet 5.

sudo nano /etc/nginx/sites-available/dotnet5testapp.conf

Du kan givetvis kalla din konfigurationsfil för vad du vill, se bara till att vara konsekvent. Jag brukar kalla dem för bara domännamnet eller domännamn.conf.

Klistra in följande kod i konfigurationsfilen, och byt ut server_name samt eventuellt den port din applikation kör på. Eftersom detta är din första applikation bör port 5000 vara ledig, men om du lägger upp flera applikationer behöver du köra dessa på olika portar.



    server {
        listen      80;
        server_name dev.datortips.se;
        location / {
            proxy_pass         http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            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;
        }
    }





Efter att du sparat en ny konfigurationsfil i sites-available som ovan behöver denna länkas in för att läsas av NGINX. Dessa länkar ska i Ubuntu ligga under sites-enabled. Vi skapar länken på följande sätt: Observera att om du döpt din konfigurationsfil till något annat än mitt exempel ovan så länkar du dit istället.

sudo ln -s /etc/nginx/sites-available/dotnet5testapp.conf /etc/nginx/sites-enabled/dotnet5testapp.conf

Ovanstående kod skapar en mjuklänk i sites-enabled till den fil du just skapat i sites-available.

Du kan nu starta om NGINX

sudo service nginx restar

Kontrollera att du inte får några fel vid omstarten. Om du har någon annan webbplats på servern kan du alltid kontrollera så att den fungerar.

Om vi ska köra en Blazor server app, eller en annan app som använder sig av SignalR rekommenderas även ytterligare en ändring. Denna gång i nginx.conf.

sudo nano /etc/nginx/nginx.conf

Lägg till följande i http blocket i denna fil.


    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }

Gå nu till den katalog där du sparade din publicerade .NET applikation och starta applikationen.

cd /var/www/testapp/
dotnet mynewblazorapp.dll

I mitt fall la jag den i /var/www/testapp och döpte den till mynewblazorapp så det är detta jag kör här.

Om allt går rätt så får du nu upp ett meddelande om att applikationen lyssnar på port 5000 och 5001 för http resp. https.

Det är nu dags att pröva om du kommer åt applikationen via webbläsaren. Gör detta utan att trycka CTRL+C så att applikationen fortsätter köras.

Om du kommer åt applikationen så fungerar allt korrekt. Du har dock ett problem kvar att lösa. Just nu kommer applikationen att stoppas om du trycker CTRL+C i terminalen eller lämnar den. Det samma gäller om servern startas om. Vi behöver därför skapa en service som håller applikationen igång och ser till att den startar när server startar.

Skapa och aktivera en service-fil som håller applikationen igång

Börja med att skapa en ny fil.

sudo nano /etc/systemd/system/dotnettestapp.service

Namnet är givetvis valfritt, men det är bra att kalla den .service och den ska ligga på samma ställe som ovan.

Klistra sedan in följande och gör nödvändiga ändringar för din egen applikation

[Unit]
Description=Exempelapplikation

[Service]
WorkingDirectory=/var/www/testapp
ExecStart=/usr/bin/dotnet /var/www/testapp/mynewblazorapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=mynewblazorapp
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Sedan aktiverar vi tjänsten genom att köra följande.

 sudo systemctl enable dotnettestapp.service

Ange samma namn här som du angav på filen ovan.

Du kommer att få följande meddelande.

Created symlink /etc/systemd/system/multi-user.target.wants/dotnettestapp.service → /etc/systemd/system/dotnettestapp.service.

Pröva nu att starta tjänsten.

 sudo service dotnettestapp start

Du ska nu komma åt din app via webbläsaren på samma sätt som tidigare. Vill du vara riktigt säker på att allt fungerar som det ska kan du pröva att starta om hela servern.

sudo shtudown -r now

Du har nu tillräckligt för att kunna sätta upp och köra minst en dotnet 5 applikation. Behöver du köra flera kan du ändra vilken port de lyssnar på när du skapar servicefilen ovan. Lägg bara till följande rad.

Environment=ASPNETCORE_URLS=http://localhost:5002

Du kan givetvis välja vilken port du vill här så länge den är ledig.

Nästa steg

Nästa steg är, förutom att skapa en riktig applikation, att göra uppkopplingen till din applikation säker. Detta täcks inte av denna guide, men du kan göra detta i Nginx oavsett vilken sorts webbapplikation du kör. Jag kommer att gå igenom detta vid ett annat tillfälle.

”Self-contained” applikationer

Det finns ett sätt att köra .NET applikationer utan att först installera .NET framework på servern. Vid publicering kan du välja att göra en ”Self-contained” build. Detta inkluderar hela ramverket i applikationen och du kan då köra den som en vanlig binärfil. Detta innebär dock att du inkluderar hela .NET 5 i applikationen och den tar därför upp betydligt större plats. Jag är inte säker på hur och om detta påverkar prestandan om du kör flera applikationer på detta sätt, men det är möjligt att samma bibliotek laddas flera gånger i minnet. Skillnaden i storlek är markant. När jag testade med en enkel Blazor app gick den från ca 1.5Mb till 80Mb i upptaget diskutrymme. Fördelen kan dock vara att du får med en specifik version av ramverket och kan stanna på den även om du uppgraderar servern eller flyttar applikationen.

Mer läsning

Microsoft har ett antal guider för att köra .NET applikationer i olika miljöer. Under skapandet av denna guide har jag använt mig av dessa.

Host ASP.NET Core on Linux with Nginx

Host and deploy Blazor Server

De har även guder för att göra samma sak med Apache som webserver, om man hällre vill köra den.

Sätt upp en Ubutu 20.04 server

Förkrav

Denna guide går igenom grundläggande setup av en Ubutnu 20.04 server. Den förutsätter att du precis har avslutat installation av servern (alternativt skapat en VPS hos någon molntjänst). Den kräver även att OpenSSH finns installerat, och att du har tillgång till en terminal som kan köra ssh (För Windows rekommenderar jag gitbash eller Putty).

Logga in och gör dig bekant med terminalen

Börja med att logga in på din nya server via en terminal

ssh root@dinip

Du kommer nu att få ange lösenordet du angav vid installationen. Om du anger detta korrekt kommer du att vara inloggad på din nya server.

Du kommer antagligen se något i stil med:

root@servername:~

~ i slutet betyder att du är i din hemkatalog. I detta fall /root då du är inloggad som root.

Om root användaren

Som root har du möjlighet att göra i princip vad du vill på servern. Du kan komma åt vilka kataloger du vill, ändra, lägga till eller ta bort vilka filer du vill osv. Det kan vara praktiskt, men av säkerhetsskäl är det bra att skapa separata användare för olika typer aktiviteter. Vi kommer att göra detta straxt, men först är det dags att se till att servern är uppdaterad med de senaste paketen.

Installera de senaste uppdateringarna

MEd din Ubuntu installation följer en lista med länkar till paket som är, eller kan installeras. Det finns flera sådana listor, men de som är inlagda från början är testade för att fungera på denna version av Ubuntu. Senare kan du själv lägga till nya paketlistor (repositories).

Först av allt behöver vi uppdatera de paketlistor som finns. detta görs med följande kommando.

apt update

Efter att detta är klart (brukar ta 30 sekunder eller så första gången) bör du uppdatera de paket som redan finns installerade. detta görs med apt update. Kör detta kommando nu.

apt upgrade

Detta tar något längre tid, och du kan få ett antal val om du vill skriva över konfigurationsfiler eller liknande för befintliga paket.

När uppdateringen är klar kan det vara en bra idé att skapa en sätta upp en icke-root användare.

Kör följande för att lägga till en användare:

adduser ditt_användarnamn

Byt ditt_använarnamn mot ett länkligt användarnamn, och följ sedan instruktionerna. Notera lösenordet du skapar för denna användare.

Som nämnts kan det vara bra att använda en annan användare för inloggning för att inte exponera root användaren. Med denna första användare du skapat vill du dock troligtvis ha möjlighet att köra kommandon som root, även om du inte är inloggad som root. Detta kan du göra genom att lägga till användaren i gruppen sudo. Detta är en speciell grupp som tillåter att användare kör kommandon med root privilegier genom att lägga till sudo framför kommandot som ska köras.

Ge användaren möjlighet att köra kommandon som root:

usermod -aG sudo ditt_användarnamn

Glöm inte att byta ditt_användarnamn mot användarnamnet du angav när du skapade användaren.

Du kan nu pröva att logga in som din nya användare via en ny terminal.

Sätt upp en grundläggande brandvägg

Det kan vara en bra idé att skydda din server med en grundläggande brandvägg. Tänk dock på att när du installerar applikationer senare måste de portar dessa applikationer använder läggas till i brandväggen. Detta är inte svårt, men lätt att glömma.

Vi kommer att använda Ubuntus inbyggda brandvägg för denna gude.

För att göra det lättare lägger vissa applikationer till färdiga regler i brandväggen som du bara behöver slå på. DU kan lista vilka applikationsregler som finns i brandväggen genom att gköra följande: kommando listar tillgängliga applikationer:

ufw app list

Om du inte installerat något extra kommer du troligen bara att se OpenSSH listad här. Denna behöver vi tillåta innan vi slår på brandväggen.

ufw allow OpenSSH

Slå sedan på brandväggen med:

ufw enable

Kontrollera brandväggen med ufw status

ufw status

VARNING: Om du inte utfört ovanstående korrekt kan det hända att du inte kan logga in utifrån längre. Pröva därför att logga in med din nya användare i ett nytt fönser, på samma sätt som du loggade in med root tidigare:

ssh ditt_användarnamn@din_ip

Om du kommer in som du ska med den nya användaren så är allt ok.

Viktiga kataloger

Innan vi avslutar denna guide kan det vara värt att få koll på några av de kataloger du ofta använder.

  • /var: Innehåller mestadels data. Databaser, loggar och webbbibliotek brukar lägga i denna katalog
  • /etc: Innehåller konfigurationsfiler för installerade applikationer. Det är ofta här man genomför konfigurationsändringar.
  • /usr: Användarinstallerade applikationer och bibliotek.
  • /home: Användarkataloger. Varje användare får en katalog under home. Du kan även välja att skapa andra kataloger här.
  • /bin: körbara filer och exekverbara kommandon

Det finns flera kataloger, men dessa är de du kan tänkas ha att göra med vid normal användning.

Nästa steg

Nu när din server är uppsatt och konfigurerad, kan du gå vidare och installera andra applikationer beroende på vad du ska använda servern till. För en vanlig webbserver kan du tänkas behöva Nginx eller Apache samt en databas och ett serverspråk. Jag planerar att skriva framtida guider för en del av detta, men just nu är du hänvisad till andra guider för att utföra dessa installationer. Om du genomfört steget med UFW. Glöm inte att lägga till eventuella webbservrar i branväggen för att slippa onödig felsökning.

Lycka till!