Självstudie: Skapa en app med flera containrar med Docker Compose
I den här självstudien får du lära dig hur du hanterar mer än en container och kommunicerar mellan dem när du använder Container Tools i Visual Studio. För att hantera flera containrar krävs containerorkestrering och kräver en orkestrerare som Docker Compose eller Service Fabric. För dessa procedurer använder du Docker Compose. Docker Compose är perfekt för lokal felsökning och testning under utvecklingscykeln.
Det färdiga exemplet som du skapar i den här självstudien finns på GitHub på https://github.com/MicrosoftDocs/vs-tutorial-samples
i mappen docker/ComposeSample.
Förutsättningar
- Docker Desktop
- Visual Studio 2019 med Web Development, Azure Tools arbetsbelastning och/eller .NET-plattformsoberoende utveckling arbetsbelastning installerad
- Docker Desktop
- Visual Studio 2022 med arbetsprogrammet Web Development, Azure Tools och/eller .NET-plattformsoberoende utveckling arbetsprogram installerat. Den här installationen innehåller .NET 8-utvecklingsverktygen.
Skapa ett webbprogramprojekt
I Visual Studio skapar du ett ASP.NET Core Web App-projekt med namnet WebFrontEnd
för att skapa ett webbprogram med Razor-sidor.
Välj inte Aktivera Docker-stödet. Du lägger till Docker-stöd senare i processen.
Välj inte Aktivera Docker-stödet. Du lägger till Docker-stöd senare i processen.
Skapa ett webb-API-projekt
Lägg till ett projekt i samma lösning och anropa det MyWebAPI. Välj API som projekttyp och avmarkera kryssrutan för Konfigurera för HTTPS-. I den här designen använder vi bara SSL för kommunikation med klienten, inte för kommunikation mellan containrar i samma webbprogram. Endast WebFrontEnd
behöver HTTPS och koden i exemplen förutsätter att du har avmarkerat kryssrutan. I allmänhet stöds .NET-utvecklarcertifikaten som används av Visual Studio endast för begäranden från externa till container, inte för begäranden från container till container.
Lägg till ett projekt i samma lösning och anropa det MyWebAPI. Välj API som projekttyp och avmarkera kryssrutan för Konfigurera för HTTPS-.
Notera
I den här designen använder vi bara HTTPS för kommunikation med klienten, inte för kommunikation mellan containrar i samma webbprogram. Endast
WebFrontEnd
behöver HTTPS och koden i exemplen förutsätter att du har avmarkerat kryssrutan. I allmänhet stöds .NET-utvecklarcertifikaten som används av Visual Studio endast för begäranden från externa till container, inte för begäranden från container till container.Lägg till stöd för Azure Cache for Redis. Lägg till NuGet-paketet
Microsoft.Extensions.Caching.StackExchangeRedis
(inteStackExchange.Redis
). I Program.cslägger du till följande rader strax förevar 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"; });
Lägg till med hjälp av direktiv i
Program.cs
förMicrosoft.Extensions.Caching.Distributed
ochMicrosoft.Extensions.Caching.StackExchangeRedis
.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;
I webb-API-projektet tar du bort befintliga
WeatherForecast.cs
och Controllers/WeatherForecastController.csoch lägger till en fil under Kontrollanter CounterController.csmed följande innehåll: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; } } }
Tjänsten ökar en räknare varje gång sidan används och lagrar räknaren i cacheminnet.
Lägga till kod för att anropa webb-API:et
I
WebFrontEnd
-projektet öppnar du filen Index.cshtml.cs och ersätter metodenOnGet
med följande kod.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(); } }
Notera
I verklig kod bör du inte ta bort
HttpClient
efter varje begäran. Metodtips finns i Använda HttpClientFactory för att implementera motståndskraftiga HTTP-begäranden.I filen
Index.cshtml
lägger du till en rad för att visaViewData["Message"]
så att filen ser ut som följande kod:@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>
(endast ASP.NET 2.x) Lägg nu till kod i kontrollanten Värden i webb-API-projektet för att anpassa meddelandet som returneras av API:et för det anrop som du lade till från webfrontend.
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "webapi (with value " + id + ")"; }
Notera
I .NET Core 3.1 och senare kan du använda det angivna WeatherForecast-API:et i stället för den här extra koden. Du måste dock kommentera ut anropet till UseHttpsRedirection i webb-API-projektet eftersom koden använder HTTP för att göra anropet i stället för HTTPS.
//app.UseHttpsRedirection();
Lägg till Stöd för Docker Compose
I projektet
WebFrontEnd
, välj Lägg till stöd för > containerorkestrerare. Dialogrutan Alternativ för Docker-support visas.Välj Docker Compose.
Välj ditt måloperativsystem, till exempel Linux.
Visual Studio skapar en docker-compose.yml-fil och en
.dockerignore
fil i docker-compose nod i lösningen, och det projektet visas i fetstil, vilket visar att det är startprojektet.docker-compose.yml visas på följande sätt:
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Den
version
som anges på den första raden är Docker Compose-filversion. Du bör normalt inte ändra den, eftersom den används av verktygen för att förstå hur du tolkar filen.Filen
.dockerignore
innehåller filtyper och tillägg som du inte vill att Docker ska inkludera i containern. Dessa filer är vanligtvis associerade med utvecklingsmiljön och källkontrollen, inte en del av den app eller tjänst som du utvecklar.Titta på avsnittet Container Tools i utdatafönstret för mer information om de kommandon som körs. Du kan se kommandoradsverktyget
docker-compose
används för att konfigurera och skapa körningscontainrar.Högerklicka igen på projektnoden i webb-API-projektet och välj Lägg till>Container Orchestrator-stöd. Välj Docker Composeoch välj sedan samma måloperativsystem.
Notera
I det här steget erbjuder Visual Studio att skapa en Dockerfile. Om du gör detta i ett projekt som redan har Docker-stöd, tillfrågas du om du vill skriva över den befintliga Dockerfile. Om du har gjort ändringar i din Dockerfile som du vill behålla väljer du nej.
Visual Studio gör vissa ändringar i Docker Compose YML-filen. Nu ingår båda tjänsterna.
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Det första projektet som du lägger till containerorkestrering i konfigureras för att startas när du kör eller felsöker. Du kan konfigurera startåtgärden i Project Properties för Docker Compose-projektet. På projektnoden Docker Compose högerklickar du för att öppna snabbmenyn och väljer sedan Egenskapereller använder Alt+Retur. Följande skärmbild visar de egenskaper som du vill använda för lösningen som används här. Till exempel kan du ändra sidan som läses in genom att anpassa Service-URL-egenskapen .
Här är vad du ser när du startar (.NET Core 2.x-versionen):
Webbappen för .NET 3.1 visar väderdata i JSON-format.
Anta nu att du bara är intresserad av att ha felsökningsprogrammet kopplat till WebFrontEnd, inte webb-API-projektet. Från menyraden kan du använda listrutan bredvid startknappen för att visa en meny med felsökningsalternativ. välj Hantera Startinställningar för Docker Compose.
Dialogrutan Hantera Startinställningar för Docker Compose visas. Med den här dialogrutan kan du styra vilken delmängd av tjänster som startas under en felsökningssession, som startas med eller utan felsökningsprogrammet kopplat, samt starttjänsten och URL:en. Se Starta en delmängd av Compose-tjänster.
Välj Ny för att skapa en ny profil och ge den namnet
Debug WebFrontEnd only
. Ställ sedan in webb-API-projektet på Starta utan att felsöka, lämna Projektet WebFrontEnd inställt på att börja med felsökning och välj Spara.Den nya konfigurationen väljs som standard för nästa F5.
Tryck på F5 för att bekräfta att det fungerar som förväntat.
Grattis, du kör ett Docker Compose-program med en anpassad Docker Compose-profil.
I
WebFrontEnd
-projektet öppnar du filen Index.cshtml.cs och ersätter metodenOnGet
med följande kod.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}"; } }
Notera
I verklig kod bör du inte ta bort
HttpClient
efter varje begäran. Metodtips finns i Använda HttpClientFactory för att implementera motståndskraftiga HTTP-begäranden.Den angivna URI:n refererar till ett tjänstnamn som definierats i filen docker-compose.yml. Docker Compose konfigurerar ett standardnätverk för kommunikation mellan containrar med hjälp av de tjänstnamn som anges som värdar.
Koden som visas här fungerar med .NET 8 och senare, som konfigurerar ett användarkonto i Dockerfile utan administratörsbehörighet och exponerar port 8080 eftersom HTTP-standardporten 80 inte är tillgänglig utan förhöjd behörighet.
I filen
Index.cshtml
lägger du till en rad för att visaViewData["Message"]
så att filen ser ut som följande kod:@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>
Den här koden visar värdet för räknaren som returneras från webb-API-projektet. Den ökar varje gång användaren kommer åt eller uppdaterar sidan.
Lägg till Stöd för Docker Compose
I projektet
WebFrontEnd
, välj Lägg till stöd för > containerorkestrerare. Dialogrutan Alternativ för Docker-support visas.Välj Docker Compose.
Visual Studio 17.12 och senare Välj scaffolding-alternativen för WebFrontEnd-projektet.
Visual Studio 17.11 och tidigare Välj ditt måloperativsystem, till exempel Linux.
Visual Studio skapar en docker-compose.yml-fil och en
.dockerignore
fil i docker-compose nod i lösningen, och det projektet visas i fetstil, vilket visar att det är startprojektet.docker-compose.yml visas på följande sätt:
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile
Filen
.dockerignore
innehåller filtyper och tillägg som du inte vill att Docker ska inkludera i containern. Dessa filer är vanligtvis associerade med utvecklingsmiljön och källkontrollen, inte en del av den app eller tjänst som du utvecklar.Titta på avsnittet Container Tools i utdatafönstret för mer information om de kommandon som körs. Du kan se kommandoradsverktyget
docker-compose
används för att konfigurera och skapa körningscontainrar.Högerklicka igen på projektnoden i webb-API-projektet och välj Lägg till>Container Orchestrator-stöd. Välj Docker Composeoch välj sedan samma måloperativsystem.
Notera
I det här steget erbjuder Visual Studio att skapa en Dockerfile. Om du gör detta i ett projekt som redan har Docker-stöd, tillfrågas du om du vill skriva över den befintliga Dockerfile. Om du har gjort ändringar i din Dockerfile som du vill behålla väljer du nej.
Visual Studio gör vissa ändringar i din
docker-compose
YML-fil. Nu ingår båda tjänsterna.services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/Dockerfile
Lägg till cachen i
docker-compose.yml
-filen:redis: image: redis
Kontrollera att indenteringen är på samma nivå som de andra två tjänsterna.
(Visual Studio 17.13 eller senare) Beroendetjänster påvisar ett vanligt problem. HTTP-begäran i klientdelens huvudsida kan köras omedelbart vid programstart, innan
mywebapi
-tjänsten är redo att ta emot webbbegäranden. Om du använder Visual Studio 17.13 eller senare kan du använda Docker Compose-funktionernadepends_on
ochhealthcheck
i docker-compose.yml för att få projekten att starta i rätt ordning och låta dem vara redo att hantera begäranden vid behov. Se Docker Compose – Startordning.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
I det här exemplet använder hälsokontrollen
curl
för att verifiera att tjänsten är redo att bearbeta begäranden. Om avbildningen du använder inte harcurl
installerat lägger du till rader ibase
-fasen i MyWebAPI Dockerfile för att installera den. Det här steget kräver utökade privilegier, men du kan återställa de normala användarbehörigheterna efter att du har installerat det som du ser här (för Debian-avbildningarna som används i det här exemplet):USER root RUN apt-get update && apt-get install -y curl USER $APP_UID
Notera
Om du använder en Linux-distribution, till exempel Alpine, som inte stöder
apt-get
kan du provaRUN apk --no-cache add curl
i stället.Dessa Docker Compose-funktioner kräver en egenskapsinställning i Docker Compose-projektfilen (
.dcproj
). Ange egenskapenDependencyAwareStart
till true:<PropertyGroup> <!-- existing properties --> <DependencyAwareStart>true</DependencyAwareStart> </PropertyGroup>
Den här egenskapen aktiverar ett annat sätt att starta containrarna för felsökning som stöder funktionerna för tjänstberoende.
Med dessa ändringar startar inte
webfrontend
-tjänsten förränmywebapi
startar och hanterar en webbbegäran.Det första projektet som du lägger till containerorkestrering i konfigureras för att startas när du kör eller felsöker. Du kan konfigurera startåtgärden i Project Properties för Docker Compose-projektet. På projektnoden Docker Compose högerklickar du för att öppna snabbmenyn och väljer sedan Egenskapereller använder Alt+Retur. Till exempel kan du ändra sidan som läses in genom att anpassa Service-URL-egenskapen .
Tryck på F5. Här är vad du ser när du startar:
Du kan övervaka containrarna med hjälp av fönstret Containrar. Om du inte ser fönstret använder du sökrutan, trycker på Ctrl+K, Ctrl+Oeller trycker på Ctrl+Q. Under Funktionssökningsöker du efter
containers
och väljer Visa>Andra fönster>Behållare i listan.Expandera Lösningscontainrar noden och välj noden för Docker Compose-projektet för att visa kombinerade loggar i fliken Loggar i det här fönstret.
Du kan också välja noden för en enskild container för att visa loggar, miljövariabler, filsystemet och annan information.
Konfigurera startprofiler
Den här lösningen har en Azure Cache for Redis, men det är inte effektivt att återskapa cachecontainern varje gång du startar en felsökningssession. För att undvika den situationen kan du konfigurera ett par startprofiler. Skapa en profil för att starta Azure Cache for Redis. Skapa en andra profil för att starta de andra tjänsterna. Den andra profilen kan använda den cachecontainer som redan körs. Från menyraden kan du använda listrutan bredvid startknappen för att öppna en meny med felsökningsalternativ. Välj Hantera Startinställningar för Docker Compose.
Dialogrutan Hantera Startinställningar för Docker Compose visas. Med den här dialogrutan kan du styra vilken delmängd av tjänster som startas under en felsökningssession, som startas med eller utan felsökningsprogrammet kopplat, samt starttjänsten och URL:en. Se Starta en delmängd av Compose-tjänster.
Välj Ny för att skapa en ny profil och ge den namnet
Start Redis
. Ställ sedan in Redis-containern på Starta utan att felsöka, lämna den andra inställd på Starta inteoch välj Spara.Skapa sedan en annan profil
Start My Services
som inte startar Redis, men startar de andra två tjänsterna.(Valfritt) Skapa en tredje profil
Start All
för att starta allt. Du kan välja Starta utan att felsöka för Redis.Välj Starta Redis i listrutan i visual studio-verktygsfältet. Redis-containern bygger och startar utan felsökning. Du kan använda fönstret Containers för att se att det körs. Välj sedan Starta mina tjänster i listrutan och tryck på F5 för att starta dem. Nu kan du hålla cachecontainern igång under många efterföljande felsökningssessioner. Varje gång du använder Starta mina tjänsteranvänder dessa tjänster samma cachecontainer.
Grattis, du kör ett Docker Compose-program med en anpassad Docker Compose-profil.
Nästa steg
Titta på alternativen för att distribuera dina containrar till Azure.