Zelfstudie: Een app met meerdere containers maken met Docker Compose
In deze zelfstudie leert u hoe u meer dan één container beheert en ertussen communiceert wanneer u Container Tools in Visual Studio gebruikt. Voor het beheren van meerdere containers is containerindeling vereist. Hiervoor is een orchestrator vereist, zoals Docker Compose of Service Fabric. Voor deze procedures gebruikt u Docker Compose. Docker Compose is ideaal voor lokale foutopsporing en -tests in de loop van de ontwikkelingscyclus.
Het voltooide voorbeeld dat u in deze zelfstudie maakt, vindt u op GitHub op https://github.com/MicrosoftDocs/vs-tutorial-samples
in de map docker/ComposeSample-.
Voorwaarden
- Docker Desktop
- Visual Studio 2019 met de Web Development, Azure Tools workload en/of .NET-platformoverschrijdende ontwikkeling workload geïnstalleerd
- Docker Desktop
- Visual Studio 2022 met de Web Development, Azure Tools workload en/of platformoverschrijdende .NET-ontwikkeling workload geïnstalleerd. Deze installatie bevat de ontwikkelhulpprogramma's voor .NET 8.
Een webtoepassingsproject maken
Maak in Visual Studio een ASP.NET Core Web App-project met de naam WebFrontEnd
om een webtoepassing te maken met Razor-pagina's.
Selecteer niet Docker-ondersteuning inschakelen. Later in het proces voegt u Docker-ondersteuning toe.
Selecteer niet Docker-ondersteuning inschakelen. Later in het proces voegt u Docker-ondersteuning toe.
Een web-API-project maken
Voeg een project toe aan dezelfde oplossing en noem het MyWebAPI-. Selecteer API- als projecttype en schakel het selectievakje voor Configureren voor HTTPS-uit. In dit ontwerp gebruiken we alleen SSL voor communicatie met de client, niet voor communicatie tussen containers in dezelfde webtoepassing. Alleen WebFrontEnd
heeft HTTPS nodig en de code in de voorbeelden gaat ervan uit dat u dat selectievakje hebt uitgeschakeld. Over het algemeen worden de .NET-ontwikkelaarscertificaten die door Visual Studio worden gebruikt, alleen ondersteund voor aanvragen van externe naar containers, niet voor container-naar-containeraanvragen.
Voeg een project toe aan dezelfde oplossing en noem het MyWebAPI-. Selecteer API- als projecttype en schakel het selectievakje voor Configureren voor HTTPS-uit.
Notitie
In dit ontwerp gebruiken we alleen HTTPS voor communicatie met de client, niet voor communicatie tussen containers in dezelfde webtoepassing. Alleen
WebFrontEnd
heeft HTTPS nodig en de code in de voorbeelden gaat ervan uit dat u dat selectievakje hebt uitgeschakeld. Over het algemeen worden de .NET-ontwikkelaarscertificaten die door Visual Studio worden gebruikt, alleen ondersteund voor aanvragen van externe naar containers, niet voor container-naar-containeraanvragen.Voeg ondersteuning toe voor Azure Cache voor Redis. Voeg het NuGet-pakket toe
Microsoft.Extensions.Caching.StackExchangeRedis
(nietStackExchange.Redis
). Voeg in Program.csde volgende regels toe, vlak voorvar app = builder.Build()
: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"; });
Gebruiksrichtlijnen toevoegen in
Program.cs
voorMicrosoft.Extensions.Caching.Distributed
enMicrosoft.Extensions.Caching.StackExchangeRedis
.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;
Verwijder in het web-API-project de bestaande
WeatherForecast.cs
en Controllers/WeatherForecastController.csen voeg een bestand toe onder Controllers, CounterController.cs, met de volgende inhoud: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; } } }
De service incrementeert een teller telkens wanneer de pagina wordt geopend en slaat de teller op in de cache.
Code toevoegen om de web-API aan te roepen
Open in het
WebFrontEnd
project het Index.cshtml.cs-bestand en vervang deOnGet
methode door de volgende 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(); } }
Notitie
In echte code moet u na elke aanvraag niet
HttpClient
verwijderen. Voor beste praktijken, zie Gebruik HttpClientFactory om veerkrachtige HTTP-aanvragen te implementeren.Voeg in het bestand
Index.cshtml
een regel toe omViewData["Message"]
weer te geven, zodat het bestand eruitziet als de volgende code:@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>
(alleen ASP.NET 2.x) Voeg nu in het web-API-project code toe aan de waardencontroller om het bericht dat door de API wordt geretourneerd, aan te passen voor de aanroep die u hebt toegevoegd vanuit webfrontend-.
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "webapi (with value " + id + ")"; }
Notitie
In .NET Core 3.1 en hoger kunt u de meegeleverde WeatherForecast-API gebruiken in plaats van deze extra code. U moet echter de aanroep naar UseHttpsRedirection in het Web-API-project uitcommentariëren, omdat de code gebruikmaakt van HTTP om de aanroep te maken in plaats van HTTPS.
//app.UseHttpsRedirection();
Ondersteuning voor Docker Compose toevoegen
In het
WebFrontEnd
-project, kies Toevoegen van > Container Orchestrator-ondersteuning. Het dialoogvenster Docker-ondersteuningsopties wordt weergegeven.Kies Docker Compose-.
Kies je doelbesturingssysteem, bijvoorbeeld Linux.
Visual Studio maakt een docker-compose.yml-bestand en een
.dockerignore
-bestand in het docker compose-knooppunt in de oplossing, en dat project wordt weergegeven in een vetgedrukt lettertype, waarin wordt aangegeven dat het het opstartproject is.De docker-compose.yml wordt als volgt weergegeven:
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
De
version
die in de eerste regel is opgegeven, is de Docker Compose-bestandsversie. Normaal gesproken moet u deze niet wijzigen, omdat het wordt gebruikt door de hulpprogramma's om te begrijpen hoe het bestand moet worden geïnterpreteerd.Het bestand
.dockerignore
bevat bestandstypen en extensies die u niet wilt opnemen in Docker in de container. Deze bestanden zijn over het algemeen gekoppeld aan de ontwikkelomgeving en broncodebeheer, en maken geen deel uit van de app of service die u ontwikkelt.Bekijk de sectie Container Tools van het uitvoervenster voor meer informatie over de opdrachten die worden uitgevoerd. U kunt zien dat het opdrachtregelprogramma
docker-compose
wordt gebruikt om runtimecontainers te configureren en te maken.Klik in het web-API-project opnieuw met de rechtermuisknop op het projectknooppunt en kies >Container Orchestrator-ondersteuning toevoegen. Kies Docker Compose-en selecteer vervolgens hetzelfde doel besturingssysteem.
Notitie
In deze stap biedt Visual Studio aan om een Dockerfile te maken. Als u dit doet op een project dat al docker-ondersteuning heeft, wordt u gevraagd of u het bestaande Dockerfile wilt overschrijven. Als u wijzigingen hebt aangebracht in uw Dockerfile die u wilt behouden, kiest u nee.
Visual Studio brengt enkele wijzigingen aan in uw Docker Compose YML-bestand. Beide services zijn nu inbegrepen.
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Het eerste project waaraan u containerindeling toevoegt, wordt ingesteld om te worden gestart bij het uitvoeren of opsporen van fouten. U kunt de startactie configureren in de Projecteigenschappen voor het Docker Compose-project. Klik in het projectknooppunt Docker Compose met de rechtermuisknop om het contextmenu te openen en kies vervolgens Eigenschappenof gebruik Alt+Enter. In de volgende schermopname ziet u de gewenste eigenschappen voor de oplossing die hier wordt gebruikt. U kunt bijvoorbeeld de pagina wijzigen die wordt geladen door de eigenschap Service-URL aan te passen.
Dit is wat u ziet wanneer deze wordt gestart (de .NET Core 2.x-versie):
De web-app voor .NET 3.1 toont de weergegevens in JSON-indeling.
Stel dat u alleen geïnteresseerd bent in het foutopsporingsprogramma dat is gekoppeld aan WebFrontEnd, niet het web-API-project. In de menubalk kunt u de vervolgkeuzelijst naast de startknop gebruiken om een menu met opties voor foutopsporing weer te geven; kies Startinstellingen voor Docker Compose beheren.
Het dialoogvenster Instellingen voor het starten van Docker Compose beheren wordt weergegeven. Met dit dialoogvenster kunt u bepalen welke subset van services wordt gestart tijdens een foutopsporingssessie, die wordt gestart met of zonder het foutopsporingsprogramma, en de startservice en URL. Zie Een subset van Compose-services starten.
Kies Nieuwe om een nieuw profiel te maken en geef het
Debug WebFrontEnd only
een naam. Stel vervolgens het web-API-project in op Starten zonder foutopsporing, laat het WebFrontEnd-project ingesteld om te beginnen met foutopsporing en kies Opslaan.De nieuwe configuratie wordt gekozen als de standaardinstelling voor de volgende F5.
Druk op F5- om te bevestigen dat deze werkt zoals verwacht.
Gefeliciteerd, u voert een Docker Compose-toepassing uit met een aangepast Docker Compose-profiel.
Open in het
WebFrontEnd
project het Index.cshtml.cs-bestand en vervang deOnGet
methode door de volgende code.public async Task OnGet() { // Call *mywebapi*, and display its response in the page using (var client = new System.Net.Http.HttpClient()) { var request = new System.Net.Http.HttpRequestMessage(); // A delay is a quick and dirty way to work around the fact that // the mywebapi service might not be immediately ready on startup. // See the text for some ideas on how you can improve this. // Uncomment if not using healthcheck (Visual Studio 17.13 or later) // await System.Threading.Tasks.Task.Delay(10000); // mywebapi is the service name, as listed in docker-compose.yml. // Docker Compose creates a default network with the services // listed in docker-compose.yml exposed as host names. // The port 8080 is exposed in the WebAPI Dockerfile. // If your WebAPI is exposed on port 80 (the default for HTTP, used // with earlier versions of the generated Dockerfile), change // or delete the port number here. request.RequestUri = new Uri("http://mywebapi:8080/Counter"); var response = await client.SendAsync(request); string counter = await response.Content.ReadAsStringAsync(); ViewData["Message"] = $"Counter value from cache :{counter}"; } }
Notitie
In echte code moet u na elke aanvraag niet
HttpClient
verwijderen. Voor beste praktijken, zie Gebruik HttpClientFactory om veerkrachtige HTTP-aanvragen te implementeren.De URI verwijst naar een servicenaam die is gedefinieerd in het docker-compose.yml-bestand. Docker Compose stelt een standaardnetwerk in voor communicatie tussen containers met behulp van de vermelde servicenamen als hosts.
De code die hier wordt weergegeven, werkt met .NET 8 en hoger, waarmee een gebruikersaccount in het Dockerfile zonder beheerdersbevoegdheden wordt ingesteld en poort 8080 beschikbaar wordt gemaakt omdat de STANDAARD-HTTP-poort 80 niet toegankelijk is zonder verhoogde bevoegdheden.
Voeg in het bestand
Index.cshtml
een regel toe omViewData["Message"]
weer te geven, zodat het bestand eruitziet als de volgende code:@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>
Met deze code wordt de waarde weergegeven van de teller die wordt geretourneerd vanuit het web-API-project. Deze wordt steeds verhoogd wanneer de gebruiker de pagina opent of vernieuwt.
Ondersteuning voor Docker Compose toevoegen
In het
WebFrontEnd
-project, kies Toevoegen van > Container Orchestrator-ondersteuning. Het dialoogvenster Docker-ondersteuningsopties wordt weergegeven.Kies Docker Compose-.
Visual Studio 17.12 en hoger Kies de opties voor het webfrontend-project.
Visual Studio 17.11 en eerder Kies uw doelbesturingssysteem, bijvoorbeeld Linux.
Visual Studio maakt een docker-compose.yml-bestand en een
.dockerignore
-bestand in het docker compose-knooppunt in de oplossing, en dat project wordt weergegeven in een vetgedrukt lettertype, waarin wordt aangegeven dat het het opstartproject is.De docker-compose.yml wordt als volgt weergegeven:
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Het bestand
.dockerignore
bevat bestandstypen en extensies die u niet wilt opnemen in Docker in de container. Deze bestanden zijn over het algemeen gekoppeld aan de ontwikkelomgeving en broncodebeheer, en maken geen deel uit van de app of service die u ontwikkelt.Bekijk de sectie Container Tools van het uitvoervenster voor meer informatie over de opdrachten die worden uitgevoerd. U kunt zien dat het opdrachtregelprogramma
docker-compose
wordt gebruikt om runtimecontainers te configureren en te maken.Klik in het web-API-project opnieuw met de rechtermuisknop op het projectknooppunt en kies >Container Orchestrator-ondersteuning toevoegen. Kies Docker Compose-en selecteer vervolgens hetzelfde doel besturingssysteem.
Notitie
In deze stap biedt Visual Studio aan om een Dockerfile te maken. Als u dit doet op een project dat al docker-ondersteuning heeft, wordt u gevraagd of u het bestaande Dockerfile wilt overschrijven. Als u wijzigingen hebt aangebracht in uw Dockerfile die u wilt behouden, kiest u nee.
Visual Studio brengt enkele wijzigingen aan in uw
docker-compose
YML-bestand. Beide services zijn nu inbegrepen.services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Voeg de cache toe aan het
docker-compose.yml
-bestand:redis: image: redis
Zorg ervoor dat de inspringing zich op hetzelfde niveau bevindt als de andere twee diensten.
(Visual Studio 17.13 of hoger) De afhankelijke services laten een veelvoorkomend probleem zien. De HTTP-aanvraag op de hoofdpagina van de front-end kan direct worden uitgevoerd bij het starten van de toepassing, voordat de
mywebapi
-service klaar is voor het ontvangen van webaanvragen. Als u Visual Studio 17.13 of hoger gebruikt, kunt u de Docker Compose-functiesdepends_on
enhealthcheck
in docker-compose.yml gebruiken om de projecten in de juiste volgorde te laten beginnen en ze zo nodig gereed te maken voor het verwerken van aanvragen. Zie Docker Compose - Opstartvolgorde.services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend depends_on: mywebapi: condition: service_healthy build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi depends_on: redis: condition: service_started healthcheck: test: curl --fail http://mywebapi:8080/ || exit 1 interval: 20s timeout: 20s retries: 5 build: context: . dockerfile: MyWebAPI/Dockerfile redis: image: redis
In dit voorbeeld gebruikt de statuscontrole
curl
om te controleren of de service gereed is voor het verwerken van aanvragen. Als de afbeelding die u gebruiktcurl
niet geïnstalleerd heeft, voegt u regels toe aan debase
stap van het MyWebAPI Dockerfile om dit te installeren. Voor deze stap zijn verhoogde bevoegdheden vereist, maar u kunt de normale gebruikersbevoegdheden herstellen nadat u deze hebt geïnstalleerd, zoals hier wordt weergegeven (voor de Debian-installatiekopieën die in dit voorbeeld worden gebruikt):USER root RUN apt-get update && apt-get install -y curl USER $APP_UID
Notitie
Als u een Linux-distributie gebruikt, zoals Alpine, biedt dat geen ondersteuning voor
apt-get
, probeert u in plaats daarvanRUN apk --no-cache add curl
.Voor deze Docker Compose-functies is een eigenschapsinstelling vereist in het Docker Compose-projectbestand (
.dcproj
). Stel de eigenschapDependencyAwareStart
in op true:<PropertyGroup> <!-- existing properties --> <DependencyAwareStart>true</DependencyAwareStart> </PropertyGroup>
Deze eigenschap activeert een andere manier om de containers te starten voor foutopsporing die ondersteuning biedt voor de serviceafhankelijkheidsfuncties.
Met deze wijzigingen wordt de
webfrontend
-service pas gestart alsmywebapi
wordt gestart en een webaanvraag met succes verwerkt.Het eerste project waaraan u containerindeling toevoegt, wordt ingesteld om te worden gestart bij het uitvoeren of opsporen van fouten. U kunt de startactie configureren in de Projecteigenschappen voor het Docker Compose-project. Klik in het projectknooppunt Docker Compose met de rechtermuisknop om het contextmenu te openen en kies vervolgens Eigenschappenof gebruik Alt+Enter. U kunt bijvoorbeeld de pagina wijzigen die wordt geladen door de eigenschap Service-URL aan te passen.
Druk op F5-. Dit is wat u ziet wanneer deze wordt gestart:
U kunt de containers bewaken met behulp van het venster Containers. Als u het venster niet ziet, gebruikt u het zoekvak, drukt u op Ctrl+K, Ctrl+O-of drukt u op Ctrl+Q. Zoek in functie, zoek naar
containers
en kies Weergeven>Andere Windows>Containers in de lijst.Vouw het Solution Containers-knooppunt uit en kies het knooppunt voor uw Docker Compose-project om gecombineerde logboeken weer te geven op het tabblad logboeken van dit venster.
U kunt ook het knooppunt voor een afzonderlijke container selecteren om logboeken, omgevingsvariabelen, het bestandssysteem en andere details weer te geven.
Startprofielen instellen
Deze oplossing heeft een Azure Cache voor Redis, maar het is niet efficiënt om de cachecontainer telkens opnieuw te bouwen wanneer u een foutopsporingssessie start. Om die situatie te voorkomen, kunt u een aantal startprofielen instellen. Maak één profiel om Azure Cache voor Redis te starten. Maak een tweede profiel om de andere services te starten. Het tweede profiel kan de cachecontainer gebruiken die al draait. In de menubalk kunt u de vervolgkeuzelijst naast de startknop gebruiken om een menu met foutopsporingsopties te openen. Selecteer Startinstellingen voor Docker Compose beheren.
Het dialoogvenster Instellingen voor het starten van Docker Compose beheren wordt weergegeven. Met dit dialoogvenster kunt u bepalen welke subset van services wordt gestart tijdens een foutopsporingssessie, die wordt gestart met of zonder het foutopsporingsprogramma, en de startservice en URL. Zie Een subset van Compose-services starten.
Kies Nieuwe om een nieuw profiel te maken en geef het
Start Redis
een naam. Stel vervolgens de Redis-container in op Starten zonder foutopsporing, laat de andere container ingesteld op Start nieten kies Opslaan.Maak vervolgens een ander profiel
Start My Services
waarmee Redis niet wordt gestart, maar de andere twee services worden gestart.(Optioneel) Maak een derde profiel
Start All
om alles te starten. U kunt kiezen voor Starten zonder foutopsporing voor Redis.Kies Start Redis in de vervolgkeuzelijst op de hoofdwerkbalk van Visual Studio. De Redis-container bouwt en start zonder debugging. U kunt het venster Containers gebruiken om te zien dat het wordt uitgevoerd. Kies vervolgens Start mijn services in de vervolgkeuzelijst en druk op F5 om ze uit te voeren. Nu kunt u de cachecontainer gedurende veel volgende foutopsporingssessies blijven uitvoeren. Telkens wanneer u Start My Servicesgebruikt, gebruiken deze services dezelfde cachecontainer.
Gefeliciteerd, u voert een Docker Compose-toepassing uit met een aangepast Docker Compose-profiel.
Volgende stappen
Bekijk de opties voor het implementeren van uw -containers in Azure.