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.
Ne sélectionnez pasActiver la prise en charge de Docker. Vous ajoutez la prise en charge de Docker ultérieurement dans le processus.
Remarque
Dans Visual Studio 2022 17.2 et versions ultérieures, vous pouvez utiliser Azure Functions pour ce projet à la place.
Ne sélectionnez pasActiver la prise en charge de Docker. Vous ajoutez la prise en charge de Docker ultérieurement dans le processus.
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.
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.Ajoutez la prise en charge pour Cache Redis. Ajoutez le package NuGet
Microsoft.Extensions.Caching.StackExchangeRedis
(nonStackExchange.Redis
). Dans Program.cs, ajoutez les lignes suivantes, juste avantvar 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"; });
Ajoutez des directives using dans Program.cs pour
Microsoft.Extensions.Caching.Distributed
etMicrosoft.Extensions.Caching.StackExchangeRedis
.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;
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
Dans le projet
WebFrontEnd
, ouvrez le fichier Index.cshtml.cs, puis remplacez la méthodeOnGet
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.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>
(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
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.Choisissez Docker Compose.
Choisissez votre système d’exploitation cible, par exemple Linux.
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.
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.
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
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 .
Voici ce que vous voyez lors du lancement (version .NET Core 2.x) :
L’application web pour .NET 3.1 affiche les données météorologiques au format JSON.
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.
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.
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.
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é.
Dans le projet
WebFrontEnd
, ouvrez le fichier Index.cshtml.cs, puis remplacez la méthodeOnGet
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.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
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.Choisissez Docker Compose.
Choisissez votre système d’exploitation cible, par exemple Linux.
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.
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.
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
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.
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 .
Appuyez sur F5. Voici ce que vous voyez lors du lancement :
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.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.
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
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.
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.
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.Créez ensuite un autre profil
Start My Services
qui ne démarre pas Redis, mais démarre les deux autres services.(Facultatif) Créez un troisième profil
Start All
pour tout démarrer. Vous pouvez choisir Démarrer sans débogage pour Redis.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.