Eigene App in Container verpacken
Wenn man eine Zeit lang die Container für sich arbeiten lässt und diese nutzt, kommt irgendwann der Gedanke, auch eigene Applikation in einen Container zu verpacken und auszuliefern. Das wollen wir am Beispiel unser Blazor Beispielprojektes ein Mal durchspielen.
Um ein Image zu erstellen, benötigen wir eine Bauanleitung. Diese wird in Form eines sogenannten Docker-Files definiert. Die Datei beschreibt Schritt für Schritt, was wir am Basissystem machen müssen, um unsere Applikation zu veröffentlichen. Dazu kommen noch einige Konfigurationsangaben, wie Port oder verfügbare Umgebungsvariablen.
Anpassbarkeit des Images
Abschnitt betitelt „Anpassbarkeit des Images“Als erstes müssen wir überlegen, welche Möglichkeiten wir dem “Nutzer” des Images zur Verfügung stellen müssen (und wollen). Da es sich um eine Web-Anwendung handelt, sollten wir mindestens den Port für den Web-Server freigeben, so dass die Anwendung auch von Außen ansprechbar ist.
Da unsere Anwendung eine Datenbankverbindung benötigt, sollten wir erlauben diese zu konfigurieren. Hier könnten wir entweder direkt den kompletten “Connection String” empfangen, oder diesen in Teilen konfigurierbar machen.
Auswahl des Basis-Images
Abschnitt betitelt „Auswahl des Basis-Images“Unsere Anwendung basiert auf der .Net Laufzeitumgebung und benötigt das ASP .Net Core Framework. Im ersten Schritt wollen wir auch, dass die App in dem Container (einfachheitshalber) direkt gebaut wird. Die Applikation nutzt .Net 10 als Version der Laufzeitumgebung. Eine Liste mit verfügbaren (offiziellen) Repositories für .Net finden wir direkt bei Microsoft.
Für unsere Zwecke werden wir das “sdk” Basis-Image nutzen.
Dockerfile
Abschnitt betitelt „Dockerfile“Die Datei Dockerfile ist eine einfache Textdatei, die einem Schema folgt. Jede neue Zeile (Anweisung) erzeugt dabei eine neue Schicht im Dateisystem des fertigen Images. Die Datei fängt immer mit einer FROM Anweisung, gefolgt von dem Basis-Image, auf dem wir unsere Applikation aufbauen.
# Basis-Image .Net 10 SDKFROM mcr.microsoft.com/dotnet/sdk:10.0Kopieren des Projektes
Abschnitt betitelt „Kopieren des Projektes“Im nächsten Schritt (nächste Zeile) legen wir das Verzeichnis (WORKDIR) an, in dem wir “arbeiten” wollen. Und kopieren (COPY) den aktuellen Inhalt des Projektes in dieses Verzeichnis.
FROM mcr.microsoft.com/dotnet/sdk:10.0# Verzeichnis für die AppWORKDIR /build# Kopiere das Projekt in das ArbeitsverzeichnisCOPY . ./Bauen des Projektes
Abschnitt betitelt „Bauen des Projektes“Nun folgen die Standardschritte von dotnet um eine Applikation für die Veröffentlichung zu bauen. Dieser Schritt ist spezifisch für die jeweilige Sprache / Framework (und unabhängig von Docker / Containern). Die Befehle werden durch die RUN Anweisung ausgeführt. Jede Zeile erzeugt, wie erwähnt, eine neue Schicht im Dateisystem.
FROM mcr.microsoft.com/dotnet/sdk:10.0...# Wiederherstellen der AbhängigkeitenRUN dotnet resore# Veröffentlichen der App in das Verzeichnis /appRUN dotnet publish BlazorWebAppMovies.csproj -c Release -o /appKonfiguration des Ports und Datenbankverbindung
Abschnitt betitelt „Konfiguration des Ports und Datenbankverbindung“Da wir eine Web-Anwendung haben, die eine Datenbank benötigt, sollen wir diese parametrisieren. Für das Arbeiten einer Web-Anwendung im Container ist es wichtig, dass wir ein Port zur Verfügung stellen, über den die Applikation erreichbar ist. In dem SDK Package ist das Port für Webanwendungen auf 8080 gesetzt (kann über die Umgebungsvariable ASPNETCORE_HTTP_PORTS angepasst werden).

Der Port wird über die Anweisung EXPOSE angegeben und kann neben dem Port selbst auch dar Protokoll enthalten.
Unsere Applikation ist auch von einer Datenbank abhängig. Wir müssen den “Connection String” mit übergeben, damit der Container sich mit der Datenbank verbinden kann. In .Net werden die Einstellungen in appsettings.json Datei (JSON Format) gespeichert. Will man diese Einstellungen mit Umgebungsvariablen überschreiben, werden die Verschachtlungen über ein __ (doppeltes Unterstrich) abgebildet. Aus aktuell { "ConnectionStrings": { "BlazorWebAppMoviesContext": "" } } wird so ConnectionStrings__BlazorWebAppMoviesContext. Da Umgebungsvariablen oft in Großbuchstaben geschrieben werden (und für .Net Konfigurationen es irrelevant ist), werden wir es als CONNECTIONSTRINGS__BLAZORWEBAPPMOVIESCONTEXT schreiben.
Die Umgebungsvariablen werden in Dockerfile mit der Anweisung ENV definiert. Schlüssel und Wert werden über = getrennt.
FROM mcr.microsoft.com/dotnet/sdk:10.0...# Neues ArbeitsverzeichnisWORKDIR /app# Datenbank Connection stringENV CONNECTIONSTRINGS__BLAZORWEBAPPMOVIESCONTEXT=""# Port für WebserverEXPOSE 8080Starten der Anwendung
Abschnitt betitelt „Starten der Anwendung“Der letzte Schritt ist nun die Anweisung, um die Anwendung in dem Container zu startet. Da wir die Applikation nicht manuell innerhalb des Containers starten wollen, sollte dies direkt beim “Instanziieren” des Containers geschehen.
Die Anwendung selbst wird über die ENTRYPOINT Anweisung ausgeführt. Die Anweisung nimmt eine Liste an Parametern entgegen. Die Applikationen in .Net startet man mit dem dotnet Befehl und dem Applikationsnamen (entspricht dem Projektnamen).
FROM mcr.microsoft.com/dotnet/sdk:10.0...# Start der .Net AnwendungENTRYPOINT ["dotnet", "BlazorWebAppMovies.dll"]Image bauen
Abschnitt betitelt „Image bauen“Im letzten Schritt können wir nun die “Bauanleitung” dazu nutzen unser erstes Image mit unserer Anwendung zu bauen. Dazu dient der Befehl docker build.
docker build -t blazor-movies:from-sdk .-t: Tag des Images, also der Image-Name + Version. In unserem Fall vergeben wir den Namenblazor-movies. Da wir einige Images bauen werden und diese miteinander vergleichen möchten, vergeben wir eine sprechenden Versionsnamen. Aktuelle Buildanleitung basiert auf dem SDK-Image. Der Versionsname ist bei uns deshalbfrom-sdk..: Das.hinter dem Tab bestimmt den Build-Context (Pfad). Der Build-Context steht beim Bauen zur Verfügung (wie bei uns der Quellcode der Anwendung)..bedeutet dabei, der aktuelle Ordner.
Finale Version
Abschnitt betitelt „Finale Version“FROM mcr.microsoft.com/dotnet/sdk:10.0# Verzeichnis für die AppWORKDIR /build# Kopiere das Projekt in das ArbeitsverzeichnisCOPY . ./# Wiederherstellen der AbhängigkeitenRUN dotnet restore# Veröffentlichen der App in das Verzeichnis /appRUN dotnet publish BlazorWebAppMovies.csproj -c Release -o /app# Arbeitsverzeichnis für AusführungWORKDIR /app# Datenbank Connection stringENV CONNECTIONSTRINGS__BLAZORWEBAPPMOVIESCONTEXT=""# Port für WebserverEXPOSE 8080# Start der .Net AnwendungENTRYPOINT ["dotnet", "BlazorWebAppMovies.dll"]