Tutorial: Erstellen einer App mit mehreren Containern mit Docker Compose
In diesem Tutorial erfahren Sie, wie Sie mehrere Container verwalten und zwischen ihnen kommunizieren können, wenn Sie Containertools in Visual Studio verwenden. Für die Verwaltung mehrerer Container sind die Containerorchestrierung und ein Orchestrator wie Docker Compose oder Service Fabric erforderlich. Für diese Verfahren verwenden Sie Docker Compose. Docker Compose eignet sich bestens für das lokale Debuggen und Testen während des Entwicklungszyklus.
Das abgeschlossene Beispiel, das Sie in diesem Tutorial erstellen, finden Sie unter GitHub unter https://github.com/MicrosoftDocs/vs-tutorial-samples im Ordner docker/ComposeSample.
Voraussetzungen
- Docker Desktop
- Visual Studio 2019 mit installierten Workloads für Webentwicklung, Azure-Tools und/oder plattformübergreifende .NET-Entwicklung
- Docker Desktop
- Visual Studio 2022 mit installierten Workloads für Webentwicklung, Azure-Tools und/oder plattformübergreifende .NET-Entwicklung. Diese Installation enthält die .NET 8-Entwicklungstools.
Erstellen eines Webanwendungsprojekts
Erstellen Sie in Visual Studio ein Projekt vom Typ ASP.NET Core-Web-App mit dem Namen WebFrontEnd
, um eine Webanwendung mit Razor Pages zu erstellen.
Wählen Sie nicht Enable Docker Support (Docker-Unterstützung aktivieren) aus. Sie fügen die Docker-Unterstützung später im Prozess hinzu.
Hinweis
In Visual Studio 2022 17.2 und höher können Sie stattdessen Azure Functions für dieses Projekt verwenden.
Wählen Sie nicht Enable Docker Support (Docker-Unterstützung aktivieren) aus. Sie fügen die Docker-Unterstützung später im Prozess hinzu.
Erstellen eines Web-API-Projekts
Fügen Sie ein Projekt zur gleichen Projektmappe hinzu, und nennen Sie es MyWebAPI. Wählen Sie API als Projekttyp aus, und deaktivieren Sie das Kontrollkästchen Für HTTPS konfigurieren. Bei diesem Entwurf wird SSL nur für die Kommunikation mit dem Client verwendet und nicht für die Kommunikation zwischen Containern in derselben Webanwendung. Nur WebFrontEnd
erfordert HTTPS und der Code in den Beispielen geht davon aus, dass Sie dieses Kontrollkästchen deaktiviert haben. Im Allgemeinen werden die von Visual Studio verwendeten .NET-Entwicklerzertifikate nur für externe Anforderungen an Container unterstützt, nicht für Anforderungen zwischen Containern.
Fügen Sie ein Projekt zur gleichen Projektmappe hinzu, und nennen Sie es WebAPI. Wählen Sie API als Projekttyp aus, und deaktivieren Sie das Kontrollkästchen Für HTTPS konfigurieren. Bei diesem Entwurf wird SSL nur für die Kommunikation mit dem Client verwendet und nicht für die Kommunikation zwischen Containern in derselben Webanwendung. Nur
WebFrontEnd
erfordert HTTPS und der Code in den Beispielen geht davon aus, dass Sie dieses Kontrollkästchen deaktiviert haben. Im Allgemeinen werden die von Visual Studio verwendeten .NET-Entwicklerzertifikate nur für externe Anforderungen an Container unterstützt, nicht für Anforderungen zwischen Containern.Fügen Sie Unterstützung für Redis Cache hinzu. Fügen Sie das NuGet-Paket
Microsoft.Extensions.Caching.StackExchangeRedis
(nichtStackExchange.Redis
) hinzu. Fügen Sie in Program.cs die folgenden Zeilen direkt vorvar app = builder.Build()
hinzu:builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "redis:6379"; // redis is the container name of the redis service. 6379 is the default port options.InstanceName = "SampleInstance"; });
Fügen Sie Anweisungen in Program.cs für
Microsoft.Extensions.Caching.Distributed
undMicrosoft.Extensions.Caching.StackExchangeRedis
hinzu.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;
Löschen Sie im Web-API-Projekt die vorhandenen Dateien WeatherForecast.cs und Controller/WeatherForecastController.cs, und fügen Sie eine Datei unter Controller, CounterController.cs, mit den folgenden Inhalten hinzu:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using StackExchange.Redis; namespace WebApi.Controllers { [ApiController] [Route("[controller]")] public class CounterController : ControllerBase { private readonly ILogger<CounterController> _logger; private readonly IDistributedCache _cache; public CounterController(ILogger<CounterController> logger, IDistributedCache cache) { _logger = logger; _cache = cache; } [HttpGet(Name = "GetCounter")] public string Get() { string key = "Counter"; string? result = null; try { var counterStr = _cache.GetString(key); if (int.TryParse(counterStr, out int counter)) { counter++; } else { counter = 0; } result = counter.ToString(); _cache.SetString(key, result); } catch(RedisConnectionException) { result = "Redis cache is not found."; } return result; } } }
Der Dienst erhöht jedes Mal einen Zähler, wenn ein Zugriff auf die Seite erfolgt, und speichert diesen Zähler dann im Redis-Cache.
Hinzufügen von Code zum Aufrufen der Web-API
Öffnen Sie die Datei Index.cshtml.cs im
WebFrontEnd
-Projekt, und ersetzen Sie dieOnGet
-Methode durch den folgenden Code.public async Task OnGet() { ViewData["Message"] = "Hello from webfrontend"; using (var client = new System.Net.Http.HttpClient()) { // Call *mywebapi*, and display its response in the page var request = new System.Net.Http.HttpRequestMessage(); request.RequestUri = new Uri("http://mywebapi/WeatherForecast"); // request.RequestUri = new Uri("http://mywebapi/api/values/1"); // For ASP.NET 2.x, comment out previous line and uncomment this line. var response = await client.SendAsync(request); ViewData["Message"] += " and " + await response.Content.ReadAsStringAsync(); } }
Hinweis
Für tatsächlich verwendeten Code sollte
HttpClient
nicht nach jeder Anforderung gelöscht werden. Best Practices finden Sie unter Verwenden von HttpClientFactory zur Implementierung robuster HTTP-Anforderungen.Fügen Sie der Datei Index.cshtml eine Zeile hinzu, um
ViewData["Message"]
so anzuzeigen, dass die Datei wie der folgende Code aussieht:@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <p>@ViewData["Message"]</p> </div>
(Nur ASP.NET 2.x) Fügen Sie nun im Web-API-Projekt Code zum Controller „Values“ hinzu, um die von der API zurückgegebene Nachricht für den Aufruf anzupassen, den Sie über webfrontend hinzugefügt haben.
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "webapi (with value " + id + ")"; }
Hinweis
In .NET Core 3.1 und höher können Sie die bereitgestellte WeatherForecast-API anstelle dieses zusätzlichen Codes verwenden. Sie müssen jedoch den Aufruf an UseHttpsRedirection im Web-API-Projekt auskommentieren, da der Code für den Aufruf HTTP und nicht HTTPS verwendet.
//app.UseHttpsRedirection();
Hinzufügen der Docker Compose-Unterstützung
Klicken Sie im
WebFrontEnd
-Projekt auf Hinzufügen > Unterstützung für Containerorchestrator. Daraufhin wird das Dialogfeld Docker-Supportoptionen geöffnet.Wählen Sie Docker Compose aus.
Wählen Sie Ihr Zielbetriebssystem aus, z. B. Linux.
Visual Studio erstellt eine docker-compose.yml- und eine .dockerignore-Datei im Knoten docker-compose der Projektmappe. Dieses Projekt wird in fetter Schrift aufgeführt, was angibt, dass es sich um das Startprojekt handelt.
Die Datei docker-compose.yml wird wie folgt angezeigt:
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Die in der ersten Zeile angegebene
version
ist die Docker Compose-Dateiversion. Normalerweise sollten Sie die Version nicht ändern, da sie von den Tools zur Interpretation der Datei benötigt wird.Die .dockerignore-Datei enthält Dateitypen und Erweiterungen, die Docker nicht im Container enthalten soll. Diese Daten stehen in der Regel in Verbindung mit der Entwicklungsumgebung und der Quellcodeverwaltung, nicht mit dem Teil der App bzw. des Diensts, den Sie entwickeln.
Details zu den ausgeführten Befehlen finden Sie im Abschnitt Containertools des Ausgabebereichs. Dort können Sie sehen, wie das Befehlszeilentool „docker-compose“ zum Konfigurieren und Erstellen der Runtimecontainer verwendet wird.
Klicken Sie im Web-API-Projekt erneut mit der rechten Maustaste auf den Projektknoten, und wählen Sie dann Hinzufügen>Unterstützung für Containerorchestrator aus. Wählen Sie Docker Compose aus, und wählen Sie dann dasselbe Zielbetriebssystem aus wie zuvor.
Hinweis
In diesem Schritt bietet Visual Studio an, eine Dockerfile zu erstellen. Wenn Sie dies in einem Projekt durchführen, das bereits über Docker-Unterstützung verfügt, werden Sie gefragt, ob Sie die vorhandene Dockerfile überschreiben möchten. Wenn Sie Änderungen an Ihrer Dockerfile vorgenommen haben, die Sie beibehalten möchten, wählen Sie „Nein“ aus.
Visual Studio nimmt einige Änderungen an Ihrer Docker Compose-YML-Datei vor. Nun sind beide Dienste enthalten.
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Das erste Projekt, dem Sie die Containerorchestrierung hinzufügen, ist so eingerichtet, dass es gestartet wird, wenn Sie die Ausführung oder das Debuggen starten. Sie können die Startaktion in den Projekteigenschaften des Projekts „docker-compose“ konfigurieren. Klicken Sie mit der rechten Maustaste auf den Projektknoten „docker-compose“, um das Kontextmenü zu öffnen, und wählen Sie dann Eigenschaften aus, oder drücken Sie ALT + ENTER. Im folgenden Screenshot werden die Eigenschaften gezeigt, die Sie für die Projektmappe verwenden sollten. Sie können beispielsweise die geladene Seite ändern, indem Sie die Eigenschaft Dienst-URL anpassen.
Hier sehen Sie, was beim Start (der Version .NET Core 2.x) angezeigt wird:
Die Web-App für .NET 3.1 zeigt die Wetterdaten im JSON-Format an.
Angenommen, Sie möchten nur den Debugger an WebFrontEnd anfügen, nicht das Web-API-Projekt. In der Menüleiste können Sie die Dropdownliste neben der Startschaltfläche verwenden, um ein Menü mit Debugoptionen zu öffnen. Wählen Sie Docker Compose-Starteinstellungen verwalten aus.
Das Dialogfeld Docker Compose-Starteinstellungen verwalten wird angezeigt. Mithilfe dieses Dialogfelds können Sie steuern, welche Teilmenge der Dienste während einer Debugsitzung gestartet und welche mit oder ohne angefügten Debugger gestartet wird. Zudem können Sie den Startdienst und die URL angeben. Weitere Informationen finden Sie unter Starten einer Teilmenge der Compose-Dienste.
Wählen Sie Neu aus, um ein neues Profil zu erstellen, und nennen Sie es
Debug WebFrontEnd only
. Legen Sie das Web-API-Projekt anschließend auf Ohne Debuggen starten fest, lassen Sie das WebFrontEnd-Projekt so festgelegt, dass es mit Debuggen gestartet wird, und klicken Sie auf Speichern.Die neue Konfiguration wird als Standard für das nächste Drücken von F5.
Drücken Sie F5, um zu bestätigen, dass dies wie erwartet funktioniert.
Herzlichen Glückwunsch, Sie führen eine Docker Compose-Anwendung mit einem benutzerdefinierten Docker Compose-Profil aus.
Öffnen Sie die Datei Index.cshtml.cs im
WebFrontEnd
-Projekt, und ersetzen Sie dieOnGet
-Methode durch den folgenden Code.public async Task OnGet() { using (var client = new System.Net.Http.HttpClient()) { // Call *mywebapi*, and display its response in the page var request = new System.Net.Http.HttpRequestMessage(); // webapi is the container name request.RequestUri = new Uri("http://webapi/Counter"); var response = await client.SendAsync(request); string counter = await response.Content.ReadAsStringAsync(); ViewData["Message"] = $"Counter value from cache :{counter}"; } }
Hinweis
Für tatsächlich verwendeten Code sollte
HttpClient
nicht nach jeder Anforderung gelöscht werden. Best Practices finden Sie unter Verwenden von HttpClientFactory zur Implementierung robuster HTTP-Anforderungen.Fügen Sie der Datei Index.cshtml eine Zeile hinzu, um
ViewData["Message"]
so anzuzeigen, dass die Datei wie der folgende Code aussieht:@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <p>@ViewData["Message"]</p> </div>
Dieser Code zeigt den Wert des vom Web-API-Projekt zurückgegebenen Zählers an.
Hinzufügen der Docker Compose-Unterstützung
Klicken Sie im
WebFrontEnd
-Projekt auf Hinzufügen > Unterstützung für Containerorchestrator. Daraufhin wird das Dialogfeld Docker-Supportoptionen geöffnet.Wählen Sie Docker Compose aus.
Wählen Sie Ihr Zielbetriebssystem aus, z. B. Linux.
Visual Studio erstellt eine docker-compose.yml- und eine .dockerignore-Datei im Knoten docker-compose der Projektmappe. Dieses Projekt wird in fetter Schrift aufgeführt, was angibt, dass es sich um das Startprojekt handelt.
Die Datei docker-compose.yml wird wie folgt angezeigt:
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Die in der ersten Zeile angegebene
version
ist die Docker Compose-Dateiversion. Normalerweise sollten Sie die Version nicht ändern, da sie von den Tools zur Interpretation der Datei benötigt wird.Die .dockerignore-Datei enthält Dateitypen und Erweiterungen, die Docker nicht im Container enthalten soll. Diese Daten stehen in der Regel in Verbindung mit der Entwicklungsumgebung und der Quellcodeverwaltung, nicht mit dem Teil der App bzw. des Diensts, den Sie entwickeln.
Details zu den ausgeführten Befehlen finden Sie im Abschnitt Containertools des Ausgabebereichs. Dort können Sie sehen, wie das Befehlszeilentool „docker-compose“ zum Konfigurieren und Erstellen der Runtimecontainer verwendet wird.
Klicken Sie im Web-API-Projekt erneut mit der rechten Maustaste auf den Projektknoten, und wählen Sie dann Hinzufügen>Unterstützung für Containerorchestrator aus. Wählen Sie Docker Compose aus, und wählen Sie dann dasselbe Zielbetriebssystem aus wie zuvor.
Hinweis
In diesem Schritt bietet Visual Studio an, eine Dockerfile zu erstellen. Wenn Sie dies in einem Projekt durchführen, das bereits über Docker-Unterstützung verfügt, werden Sie gefragt, ob Sie die vorhandene Dockerfile überschreiben möchten. Wenn Sie Änderungen an Ihrer Dockerfile vorgenommen haben, die Sie beibehalten möchten, wählen Sie „Nein“ aus.
Visual Studio nimmt einige Änderungen an Ihrer Docker Compose-YML-Datei vor. Nun sind beide Dienste enthalten.
version: '3.4' services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Fügen Sie den Redis-Cache zur
docker.compose.yml
-Datei hinzu:redis: image: redis
Stellen Sie sicher, dass sich der Einzug auf derselben Ebene befindet wie die anderen beiden Dienste.
Das erste Projekt, dem Sie die Containerorchestrierung hinzufügen, ist so eingerichtet, dass es gestartet wird, wenn Sie die Ausführung oder das Debuggen starten. Sie können die Startaktion in den Projekteigenschaften des Projekts „docker-compose“ konfigurieren. Klicken Sie mit der rechten Maustaste auf den Projektknoten „docker-compose“, um das Kontextmenü zu öffnen, und wählen Sie dann Eigenschaften aus, oder drücken Sie ALT+EINGABE. Sie können beispielsweise die geladene Seite ändern, indem Sie die Eigenschaft Dienst-URL anpassen.
Drücken Sie F5. Folgendes wird beim Start angezeigt:
Sie können die Container mithilfe des Fensters Container überwachen. Wenn das Fenster nicht angezeigt wird, verwenden Sie das Suchfeld, drücken Sie STRG+K, STRG+O, oder drücken Sie STRG+Q. Suchen Sie unter Featuresuche nach
containers
, und wählen Sie in der Liste Ansicht>Weitere Fenster>Container aus.Erweitern Sie den Knoten Lösungscontainer, und wählen Sie den Knoten für Ihr Docker Compose-Projekt aus, um kombinierte Protokolle auf der Registerkarte Protokolle dieses Fensters anzuzeigen.
Sie können auch den Knoten für einen einzelnen Container auswählen, um Protokolle, Umgebungsvariablen, das Dateisystem und andere Details anzuzeigen.
Einrichten von Startprofilen
Diese Lösung verfügt über eine Redis Cache-Instanz, es ist jedoch nicht effizient, den Redis-Cachecontainer jedes Mal neu zu erstellen, wenn Sie eine Debugsitzung starten. Um diese Situation zu vermeiden, können Sie ein paar Startprofile einrichten. Erstellen Sie ein Profil, um den Redis-Cache zu starten. Erstellen Sie ein zweites Profil, um die anderen Dienste zu starten. Das zweite Profil kann den Redis-Cachecontainer verwenden, der bereits ausgeführt wird. Über die Menüleiste können Sie die Dropdownliste neben der Startschaltfläche verwenden, um ein Menü mit Debugoptionen zu öffnen. Wählen Sie Verwalten der Docker Compose-Starteinstellungen aus.
Das Dialogfeld Docker Compose-Starteinstellungen verwalten wird angezeigt. Mithilfe dieses Dialogfelds können Sie steuern, welche Teilmenge der Dienste während einer Debugsitzung gestartet und welche mit oder ohne angefügten Debugger gestartet wird. Zudem können Sie den Startdienst und die URL angeben. Weitere Informationen finden Sie unter Starten einer Teilmenge der Compose-Dienste.
Wählen Sie Neu aus, um ein neues Profil zu erstellen, und nennen Sie es
Start Redis
. Legen Sie dann den Redis-Container auf Ohne Debuggen starten und den anderen Satz auf Nicht starten fest, und wählen Sie Speichern aus.Erstellen Sie dann ein anderes
Start My Services
-Profil, das nicht Redis startet, sondern die anderen beiden Dienste.(Optional) Erstellen Sie ein drittes Profil,
Start All
, um alles zu starten. Alternativ können Sie auch Ohne Debuggen starten auswählen.Wählen Sie Redis starten aus der Dropdownliste in der Symbolleiste von Visual Studio aus, und drücken Sie F5. Der Redis-Container wird erstellt und gestartet. Sie können das Container-Fenster verwenden, um anzuzeigen, dass er ausgeführt wird. Wählen Sie als Nächstes Meine Dienste starten aus der Dropdownliste aus, und drücken Sie F5, um sie zu starten. Jetzt können Sie den Redis-Cachecontainer in vielen nachfolgenden Debugsitzungen ausführen. Jedes Mal, wenn Sie Meine Dienste starten verwenden, verwenden diese Dienste den gleichen Redis-Cachecontainer.
Herzlichen Glückwunsch, Sie führen eine Docker Compose-Anwendung mit einem benutzerdefinierten Docker Compose-Profil aus.
Nächste Schritte
Sehen Sie sich die Optionen zum Bereitstellen Ihrer Container in Azure an.