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 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.

Screenshot showing Create ASP.NET Core Web App project.

Wählen Sie nicht Enable Docker Support (Docker-Unterstützung aktivieren) aus. Sie fügen die Docker-Unterstützung später im Prozess hinzu.

Screenshot of the Additional information screen when creating a web project. The option to Enable Docker Support is not selected.

Hinweis

In Visual Studio 2022 17.2 und höher können Sie stattdessen Azure Functions für dieses Projekt verwenden.

Screenshot showing Create ASP.NET Core Web App project.

Wählen Sie nicht Enable Docker Support (Docker-Unterstützung aktivieren) aus. Sie fügen die Docker-Unterstützung später im Prozess hinzu.

Screenshot of the Additional information screen when creating a web project. The option to Enable Docker Support is not selected.

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.

Screenshot of creating the Web API project.

  1. 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.

    Screenshot of creating the Web API project.

  2. Fügen Sie Unterstützung für Redis Cache hinzu. Fügen Sie das NuGet-Paket Microsoft.Extensions.Caching.StackExchangeRedis (nicht StackExchange.Redis) hinzu. Fügen Sie in Program.cs die folgenden Zeilen direkt vor var 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";
       });
    
  3. Fügen Sie Anweisungen in Program.cs für Microsoft.Extensions.Caching.Distributed und Microsoft.Extensions.Caching.StackExchangeRedis hinzu.

    using Microsoft.Extensions.Caching.Distributed;
    using Microsoft.Extensions.Caching.StackExchangeRedis;
    
  4. 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

  1. Öffnen Sie die Datei Index.cshtml.cs im WebFrontEnd-Projekt, und ersetzen Sie die OnGet-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.

  2. 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>
    
  3. (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

  1. Klicken Sie im WebFrontEnd-Projekt auf Hinzufügen > Unterstützung für Containerorchestrator. Daraufhin wird das Dialogfeld Docker-Supportoptionen geöffnet.

  2. Wählen Sie Docker Compose aus.

  3. Wählen Sie Ihr Zielbetriebssystem aus, z. B. Linux.

    Screenshot of choosing the Target OS.

    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.

    Screenshot of Solution Explorer with docker-compose project added.

    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.

  4. 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
    
  5. 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.

    Screenshot of docker-compose project properties.

    Hier sehen Sie, was beim Start (der Version .NET Core 2.x) angezeigt wird:

    Screenshot of running web app.

    Die Web-App für .NET 3.1 zeigt die Wetterdaten im JSON-Format an.

  6. 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.

    Screenshot of Debug Manage Compose Settings menu item.

    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.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    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.

  7. 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.

  1. Öffnen Sie die Datei Index.cshtml.cs im WebFrontEnd-Projekt, und ersetzen Sie die OnGet-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.

  2. 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

  1. Klicken Sie im WebFrontEnd-Projekt auf Hinzufügen > Unterstützung für Containerorchestrator. Daraufhin wird das Dialogfeld Docker-Supportoptionen geöffnet.

  2. Wählen Sie Docker Compose aus.

  3. Wählen Sie Ihr Zielbetriebssystem aus, z. B. Linux.

    Screenshot of choosing the Target OS.

    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.

    Screenshot of Solution Explorer with docker-compose project added.

    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.

  4. 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
    
  5. 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.

  6. 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.

    Screenshot of docker-compose project properties.

  7. Drücken Sie F5. Folgendes wird beim Start angezeigt:

    Screenshot of running web app.

  8. 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.

  9. 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.

    Screenshot showing viewing the Logs tab in the Containers window.

    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

  1. 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.

    Screenshot of Debug Manage Compose Settings menu item.

    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.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    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.

    Screenshot showing creating the Redis profile that starts the Redis service only.

    Erstellen Sie dann ein anderes Start My Services-Profil, das nicht Redis startet, sondern die anderen beiden Dienste.

    Screenshot showing creating the Services profile that starts the other services.

    (Optional) Erstellen Sie ein drittes Profil, Start All, um alles zu starten. Alternativ können Sie auch Ohne Debuggen starten auswählen.

  2. 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.

Weitere Informationen

Docker Compose
Containertools