Sdílet prostřednictvím


Kurz: Vytvoření vícekontenerové aplikace pomocí Docker Compose

V tomto kurzu se naučíte spravovat více než jeden kontejner a komunikovat mezi nimi při použití nástrojů kontejneru v sadě Visual Studio. Správa více kontejnerů vyžaduje orchestraci kontejnerů a vyžaduje orchestrátor, jako je Docker Compose. Pro tyto postupy použijete Docker Compose. Docker Compose je skvělý pro místní ladění a testování v průběhu vývojového cyklu.

Dokončená ukázka, kterou vytvoříte v tomto kurzu, najdete na GitHubu na https://github.com/MicrosoftDocs/vs-tutorial-samples ve složce docker/ComposeSample.

Požadavky

  • Docker Desktop
  • Visual Studio s nainstalovanou úlohou vývoje pro ASP.NET a web, úlohou vývoje pro Azure a/nebo .NET pro různé platformy Tato instalace zahrnuje sadu .NET SDK.
  • Docker Desktop
  • Visual Studio s nainstalovanou úlohou vývoje pro ASP.NET a web, úlohou vývoje pro Azure a/nebo .NET pro různé platformy Tato instalace zahrnuje sadu .NET SDK.

Vytvoření projektu webové aplikace

V sadě Visual Studio vytvořte projekt ASP.NET Core Web App s názvem WebFrontEnda vytvořte webovou aplikaci se stránkami Razor Pages.

Snímek obrazovky zobrazující projekt Vytvoření webové aplikace ASP.NET Core.

Nepovolujte podporu Dockeru. Podporu pro Docker Compose přidáte později v procesu.

snímek obrazovky Další informace při vytváření webového projektu Možnost Povolit podporu Dockeru není vybraná.

Nevybírejte Povolit podporu kontejnerů. Podporu kontejneru přidáte později v procesu.

Snímek obrazovky Další informace při vytváření webového projektu Možnost Povolit podporu kontejneru není vybraná.

Vytvoření projektu webového rozhraní API

Přidejte projekt do stejného řešení a zavolejte ho MyWebAPI. Vyberte jako typ projektu rozhraní API a zrušte zaškrtnutí políčka Konfigurovat proHTTPS. V tomto návrhu používáme pouze ssl pro komunikaci s klientem, ne pro komunikaci mezi kontejnery ve stejné webové aplikaci. Pouze WebFrontEnd potřebuje HTTPS a kód v příkladech předpokládá, že jste toto políčko nezaškrtli. Obecně platí, že vývojářské certifikáty .NET používané sadou Visual Studio jsou podporovány pouze pro požadavky externího kontejneru, ne pro požadavky typu kontejner-kontejner.

snímek obrazovky s vytvořením projektu webového rozhraní API

  1. Přidejte projekt do stejného řešení a zavolejte ho MyWebAPI. Vyberte jako typ projektu rozhraní API a zrušte zaškrtnutí políčka Konfigurovat proHTTPS.

    Poznámka

    V tomto návrhu používáme pouze HTTPS pro komunikaci s klientem, ne pro komunikaci mezi kontejnery ve stejné webové aplikaci. Pouze WebFrontEnd potřebuje HTTPS a kód v příkladech předpokládá, že jste toto políčko nezaškrtli. Obecně platí, že vývojářské certifikáty .NET používané sadou Visual Studio jsou podporovány pouze pro požadavky externího kontejneru, ne pro požadavky typu kontejner-kontejner.

    snímek obrazovky s vytvořením projektu webového rozhraní API

  2. Přidání podpory pro Azure Cache for Redis Přidejte balíček NuGet Microsoft.Extensions.Caching.StackExchangeRedis (nikoli StackExchange.Redis). Do Program.cspřidejte následující řádky těsně před var 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";
       });
    
  3. Přidejte direktivy using pro Program.cs, Microsoft.Extensions.Caching.Distributed a Microsoft.Extensions.Caching.StackExchangeRedis.

    using Microsoft.Extensions.Caching.Distributed;
    using Microsoft.Extensions.Caching.StackExchangeRedis;
    
  4. V projektu webového rozhraní API odstraňte existující WeatherForecast.cs a kontrolery/WeatherForecastController.csa přidejte soubor pod kontrolery CounterController.css následujícím obsahem:

    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;
            }
        }
    }
    

    Služba zvýší čítač při každém přístupu na stránku a uloží čítač do mezipaměti.

Přidání kódu pro volání webového rozhraní API

  1. V projektu WebFrontEnd otevřete soubor Index.cshtml.cs a nahraďte metodu OnGet následujícím kódem.

     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();
        }
     }
    

    Poznámka

    V reálném kódu byste neměli po každém požadavku odstraňovat HttpClient. Osvědčené postupy najdete v tématu Použití HttpClientFactory k implementaci odolných požadavků HTTP.

  2. Do souboru Index.cshtml přidejte řádek pro zobrazení ViewData["Message"], aby soubor vypadal jako následující kód:

    @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. (pouze ASP.NET 2.x) Nyní v projektu Web API přidejte do kontroleru Values kód, který přizpůsobí zprávu vrácenou rozhraním API pro volání, které jste přidali z webfrontend.

    // GET api/values/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
       return "webapi (with value " + id + ")";
    }
    

    Poznámka

    Místo tohoto nadbytečného kódu můžete použít zadané rozhraní API WeatherForecast. Je však nutné okomentovat volání UseHttpsRedirection v projektu webového rozhraní API, protože kód používá k volání protokol HTTP místo HTTPS.

          //app.UseHttpsRedirection();
    

Přidání podpory Docker Compose

  1. V projektu WebFrontEnd zvolte Přidat podporu orchestrátoru kontejnerů >. Zobrazí se dialogové okno Možnosti podpory Dockeru.

  2. Vyberte Docker Compose.

  3. Zvolte cílový operační systém, například Linux.

    snímek obrazovky s výběrem cílového operačního systému.

    Visual Studio vytvoří soubor docker-compose.yml a soubor .dockerignore v uzlu docker-compose v řešení a tento projekt je zobrazen tučným písmem, což ukazuje, že se jedná o spouštěcí projekt.

    snímek obrazovky Průzkumníka řešení s přidaným projektem Docker Compose

    docker-compose.yml se zobrazí takto:

     services:
       webfrontend:
         image: ${DOCKER_REGISTRY-}webfrontend
         build:
           context: .
           dockerfile: WebFrontEnd/Dockerfile
    

    version zadané na prvním řádku je verze souboru Docker Compose . Obvykle byste ho neměli měnit, protože ho nástroje používají k pochopení toho, jak soubor interpretovat.

    Soubor .dockerignore obsahuje typy souborů a přípony, které nechcete do kontejneru zahrnout. Tyto soubory jsou obecně přidružené k vývojovému prostředí a správě zdrojového kódu, nikoli k aplikaci nebo službě, kterou vyvíjíte.

    Podrobnosti o spouštěných příkazech najdete v části Nástroje kontejneru podokna výstupu. Nástroj příkazového řádku docker-compose slouží ke konfiguraci a vytvoření kontejnerů modulu runtime.

  4. V projektu webového rozhraní API opět klikněte pravým tlačítkem myši na uzel projektu a zvolte Přidat>podporu orchestrátoru kontejnerů. Zvolte Docker Compose a pak vyberte stejný cílový operační systém.

    Poznámka

    V tomto kroku Visual Studio nabídne vytvoření souboru Dockerfile. Pokud to uděláte u projektu, který už podporuje Docker, zobrazí se výzva, jestli chcete přepsat existující soubor Dockerfile. Pokud jste v souboru Dockerfile udělali změny, které chcete zachovat, zvolte ne.

    Visual Studio provede některé změny v souboru Docker Compose YML. Nyní jsou zahrnuty obě služby.

    services:
      webfrontend:
        image: ${DOCKER_REGISTRY-}webfrontend
        build:
          context: .
          dockerfile: WebFrontEnd/Dockerfile
    
      mywebapi:
        image: ${DOCKER_REGISTRY-}mywebapi
        build:
          context: .
          dockerfile: MyWebAPI/Dockerfile
    
  5. První projekt, ke kterému přidáte orchestraci kontejnerů, se nastaví tak, aby se spustil při spuštění nebo ladění. Akci spuštění můžete nakonfigurovat v vlastnostech projektu pro projekt Docker Compose. V uzlu projektu Docker Compose kliknutím pravým tlačítkem otevřete místní nabídku a pak zvolte Vlastnostinebo použijte Alt+Enter. Následující snímek obrazovky ukazuje vlastnosti, které chcete použít pro řešení použité tady. Například můžete změnit stránku, která se načítá, přizpůsobením vlastnosti Adresa URL služby.

    snímek obrazovky s vlastnostmi projektu Docker Compose

    Toto uvidíte při spuštění (verze .NET Core 2.x):

    snímek obrazovky se spuštěnou webovou aplikací.

    Webová aplikace pro .NET 3.1 zobrazuje data o počasí ve formátu JSON.

  6. Předpokládejme, že vás zajímá jenom to, že ladicí program je připojený k WebFrontEndu, ne projekt webového rozhraní API. V řádku nabídek můžete pomocí rozevíracího seznamu vedle tlačítka Start zobrazit nabídku možností ladění; zvolte Spravovat nastavení spuštění Docker Compose.

    snímek obrazovky s položkou nabídky Spravovat nastavení skládání pro ladění

    Zobrazí se dialogové okno Spravovat nastavení spuštění docker Compose. Pomocí tohoto dialogového okna můžete určit, která podmnožina služeb se spustí během ladicí relace, která se spustí s připojeným ladicím programem nebo bez něj, a spouštěcí službu a adresu URL. Viz Spusťte podmnožinu služeb Compose.

    Snímek obrazovky dialogového okna pro správu nastavení spuštění Docker Compose.

    Zvolte Nový a vytvořte nový profil a pojmenujte ho Debug WebFrontEnd only. Pak nastavte projekt webového rozhraní API na Spustit bez ladění, ponechte projekt WebFrontEnd nastavený tak, aby začal s laděním, a zvolte Uložit.

    Nová konfigurace je zvolena jako výchozí pro další F5.

  7. Stisknutím klávesy F5 potvrďte, že funguje podle očekávání.

Blahopřejeme, spouštíte aplikaci Docker Compose s vlastním profilem Docker Compose.

  1. V projektu WebFrontEnd otevřete soubor Index.cshtml.cs a nahraďte metodu OnGet následujícím kódem.

    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}";
       }
    }
    

    Poznámka

    V reálném kódu byste neměli po každém požadavku odstraňovat HttpClient. Osvědčené postupy najdete v tématu Použití HttpClientFactory k implementaci odolných požadavků HTTP.

    Identifikátor URI odkazuje na název služby definovaný v souboru docker-compose.yml. Docker Compose nastaví výchozí síť pro komunikaci mezi kontejnery pomocí uvedených názvů služeb jako hostitelů.

    Zde uvedený kód funguje s .NET 8 a novějším, který nastaví uživatelský účet v souboru Dockerfile bez oprávnění správce a zpřístupní port 8080, protože výchozí port HTTP 80 není přístupný bez zvýšených oprávnění.

  2. Do souboru Index.cshtml přidejte řádek pro zobrazení ViewData["Message"], aby soubor vypadal jako následující kód:

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

    Tento kód zobrazí hodnotu čítače, která je vrácena z projektu rozhraní webového API. Zvýší se pokaždé, když uživatel přistupuje nebo aktualizuje stránku.

Přidání podpory Docker Compose

  1. V projektu WebFrontEnd zvolte Přidat podporu orchestrátoru kontejnerů >. Zobrazí se dialogové okno Možnosti podpory Dockeru.

  2. Vyberte Docker Compose.

  3. Visual Studio 17.12 a novější Zvolte možnosti generování kódu pro projekt WebFrontEnd.

    Snímek obrazovky s dialogem Možnosti lešení kontejneru pro projekt WebFrontEnd

    Visual Studio verze 17.11 a starší Zvolte svůj cílový operační systém, například Linux.

    snímek obrazovky s výběrem cílového operačního systému.

    Visual Studio vytvoří soubor docker-compose.yml a soubor .dockerignore v uzlu docker-compose v řešení a tento projekt je zobrazen tučným písmem, což ukazuje, že se jedná o spouštěcí projekt.

    snímek obrazovky Průzkumníka řešení s přidaným projektem Docker Compose

    docker-compose.yml se zobrazí takto:

     services:
       webfrontend:
         image: ${DOCKER_REGISTRY-}webfrontend
         build:
           context: .
           dockerfile: WebFrontEnd/Dockerfile
    

    Soubor .dockerignore obsahuje typy souborů a přípony, které nechcete do kontejneru zahrnout. Tyto soubory jsou obecně přidružené k vývojovému prostředí a správě zdrojového kódu, nikoli k aplikaci nebo službě, kterou vyvíjíte.

    Podrobnosti o spouštěných příkazech najdete v části Nástroje kontejneru podokna výstupu. Nástroj příkazového řádku docker-compose slouží ke konfiguraci a vytvoření kontejnerů modulu runtime.

  4. V projektu webového rozhraní API opět klikněte pravým tlačítkem myši na uzel projektu a zvolte Přidat>podporu orchestrátoru kontejnerů. Zvolte Docker Compose a pak vyberte stejný cílový operační systém.

    Poznámka

    V tomto kroku Visual Studio nabídne vytvoření souboru Dockerfile. Pokud to uděláte u projektu, který už podporuje Docker, zobrazí se výzva, jestli chcete přepsat existující soubor Dockerfile. Pokud jste v souboru Dockerfile udělali změny, které chcete zachovat, zvolte ne.

    Visual Studio provede některé změny souboru docker-compose YML. Nyní jsou zahrnuty obě služby.

    services:
      webfrontend:
        image: ${DOCKER_REGISTRY-}webfrontend
        build:
          context: .
          dockerfile: WebFrontEnd/Dockerfile
    
      mywebapi:
        image: ${DOCKER_REGISTRY-}mywebapi
        build:
          context: .
          dockerfile: MyWebAPI/Dockerfile
    
  5. Přidejte mezipaměť do souboru docker-compose.yml:

    redis:
       image: redis
    

    Ujistěte se, že odsazení je na stejné úrovni jako ostatní dvě služby.

  6. (Visual Studio 17.13 nebo novější) Závislé služby ukazují běžný problém. Požadavek HTTP na hlavní stránce front-endu se může spustit okamžitě při spuštění aplikace, než bude služba mywebapi připravená přijímat webové požadavky. Pokud používáte Visual Studio 17.13 nebo novější, můžete použít funkce Docker Compose depends_on a healthcheck v docker-compose.yml, aby se projekty spustily ve správném pořadí, a v případě potřeby je můžete připravit k poskytování požadavků. Viz Docker Compose – pořadí spuštění.

    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/Counter || exit 1
            interval: 20s
            timeout: 20s
            retries: 5
         build:
            context: .
            dockerfile: MyWebAPI/Dockerfile
    
      redis:
         image: redis
    

    V tomto příkladu kontrola stavu používá curl k ověření, že služba je připravená zpracovávat požadavky. Pokud image, kterou používáte, nemá nainstalované curl, přidejte řádky do fáze base v souboru MyWebAPI Dockerfile k její instalaci. Tento krok vyžaduje zvýšená oprávnění, ale po instalaci můžete obnovit normální uživatelská oprávnění, jak je znázorněno zde (pro image Debianu použité v tomto příkladu):

    USER root
    RUN apt-get update && apt-get install -y curl
    USER $APP_UID
    

    Poznámka

    Pokud používáte distribuci Linuxu, například Alpine, která nepodporuje apt-get, zkuste místo toho RUN apk --no-cache add curl.

    Tyto funkce Docker Compose vyžadují nastavení vlastnosti v souboru projektu Docker Compose (.dcproj). Nastavte vlastnost DependencyAwareStart na true:

    <PropertyGroup>
       <!-- existing properties -->
       <DependencyAwareStart>true</DependencyAwareStart>
    </PropertyGroup>
    

    Tato vlastnost aktivuje odlišný způsob spuštění kontejnerů pro ladění, který podporuje funkce závislosti služby.

    Při těchto změnách se služba webfrontend nespustí, dokud mywebapi nespustí a úspěšně zpracuje webový požadavek.

  7. První projekt, ke kterému přidáte orchestraci kontejnerů, se nastaví tak, aby se spustil při spuštění nebo ladění. Akci spuštění můžete nakonfigurovat v vlastnostech projektu pro projekt Docker Compose. V uzlu projektu Docker Compose klikněte pravým tlačítkem myši, abyste otevřeli místní nabídku, a potom zvolte Vlastnosti, nebo použijte Alt+Enter. Například můžete změnit stránku, která se načítá, přizpůsobením vlastnosti Adresa URL služby.

    snímek obrazovky s vlastnostmi projektu Docker Compose

  8. Stiskněte F5. Při spuštění uvidíte toto:

    snímek obrazovky se spuštěnou webovou aplikací.

  9. Kontejnery můžete monitorovat pomocí okna Containers. Pokud okno nevidíte, použijte vyhledávací pole, stiskněte Ctrl+K, Ctrl+Onebo stiskněte Ctrl+Q. V části Vyhledávání funkcívyhledejte containersa v seznamu zvolte Zobrazení>Další Okna>Kontejnery.

  10. Rozbalte uzel Kontejnery řešení a výběrem uzlu projektu Docker Compose zobrazte kombinované protokoly na kartě Protokoly v tomto okně.

    snímek obrazovky zobrazující kartu Protokoly v okně Kontejnery

    Můžete také vybrat uzel pro jednotlivé kontejnery a zobrazit protokoly, proměnné prostředí, systém souborů a další podrobnosti.

Nastavte profily spuštění

  1. Řešení obsahuje službu Azure Cache for Redis, avšak není účelné znovu sestavovat kontejner mezipaměti při každém spuštění ladicí relace. Abyste se této situaci vyhnuli, můžete nastavit několik profilů spuštění. Vytvořte jeden profil pro spuštění služby Azure Cache for Redis. Vytvořte druhý profil, který spustí ostatní služby. Druhý profil může použít kontejner mezipaměti, který už je spuštěný. V řádku nabídek můžete pomocí rozevíracího seznamu vedle tlačítka Start otevřít nabídku s možnostmi ladění. Vyberte Spravovat nastavení spuštění Docker Compose.

    snímek obrazovky s položkou nabídky Spravovat nastavení skládání pro ladění

    Zobrazí se dialogové okno Spravovat nastavení spuštění docker Compose. Pomocí tohoto dialogového okna můžete určit, která podmnožina služeb se spustí během ladicí relace, která se spustí s připojeným ladicím programem nebo bez něj, a spouštěcí službu a adresu URL. Viz Spusťte podmnožinu služeb Compose.

    Snímek obrazovky dialogového okna pro správu nastavení spuštění Docker Compose.

    Zvolte Nový a vytvořte nový profil a pojmenujte ho Start Redis. Potom nastavte kontejner Redis na Spustit bez ladění, ponechte druhou nastavenou na Nespouštěta zvolte Uložit.

    Snímek obrazovky znázorňující vytvoření profilu Redis, který spouští pouze službu Redis

    Pak vytvořte další profil Start My Services, který nespustí Redis, ale spustí další dvě služby.

    snímek obrazovky znázorňující vytvoření profilu Služby, který spouští ostatní služby

    (Volitelné) Vytvořte třetí profil Start All, abyste mohli vše zahájit. Můžete si vybrat možnost Spustit bez ladění pro Redis.

  2. V rozevíracím seznamu na hlavním panelu nástrojů sady Visual Studio zvolte Spustit Redis. Kontejner Redis se sestaví a spustí bez ladění. Pomocí okna Containers můžete zjistit, že je spuštěný. Potom v rozevíracím seznamu zvolte Spustit moje služby a stisknutím klávesy F5 je spusťte. Teď můžete kontejner mezipaměti udržovat spuštěný v několika následných ladicích relacích. Pokaždé, když používáte Spustit moje služby, tyto služby používají stejný kontejner mezipaměti.

Blahopřejeme, spouštíte aplikaci Docker Compose s vlastním profilem Docker Compose.

Další kroky

Podívejte se na možnosti nasazení kontejnerů do Azure. Pokud jste připravení nasadit do Azure Container Apps, přečtěte si téma Nasazení vícekontejnerové aplikace do Azure Container Apps.

Viz také

Docker Compose

Nástroje kontejneru