Didacticiel : Créer une application multiconteneur avec Docker Compose

Dans ce tutoriel, vous allez apprendre à gérer plusieurs conteneurs et communiquer entre eux lorsque vous utilisez les outils conteneur dans Visual Studio. La gestion de plusieurs conteneurs nécessite une orchestration de conteneur et un orchestrateur tel que Docker Compose ou Service Fabric. Pour ces procédures, vous utilisez Docker Compose. Docker Compose est idéal pour le débogage et les tests locaux au cours du cycle de développement.

Vous trouverez l’exemple terminé que vous allez créer dans ce tutoriel sur GitHub sous https://github.com/MicrosoftDocs/vs-tutorial-samples dans le dossier docker/ComposeSample.

Prérequis

  • Docker Desktop
  • Visual Studio 2019 avec la charge de travail Développement web, Outils Azure et/ou la charge de travail Développement multiplateforme .NET Core installée
  • Docker Desktop
  • Visual Studio 2022 avec la charge de travail Développement web, Outils Azure et/ou la charge de travail Développement multiplateforme .NET Core installée. Cette installation inclut les outils de développement .NET 8.

Créer un projet d’application web

Dans Visual Studio, créez un projet d’application web ASP.NET Core, nommé WebFrontEnd, pour créer une application web avec des pages Razor.

Screenshot showing Create ASP.NET Core Web App project.

Ne sélectionnez pasActiver la prise en charge de Docker. Vous ajoutez la prise en charge de Docker ultérieurement dans le processus.

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

Remarque

Dans Visual Studio 2022 17.2 et versions ultérieures, vous pouvez utiliser Azure Functions pour ce projet à la place.

Screenshot showing Create ASP.NET Core Web App project.

Ne sélectionnez pasActiver la prise en charge de Docker. Vous ajoutez la prise en charge de Docker ultérieurement dans le processus.

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

Créer un projet d’API web

Ajoutez un projet à la même solution et appelez-le MyWebAPI. Sélectionnez API comme type de projet, puis décochez la case Configurer pour HTTPS. Dans cette conception, nous utilisons uniquement SSL pour la communication avec le client, et non pour la communication entre les conteneurs dans la même application web. Seul WebFrontEnd nécessite HTTPS et le code dans les exemples suppose que vous avez décoché cette case. En général, les certificats de développeur .NET utilisés par Visual Studio sont uniquement pris en charge pour les demandes externes à conteneur, et non pour les demandes de conteneur à conteneur.

Screenshot of creating the Web API project.

  1. Ajoutez un projet à la même solution et appelez-le WebAPI. Sélectionnez API comme type de projet, puis décochez la case Configurer pour HTTPS. Dans cette conception, nous utilisons uniquement SSL pour la communication avec le client, et non pour la communication entre les conteneurs dans la même application web. Seul WebFrontEnd nécessite HTTPS et le code dans les exemples suppose que vous avez décoché cette case. En général, les certificats de développeur .NET utilisés par Visual Studio sont uniquement pris en charge pour les demandes externes à conteneur, et non pour les demandes de conteneur à conteneur.

    Screenshot of creating the Web API project.

  2. Ajoutez la prise en charge pour Cache Redis. Ajoutez le package NuGet Microsoft.Extensions.Caching.StackExchangeRedis (non StackExchange.Redis). Dans Program.cs, ajoutez les lignes suivantes, juste avant 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. Ajoutez des directives using dans Program.cs pour Microsoft.Extensions.Caching.Distributed et Microsoft.Extensions.Caching.StackExchangeRedis.

    using Microsoft.Extensions.Caching.Distributed;
    using Microsoft.Extensions.Caching.StackExchangeRedis;
    
  4. Dans le projet d’API web, supprimez les fichiers WeatherForecast.cs et Controllers/WeatherForecastController.cs existants, puis ajoutez un fichier sous Contrôleurs, CounterController.cs, avec le contenu suivant :

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

    Le service incrémente un compteur chaque fois que la page est consultée et stocke le compteur dans le cache Redis.

Ajouter le code pour appeler l’API web

  1. Dans le projet WebFrontEnd, ouvrez le fichier Index.cshtml.cs, puis remplacez la méthode OnGet par le code suivant.

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

    Notes

    Dans le code réel, vous ne devez pas supprimer HttpClient après chaque requête. Pour obtenir les meilleures pratiques, consultez Utiliser HttpClientFactory pour implémenter des requêtes HTTP résilientes.

  2. Dans le fichier Index.cshtml, ajoutez une ligne pour afficher ViewData["Message"] afin que le fichier ressemble à ce qui suit :

    @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. (ASP.NET 2.x uniquement) Maintenant, dans le projet d’API web, ajoutez du code au contrôleur de valeurs pour personnaliser le message retourné par l’API pour l’appel que vous avez ajouté à partir de webfrontend.

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

    Remarque

    Dans .NET Core 3.1 et les versions ultérieures, vous pouvez utiliser l’API WeatherForecast fournie plutôt que ce code supplémentaire. Toutefois, vous devez commenter l’appel à UseHttpsRedirection dans le projet d’API web, car ce code utilise HTTP, et non HTTPS, pour appeler l’API web.

          //app.UseHttpsRedirection();
    

Ajouter la prise en charge de Docker Compose

  1. Dans le projet WebFrontEnd, choisissez Ajouter > Prise en charge de l’orchestrateur de conteneurs. La boîte de dialogue Options de prise en charge de Docker s’affiche.

  2. Choisissez Docker Compose.

  3. Choisissez votre système d’exploitation cible, par exemple Linux.

    Screenshot of choosing the Target OS.

    Visual Studio crée un fichier docker-compose.yml et un fichier .dockerignore dans le nœud docker-compose de la solution, et ce projet s’affiche en police gras, ce qui montre qu’il s’agit du projet de démarrage.

    Screenshot of Solution Explorer with docker-compose project added.

    Le fichier docker-compose.yml s’affiche comme suit :

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

    Le version spécifié dans la première ligne est la version du fichier Docker Compose. Normalement, vous ne devez pas le modifier, car il est utilisé par les outils pour comprendre comment interpréter le fichier.

    Le fichier .dockerignore contient les types et extensions de fichiers que Docker ne doit pas inclure dans le conteneur. Ces fichiers sont généralement associés à l’environnement de développement et au contrôle de code source et ne font pas partie de l’application ou du service que vous déployez.

    Pour plus d’informations sur les commandes en cours d’exécution, consultez la section Outils conteneur du volet de sortie. Vous pouvez voir que l’outil en ligne de commande docker-compose est utilisé pour configurer et créer les conteneurs d’exécution.

  4. Dans le projet d’API web, cliquez de nouveau avec le bouton droit sur le nœud du projet, puis choisissez Ajouter >Prise en charge de l’orchestrateur de conteneurs. Choisissez Docker Compose, puis sélectionnez le même système d’exploitation cible.

    Notes

    Dans cette étape, Visual Studio propose de créer un fichier Dockerfile. Si vous effectuez cette opération sur un projet qui dispose déjà de la prise en charge de Docker, vous êtes invité à indiquer si vous souhaitez remplacer le fichier Dockerfile existant. Si vous avez apporté des modifications à votre fichier Dockerfile que vous souhaitez conserver, choisissez non.

    Visual Studio apporte des modifications à votre fichier YML Docker Compose. Les deux services sont désormais inclus.

    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. Le premier projet auquel vous ajoutez l’orchestration de conteneur est configuré pour être lancé lorsque vous effectuez une exécution ou un débogage. Vous pouvez configurer l’action de lancement dans les propriétés du projet Docker-Compose. Sur le nœud du projet Docker-Compose, cliquez avec le bouton droit pour ouvrir le menu contextuel, puis choisissez Propriétés ou utilisez Alt+Entrée. La capture d’écran suivante montre les propriétés souhaitées pour la solution utilisée ici. Par exemple, vous pouvez modifier la page chargée en personnalisant la propriété URL du service .

    Screenshot of docker-compose project properties.

    Voici ce que vous voyez lors du lancement (version .NET Core 2.x) :

    Screenshot of running web app.

    L’application web pour .NET 3.1 affiche les données météorologiques au format JSON.

  6. Supposons maintenant que vous vouliez que le débogueur soit uniquement attaché à WebFrontEnd, et non au projet d’API web. Dans la barre de menus, vous pouvez utiliser la liste déroulante en regard du bouton Démarrer pour afficher un menu d’options de débogage ; choisissez Gérer les paramètres de lancement de Docker Compose.

    Screenshot of Debug Manage Compose Settings menu item.

    La boîte de dialogue Gérer les paramètres de lancement de Docker Compose s’affiche. Cette boîte de dialogue vous permet de contrôler le sous-ensemble de services qui est lancé pendant une session de débogage, quels services sont lancés avec ou sans le débogueur attaché, ainsi que le service de lancement et l’URL. Consulter Démarrer un sous-ensemble de services Compose.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    Choisissez Nouveau pour créer un profil et nommez-le Debug WebFrontEnd only. Ensuite, définissez le projet d’API web sur Démarrer sans débogage, laissez le projet WebFrontEnd défini pour commencer par le débogage, puis choisissez Enregistrer.

    La nouvelle configuration est choisie comme valeur par défaut pour la F5 suivante.

  7. Appuyez sur F5 pour confirmer qu’elle fonctionne comme prévu.

Félicitations, vous exécutez une application Docker Compose avec un profil Docker Compose personnalisé.

  1. Dans le projet WebFrontEnd, ouvrez le fichier Index.cshtml.cs, puis remplacez la méthode OnGet par le code suivant.

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

    Notes

    Dans le code réel, vous ne devez pas supprimer HttpClient après chaque requête. Pour obtenir les meilleures pratiques, consultez Utiliser HttpClientFactory pour implémenter des requêtes HTTP résilientes.

  2. Dans le fichier Index.cshtml, ajoutez une ligne pour afficher ViewData["Message"] afin que le fichier ressemble à ce qui suit :

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

    Ce code affiche la valeur du compteur retourné par le projet d’API web.

Ajouter la prise en charge de Docker Compose

  1. Dans le projet WebFrontEnd, choisissez Ajouter > Prise en charge de l’orchestrateur de conteneurs. La boîte de dialogue Options de prise en charge de Docker s’affiche.

  2. Choisissez Docker Compose.

  3. Choisissez votre système d’exploitation cible, par exemple Linux.

    Screenshot of choosing the Target OS.

    Visual Studio crée un fichier docker-compose.yml et un fichier .dockerignore dans le nœud docker-compose de la solution, et ce projet s’affiche en police gras, ce qui montre qu’il s’agit du projet de démarrage.

    Screenshot of Solution Explorer with docker-compose project added.

    Le fichier docker-compose.yml s’affiche comme suit :

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

    Le version spécifié dans la première ligne est la version du fichier Docker Compose. Normalement, vous ne devez pas le modifier, car il est utilisé par les outils pour comprendre comment interpréter le fichier.

    Le fichier .dockerignore contient les types et extensions de fichiers que Docker ne doit pas inclure dans le conteneur. Ces fichiers sont généralement associés à l’environnement de développement et au contrôle de code source et ne font pas partie de l’application ou du service que vous déployez.

    Pour plus d’informations sur les commandes en cours d’exécution, consultez la section Outils conteneur du volet de sortie. Vous pouvez voir que l’outil en ligne de commande docker-compose est utilisé pour configurer et créer les conteneurs d’exécution.

  4. Dans le projet d’API web, cliquez de nouveau avec le bouton droit sur le nœud du projet, puis choisissez Ajouter >Prise en charge de l’orchestrateur de conteneurs. Choisissez Docker Compose, puis sélectionnez le même système d’exploitation cible.

    Notes

    Dans cette étape, Visual Studio propose de créer un fichier Dockerfile. Si vous effectuez cette opération sur un projet qui dispose déjà de la prise en charge de Docker, vous êtes invité à indiquer si vous souhaitez remplacer le fichier Dockerfile existant. Si vous avez apporté des modifications à votre fichier Dockerfile que vous souhaitez conserver, choisissez non.

    Visual Studio apporte des modifications à votre fichier YML Docker Compose. Les deux services sont désormais inclus.

    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. Ajoutez le cache Redis au fichier docker.compose.yml :

    redis:
       image: redis
    

    Assurez-vous que la mise en retrait est au même niveau que les deux autres services.

  6. Le premier projet auquel vous ajoutez l’orchestration de conteneur est configuré pour être lancé lorsque vous effectuez une exécution ou un débogage. Vous pouvez configurer l’action de lancement dans les propriétés du projet Docker-Compose. Sur le nœud du projet Docker-Compose, cliquez avec le bouton droit pour ouvrir le menu contextuel, puis choisissez Propriétés ou utilisezAlt+Entrée. Par exemple, vous pouvez modifier la page chargée en personnalisant la propriété URL du service .

    Screenshot of docker-compose project properties.

  7. Appuyez sur F5. Voici ce que vous voyez lors du lancement :

    Screenshot of running web app.

  8. Vous pouvez surveiller les conteneurs à l’aide de la fenêtre Conteneurs. Si vous ne voyez pas la fenêtre, utilisez la zone de recherche, appuyez sur Ctrl+K, Ctrl+Oou appuyez sur Ctrl+Q. Sous Recherche de fonctionnalités, recherchez containers et choisissez Afficher>Autres conteneurs>Windows dans la liste.

  9. Développez le nœud Conteneurs de solutions, puis choisissez le nœud de votre projet Docker Compose pour afficher les journaux combinés sous l’onglet Journaux de cette fenêtre.

    Screenshot showing viewing the Logs tab in the Containers window.

    Vous pouvez également sélectionner le nœud d’un conteneur individuel pour afficher les journaux, les variables d’environnement, le système de fichiers et d’autres détails.

Configurer des profils de lancement

  1. Cette solution dispose d’un cache Redis, mais il n’est pas efficace de regénérer le conteneur de cache Redis chaque fois que vous démarrez une session de débogage. Pour éviter cette situation, vous pouvez configurer quelques profils de lancement. Créez un profil pour démarrer le cache Redis. Créez un deuxième profil pour démarrer les autres services. Le deuxième profil peut utiliser le conteneur de cache Redis déjà en cours d’exécution. Dans la barre de menus, vous pouvez utiliser la liste déroulante à côté du bouton Démarrer pour ouvrir un menu avec les options de débogage. Sélectionnez Gérer les paramètres de lancement de Docker Compose.

    Screenshot of Debug Manage Compose Settings menu item.

    La boîte de dialogue Gérer les paramètres de lancement de Docker Compose s’affiche. Cette boîte de dialogue vous permet de contrôler le sous-ensemble de services qui est lancé pendant une session de débogage, quels services sont lancés avec ou sans le débogueur attaché, ainsi que le service de lancement et l’URL. Consulter Démarrer un sous-ensemble de services Compose.

    Screenshot of Manage Docker Compose Launch Settings dialog box.

    Choisissez Nouveau pour créer un profil et nommez-le Start Redis. Ensuite, définissez le conteneur Redis sur Démarrer sans débogage, laissez l’autre défini sur Ne pas démarrer, puis choisissez Enregistrer.

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

    Créez ensuite un autre profil Start My Services qui ne démarre pas Redis, mais démarre les deux autres services.

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

    (Facultatif) Créez un troisième profil Start All pour tout démarrer. Vous pouvez choisir Démarrer sans débogage pour Redis.

  2. Choisissez Démarrer Redis dans la liste déroulante de la barre d’outils principale de Visual Studio, appuyez sur F5. Le conteneur Redis est généré et démarre. Vous pouvez utiliser la fenêtre Conteneurs pour voir qu’elle est en cours d’exécution. Ensuite, choisissez Démarrer mes services dans la liste déroulante et appuyez sur F5 pour les lancer. Vous pouvez maintenant maintenir le conteneur de cache Redis en cours d’exécution tout au long de nombreuses sessions de débogage suivantes. Chaque fois que vous utilisez Démarrer mes services, ces services utilisent le même conteneur de cache Redis.

Félicitations, vous exécutez une application Docker Compose avec un profil Docker Compose personnalisé.

Étapes suivantes

Examinez les options de déploiement de vos conteneurs sur Azure.

Voir aussi

Docker Compose
Outils de conteneur