20. Jul 2017
Lesedauer 9 Min.
ASP.NET Core Hosting: Allzeit und überall bereit
Hosting
Es gibt mindestens acht Arten, ASP.NET Core auf Windows, Linux und MacOS zu hosten.

Mit dem Web-Framework ASP.NET Core bietet Microsoft eine komplett neu geschriebene und leichtgewichtige Version von ASP.NET an, die sowohl auf .NET Core als auch dem großen .NET Framework laufen kann. In der Core-Variante ist ASP.NET hochgradig Cloud-fähig und lässt sich auf weiteren Betriebssystemen als nur Windows einsetzen. So können Webanwendungen, die auf ASP.NET Core basieren, auf vielen Linux-Distributionen, in Docker-Containern, auf MacOS und natürlich auf den verschiedenen Windows-Versionen laufen. Aber ASP.NET Core lässt sich auch auf ARM-Prozessoren zum Laufen bringen, wie zum Beispiel auf einem Raspberry Pi. Nie war es leichter und flexibler möglich, eine ASP.NET-Applikation bereitzustellen. Dank der plattformübergreifenden Merkmale von .NET Core bleibt diesem Framework nun fast keine Türe versperrt.
Hosting mit Kestrel
Kestrel ist ein auf der systemübergreifenden I/O-Bibliothek Libuv [1] basierender Webserver, der üblicherweise eingesetzt wird, wenn es darum geht, ASP.NET zu beheimaten [2]. Ganz egal, ob eine ASP.NET-Core-Site über die Internet Information Services (IIS), Nginx oder auf Azure gehostet wird, Kestrel ist immer im Einsatz; Kestrel macht die eigentliche Arbeit, während die großen Webserver nur noch als Reverse-Proxy arbeiten [3].Kestrel ist zwar ein vollständiger Webserver, kann aber nur eine Website (im ASP.NET-Jargon auch „Web“ genannt) gleichzeitig ausliefern und im Falle eines kritischen Fehlers kann der Server abstürzen und nicht wieder alleine starten – die Site wäre nicht mehr erreichbar. Daher empfiehlt es sich, einen großen Webserver als Reverse Proxy vorzuschalten. Die großen Webserver sind zudem in der Lage, den Kestrel-Server im Falle eines Absturzes neu zu starten und die Site so erreichbar zu halten. Zudem bieten die großen Webserver weiteren Schutz gegen Attacken aus dem Internet.In einer hausinternen Applikation oder einer Ersatzanwendung, wenn die Webapplikation nicht direkt über das Internet erreichbar ist, kann es aber durchaus Sinn ergeben, eine ASP.NET-Core-Site nur über Kestrel bereitzustellen.Jede neu erstellte ASP.NET-Core-Site nutzt Kestrel als Webserver, siehe Beispiel 1:// Beispiel 1:
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
Hosting mit Web-Listener
Statt dem eigenständigen Kestrel-Prozess lässt sich eine ASP.NET-Core-Site über den Web-Listener hosten. Statt der oben verwendeten Methode UseKestrel() wird dann UseWebListener() eingesetzt, siehe folgendes Beispiel:// Beispiel 2:
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseWebListener()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
Allerdings lässt sich diese Site nicht mit Visual Studio über [F5] starten, solange IIS Express als Webserver ausgewählt ist. Zum Starten der Site muss dann UseWebListener() als Profil zum Debuggen ausgewählt werden. Ein Druck auf [F5] nutzt dann die .NET-Kommandozeile, um die Site zu starten.Außerdem ist der Web-Listener nur auf Windows verfügbar, da dieser – wie auch den IIS-Server – Windows-interne HTTP-Funktionen verwendet.Aus Gründen des Laufzeitverhaltens sollte allerdings Kestrel eingesetzt werden, der inzwischen unter den Top 10 der schnellsten Webserver zu finden ist.
Die .NET-Kommandozeile
Bei der .NET-Kommandozeile handelt es sich um das Kommandozeilen-Interface des .NET Core SDK. Darüber lassen sich .NET-Core-Projekte erstellen, ändern, bauen und ausliefern, aber auch starten. Führt man in der Konsole im Projektverzeichnis den Befehl dotnet run aus, startet die Applikation (Bild 1).
Das ist – nach [F5] in Visual Studio – die einfachste Art, ein ASP.NET-Core-Projekt zu starten, und sie eignet sich hervorragend, um während der Entwicklung oder zu Demozwecken eine Site aufzurufen. Allerdings ist diese Variante aus den eingangs erwähnten Gründen nicht für den produktiven Einsatz geeignet.
Self-hosted
Genau genommen ist jede neu erstellte ASP.NET-Core-Website bereits ein „self-hosted web“ in einer Konsolenanwendung. Wenn man sich die Codebeispiele 1 und 2 genau anschaut, wird das ersichtlich. Es gibt eine Methode static void Main(), wie es bei Konsolenanwendungen üblich ist. Der Start und die Konfiguration des Webservers erfolgen innerhalb dieser Methode. Diese Zeilen lassen sich, so wie sie sind, in jeder beliebigen Applikation nutzen. Lediglich die Einbindung der IIS kann dann gegebenenfalls entfernt werden. Erstellen Sie eine Startup-Klasse mit der nötigen Konfiguration, die dort erreichbar ist, und hängen sie diese wie oben gezeigt in die Applikation ein.Hosting im IIS-Server
Etwas mehr Aufwand ist nötig, um eine Site im eigenen IIS-Server zu hosten. Denn eine ASP.NET-Core-Site kann nicht direkt so, wie sie ist, in den IIS eingebunden werden. Das ist neu im Gegensatz zu herkömmlichen ASP.NET-Projekten: Ein ASP.NET-Core-Projekt muss für das Hosting in den IIS vorbereitet werden.
Visual Studio 2017 löst dies aber recht gut. In einem geöffneten ASP.NET-Core-Projekt führt ein Klick mit der rechten Maustaste im Projektmappen-Explorer auf das Projekt und dann auf den Menüpunkt Veröffentlichen… zur entsprechenden Ansicht der IDE; das ist keine Dialogbox mehr, sondern eine Ansicht im Hauptbereich von Visual Studio (Bild 2). Hier ist IIS, FTP, usw. zu wählen. Erst danach öffnet sich ein mehr oder weniger bekannter Dialog zum Publizieren von Webapplikationen.In diesem Dialog mit dem Titel Veröffentlichen gibt es nun die Auswahl zwischen folgenden Veröffentlichungsmethoden:
- Web Deploy
- Web Deploy-Paket
- FTP
- Dateisystem
Bild 3 zeigt die Einstellungen für das Publizieren in die lokalen IIS. Visual Studio muss dafür mit einem Administratorkonto ausgeführt werden, um Einstellungen am IIS-Server vorzunehmen zu können. Die Site CoreWebApplication muss zuvor als Site in den IIS eingerichtet werden und auf ein vorhandenes Verzeichnis zeigen. Darüber hinaus sind erst einmal keine weiteren Einstellungen im Webserver nötig (siehe Bild 4). Im Veröffentlichen-Dialog können Sie nun auf die Schaltfläche Weiter und dann auf Speichern klicken, um die Veröffentlichung in Gang zu setzen. Sobald das passiert ist, wird der Standardbrowser mit der hinterlegten URL gestartet.
Zu guter Letzt lohnt es sich noch, einen Blick in das Webverzeichnis zu werfen. Dadurch wird klar, dass das Projekt, wie es in Visual Studio sichtbar ist, nicht direkt im IIS-
Server als Site gemappt werden kann. Denn die Struktur ist tatsächlich eine völlig andere als in herkömmlichen ASP.NET-Projekten und im Projektverzeichnis. Wie in Bild 5 teilweise zu sehen ist, befinden sich im Webverzeichnis die DLL-Datei des Projekts sowie eine Menge Microsoft-DLL-Dateien. Die Veröffentlichung führt also dazu, dass alle benötigten Abhängigkeiten aus ASP.NET Core und .NET Core ebenso publiziert werden. Das Verzeichnis refs enthält außerdem die .NET-Core-Runtime; dadurch kann die ASP.NET-Core-Site auch dort installiert werden, wo kein .NET-Core-SDK installiert ist.
Server als Site gemappt werden kann. Denn die Struktur ist tatsächlich eine völlig andere als in herkömmlichen ASP.NET-Projekten und im Projektverzeichnis. Wie in Bild 5 teilweise zu sehen ist, befinden sich im Webverzeichnis die DLL-Datei des Projekts sowie eine Menge Microsoft-DLL-Dateien. Die Veröffentlichung führt also dazu, dass alle benötigten Abhängigkeiten aus ASP.NET Core und .NET Core ebenso publiziert werden. Das Verzeichnis refs enthält außerdem die .NET-Core-Runtime; dadurch kann die ASP.NET-Core-Site auch dort installiert werden, wo kein .NET-Core-SDK installiert ist.
Damit ist die Site mit dem IIS-Server als Reverse Proxy eingerichtet. Auch wenn es auf den ersten Blick nicht ersichtlich ist, läuft sie eigentlich auf Kestrel.
Hosting auf Azure
Sobald über das Azure-Portal eine Site erstellt und konfiguriert ist, ist dort bereits alles für das Hosting einer ASP.NET-Core-Applikation vorbereitet. ASP.NET Core ist für Azure optimiert und sollte dort auf Anhieb laufen. In Visual Studio ist dazu – wie im vorherigen Abschnitt beschrieben – der Dialog zum Veröffentlichen der Website aufzurufen. Nur wird diesmal Microsoft Azure App Service gewählt. Falls noch keine Web-App angelegt wurde, kann hier Neues Element erstellen gewählt werden, im anderen Fall wird Vorhandenes Element auswählen selektiert. In den Folgedialogen sind dann die Zugangsdaten für Azure einzutragen.Für den Fall, dass noch keine Web-App angelegt ist, wird ein Name festgelegt, eine Subscription eingetragen sowie eine Resource Group (Ressourcengruppe) und ein App Service Plan ausgewählt oder neu angelegt.Im anderen Fall werden eine vorhandene Subscription und eine bestehende Ressourcengruppe spezifiziert, um die bereits angelegte Website zu finden und auszuwählen.In beiden Fällen wird anschließend automatisch ein Veröffentlichungsprofil angelegt, über das die Anwendung dann bei Azure publiziert wird. Wird der Dialog beendet, startet die Auslieferung an die Azure-Website. Auch hier erfolgt nach dem erfolgreichen Vorgang der Aufruf der veröffentlichten Site im Webbrowser.Mit Nginx unter Linux
Unter Linux bietet sich Nginx als Reverse Proxy an. Die Webapplikation wird hierfür am besten direkt mit der .NET-Kommandozeile veröffentlicht:dotnet publish
Dieses Kommando erzeugt unterhalb des bin-Verzeichnisses im laufzeitspezifischen Ordner einen publish-Ordner. Dieser lässt sich auf einen Linux-Server kopieren.Wie Nginx zu konfigurieren ist, lässt sich der sehr ausführlichen Dokumentation entnehmen [4].
Docker
Eine weitere Variante, um eine ASP.NET-Core-Applikation zu hosten, ist ein Docker-Container; Visual Studio 2017 enthält die Tools dafür. Um das auszuprobieren, kann man die Azure-Containerdienste verwenden oder Docker for Windows aus dem Docker Store herunterladen und installieren [5].In einem neuen ASP.NET-Core-Projekt muss die Unterstützung für Docker aktiviert werden. Dazu klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt und wählen Hinzufügen | Docker-Unterstützung im Kontextmenü. Das führt dazu, dass die Projektmappe um einen neuen Ordner mit dem Namen docker-compose erweitert wird. Was aber noch viel wichtiger ist: Dem Projekt wird eine Datei mit dem Namen Dockerfile hinzugefügt.Diese Datei Dockerfile definiert das Basis-Image, das bereits für ASP.NET Core vorbereitet ist, und legt fest, wie die Applikation im Docker-Container laufen soll. Dockerfile kann so aussehen:FROM microsoft/aspnetcore:1.1
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "AspNetOnDocker.dll"]
Sobald dies eingestellt ist, lässt sich die Anwendung mit [F5] mit Docker starten. Visual Studio 2017 wird nun das Docker-Image bauen, was beim ersten Start etwas länger dauern kann, da das Basis-Image erst vom Docker-Hub geladen werden muss. Mit Visual Studio lässt sich die Applikation dann auch direkt in Docker debuggen. Man bedenke, dass der Container in einem Linux-Host innerhalb von Hyper-V läuft. Der Quellcode wird aber beim Debuggen mit Visual Studio über die Festplatte geteilt. So ist es möglich, Code anzupassen, ohne ein neues Docker-Image bauen zu müssen. Das ist aber nur ein zeitweiliges Hosting für das Debuggen der Applikation. Wird das Debugging beendet, so ist die Site nicht mehr erreichbar.Wie sieht es aber nun aus, wenn das Image permanent in einem Docker-Container laufen soll?Zuerst ist es notwendig, die Datei Dockerfile zu modifizieren; in den Dateieigenschaften in Visual Studio muss außerdem eingestellt werden, dass die Datei bei jedem Build mit ausgeliefert wird. Zeile 2 in der Beispieldatei (siehe oben) wird ersetzt durch:
ARG source=.
Zeile 5 wird ersetzt durch:
COPY $source .
Danach wechselt man am besten mit der Konsole in das Projektverzeichnis und führt die folgenden Befehle aus:
dotnet restore
dotnet publish
Da die kompilierte Version in das Image eingebaut werden soll, wechselt man mit der Konsole in das Unterverzeichnis, das die veröffentlichte Anwendung enthält:
bin\Debug\netcoreapp1.1\publish
Da die Dockerfile-Datei ebenfalls publiziert worden ist, kann folgender Befehl in diesem Verzeichnis ausgeführt werden, um das Docker-Image zu erzeugen:
docker build . -t aspnetondocker
Ist das Image erstellt, können Sie es mit dem Befehl docker image ls anzeigen und mit folgendem Kommando starten:
docker run -p 8080:80 aspnetondocker
Nun lässt sich die Site mit dem URL http://localhost:8080/ im Browser aufrufen. Der Befehl docker container ls listet die laufenden Container auf (Bild 6).
In einem sehr ausführlichen Blog-Beitrag beschreibt Scott Hanselman von Microsoft, wie eine ASP.NET-Core-Applikation in einem Docker-Container unter Linux und Windows-NanoServer gehostet werden kann [6].
Zusammenfassung
Sie sehen: Es gibt viele Möglichkeiten, eine ASP.NET-Core-Site bereitzustellen. Sehr wahrscheinlich werden die Varianten mit IIS, Nginx und Docker die häufigsten bleiben. Microsoft betont immer wieder, wie wichtig es ist, einen Reverse Proxy vor dem Kestrel-Server laufen zu lassen, um Sicherheit und Stabilität zu garantieren. IIS und Nginx sind hierbei die unterstützten Varianten. Die Konfiguration in den IIS ist denkbar einfach und unterscheidet sich nicht wirklich vom Einrichten herkömmlicher ASP.NET-Anwendungen. Nur ein Blick in die Datei Web.config zeigt den Unterschied.Fussnoten
- Libuv, https://github.com/libuv/libuv
- Introduction to Kestrel web server implementation in ASP.NET Core, http://www.dotnetpro.de/SL1708CoreHosting1
- Wikipedia: Reverse Proxy, http://www.dotnetpro.de/SL1708CoreHosting2
- Set up a hosting environment for ASP.NET Core on Linux with Nginx, and deploy to it,, http://www.dotnetpro.de/SL1708CoreHosting3
- Docker Community Edition for Windows, http://www.dotnetpro.de/SL1708CoreHosting4
- Scott Hanselman: Exploring ASP.NET Core with Docker in both Linux and Windows Containers, http://www.dotnetpro.de/SL1708CoreHosting5