Outils de conteneur Visual Studio avec ASP.NET Core

Visual Studio 2017 et versions ultérieures prennent en charge la génération, le débogage et l’exécution d’applications ASP.NET Core conteneurisées ciblant .NET Core. Les conteneurs Windows et Linux sont pris en charge.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Prérequis

Installation et configuration

Pour l’installation Docker, commencez par passer en revue les informations contenues dans Docker for Windows: What to know before you install. Ensuite, installez Docker pour Windows.

Il est nécessaire de configurer les lecteurs partagés dans Docker pour Windows pour prendre en charge le mappage de volume et le débogage. Cliquez avec le bouton droit sur l’icône Docker de la zone de notification, sélectionnez Paramètres, puis Lecteurs partagés. Sélectionnez le lecteur où Docker stocke les fichiers. Cliquez sur Appliquer.

Dialog to select local C drive sharing for containers

Conseil

Visual Studio 2017 versions 15.6 et ultérieures sollicitent l’utilisateur quand les lecteurs partagés ne sont pas configurés.

Ajouter un projet à un conteneur Docker

Pour mettre en conteneur un projet ASP.NET Core, le projet doit cibler .NET Core. Les conteneurs Linux et Windows sont pris en charge.

Quand vous ajoutez la prise en charge de Docker à un projet, choisissez un conteneur Windows ou Linux. L’hôte Docker doit exécuter le même type de conteneur. Pour changer le type de conteneur dans l’instance de Docker en cours d’exécution, cliquez avec le bouton droit sur l’icône Docker de la zone de notification, puis choisissez Basculer vers les conteneurs Windows... ou Basculer vers les conteneurs Linux....

Nouvelle application

Quand vous créez une application avec les modèles de projet Application web ASP.NET Core, cochez la case Activer la prise en charge de Docker :

Enable Docker Support checkbox

Si la version cible du .NET Framework est .NET Core, la liste déroulante OS (SE) permet la sélection d’un type de conteneur.

Application existante

Pour les projets ASP.NET Core ciblant .NET Core, il existe deux options pour ajouter la prise en charge de Docker via les outils. Ouvrez le projet dans Visual Studio et choisissez l’une des options suivantes :

  • Sélectionnez Prise en charge de Docker dans le menu Projet.
  • Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions, puis sélectionnez Ajouter>Prise en charge de Docker.

Les outils de conteneur Visual Studio ne prennent pas en charge l’ajout de Docker à un projet ASP.NET Core existant ciblant le .NET Framework.

Vue d’ensemble du fichier Dockerfile

Un fichier Dockerfile, la recette de la création d’une image Docker finale, est ajouté à la racine du projet. Reportez-vous à Informations de référence sur Dockerfile pour comprendre les commandes qu’il contient. Ce fichier Dockerfile spécifique utilise une build en plusieurs étapes avec quatre différentes étapes de build nommées :

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 AS base
WORKDIR /app
EXPOSE 59518
EXPOSE 44364

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build
WORKDIR /src
COPY HelloDockerTools/HelloDockerTools.csproj HelloDockerTools/
RUN dotnet restore HelloDockerTools/HelloDockerTools.csproj
COPY . .
WORKDIR /src/HelloDockerTools
RUN dotnet build HelloDockerTools.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish HelloDockerTools.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]

L’image Dockerfile précédente comprend le runtime ASP.NET Core et des packages NuGet. Les packages sont compilés juste-à-temps (JIT) pour améliorer les performances de démarrage.

Quand la case Configurer pour HTTPS de la boîte de dialogue du nouveau projet est cochée, le fichier Dockerfile expose deux ports. Un port est utilisé pour le trafic HTTP tandis que l’autre est utilisé pour HTTPS. Si la case n’est pas cochée, un seul port (80) est exposé pour le trafic HTTP.

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY HelloDockerTools/HelloDockerTools.csproj HelloDockerTools/
RUN dotnet restore HelloDockerTools/HelloDockerTools.csproj
COPY . .
WORKDIR /src/HelloDockerTools
RUN dotnet build HelloDockerTools.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish HelloDockerTools.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]

L’image Dockerfile précédente comprend les packages NuGet ASP.NET Core, qui ont été compilés juste-à-temps (JIT) pour améliorer les performances de démarrage.

Ajouter la prise en charge des orchestrateurs de conteneurs à une application

Visual Studio 2017 version 15.7 ou antérieure prend en charge Docker Compose en tant que solution d’orchestration de conteneurs unique. Les artefacts Docker Compose sont ajoutés via Ajouter>Prise en charge de Docker.

Visual Studio 2017 version 15.8 ou ultérieure ajoute une solution d’orchestration seulement si cela lui est demandé. Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions, puis sélectionnez Ajouter>Prise en charge de l’orchestrateur de conteneurs. Les choix suivants sont disponibles :

Docker Compose

Les outils de conteneur Visual Studio ajoutent un projet docker-compose à la solution avec les fichiers suivants :

  • docker-.dcproj : Fichier représentant le projet. Comprend un élément <DockerTargetOS> spécifiant le système d’exploitation à utiliser.
  • .dockerignore : Répertorie les modèles de fichiers et de répertoires à exclure pendant la génération d’un contexte de build.
  • docker-compose.yml : Fichier Docker Compose de base utilisé pour définir la collection d’images générées et exécutées avec docker-compose build et docker-compose run, respectivement.
  • docker-compose.override.yml : Fichier facultatif, lu par Docker Compose, avec les remplacements de configuration pour les services. Visual Studio exécute docker-compose -f "docker-compose.yml" -f "docker-compose.override.yml" pour fusionner ces fichiers.

Le fichier docker-compose.yml référence le nom de l’image créée pendant l’exécution du projet :

version: '3.4'

services:
  hellodockertools:
    image: ${DOCKER_REGISTRY}hellodockertools
    build:
      context: .
      dockerfile: HelloDockerTools/Dockerfile

Dans l’exemple précédent, image: hellodockertools génère l’image hellodockertools:dev quand l’application est exécutée en mode débogage. L’image hellodockertools:latest est générée quand l’application est exécutée en mode mise en production.

En guise de préfixe, ajoutez au nom de l’image le nom d’utilisateur Docker Hub (par exemple, dockerhubusername/hellodockertools) si l’image est destinée à être envoyée (push) au Registre. Vous pouvez aussi changer le nom de l’image pour inclure l’URL de Registre privé (par exemple, privateregistry.domain.com/hellodockertools) en fonction de la configuration.

Si vous souhaitez un autre comportement basé sur la configuration de build (par exemple, Debug ou Release), ajoutez des fichiers docker-compose propres à la configuration. Les fichiers doivent être nommés en fonction de la configuration de build (par exemple, docker-compose.vs.debug.yml et docker-compose.vs.release.yml), et placés dans le même emplacement que le fichier docker-compose-override.yml.

À l’aide des fichiers de substitution spécifiques à la configuration, vous pouvez spécifier différents paramètres de configuration (par exemple, des variables d’environnement ou des points d’entrée) pour les configurations de build Debug et Release.

Pour que Docker Compose affiche une option pour exécuter dans Visual Studio, le projet Docker doit être le projet de démarrage.

Service Fabric

En plus des prérequis de base, la solution d’orchestration Service Fabric impose les prérequis suivants :

Service Fabric ne prend pas en charge les conteneurs Linux s’exécutant dans le cluster de développement local sur Windows. Si le projet utilise déjà un conteneur Linux, Visual Studio vous invite à basculer vers des conteneurs Windows.

Les outils de conteneur Visual Studio effectuent les tâches suivantes :

  • Ajoute un projet Application Service Fabric<Application>nom_projet.

  • Ajoute un fichier Dockerfile et un fichier .dockerignore au projet ASP.NET Core. S’il existe déjà un fichier Dockerfile dans le projet ASP.NET Core, il est renommé Dockerfile.original. Un nouveau fichier Dockerfile, semblable au suivant, est créé :

    # See https://aka.ms/containerimagehelp for information on how to use Windows Server 1709 containers with Service Fabric.
    # FROM microsoft/aspnetcore:2.0-nanoserver-1709
    FROM microsoft/aspnetcore:2.0-nanoserver-sac2016
    ARG source
    WORKDIR /app
    COPY ${source:-obj/Docker/publish} .
    ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]
    
  • Ajoute un élément <IsServiceFabricServiceProject> au fichier .csproj du projet ASP.NET Core :

    <IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
    
  • Ajoute un dossier PackageRoot au projet ASP.NET Core. Le dossier comprend le manifeste de service et les paramètres du nouveau service.

Pour plus d’informations, consultez Déployer une application .NET dans un conteneur Windows vers Azure Service Fabric.

Débogage

Sélectionnez Docker dans la liste déroulante de débogage dans la barre d’outils et démarrez le débogage de l’application. La vue Docker de la fenêtre Sortie affiche les actions suivantes qui se déroulent :

  • La balise 2.1-aspnetcore-runtime de l’image de runtime microsoft/dotnet est acquise (si elle ne se trouve pas déjà dans le cache). L’image installe les runtimes ASP.NET Core et .NET Core et les bibliothèques associées. Elle est optimisée pour l’exécution des applications ASP.NET Core en production.
  • La variable d’environnement ASPNETCORE_ENVIRONMENT a la valeur Development dans le conteneur.
  • Deux ports attribués dynamiquement sont exposés : un pour HTTP et l’autre pour HTTPS. Le port attribué à localhost peut être interrogé avec la commande docker ps.
  • L’application est copiée dans le conteneur.
  • Le navigateur par défaut est lancé avec le débogueur attaché au conteneur, en utilisant le port attribué dynamiquement.

L’image Docker obtenue de l’application est marquée avec la balise dev. L’image est basée sur la balise 2.1-aspnetcore-runtime de l’image de base microsoft/dotnet. Exécutez la commande docker images dans la fenêtre Console du Gestionnaire de package. Les images sur la machine s’affichent :

REPOSITORY        TAG                     IMAGE ID      CREATED         SIZE
hellodockertools  dev                     d72ce0f1dfe7  30 seconds ago  255MB
microsoft/dotnet  2.1-aspnetcore-runtime  fcc3887985bb  6 days ago      255MB
  • L’image d’exécution microsoft/aspnetcore est acquise (si elle n’est pas déjà dans le cache).
  • La variable d’environnement ASPNETCORE_ENVIRONMENT a la valeur Development dans le conteneur.
  • Le port 80 est exposé et mappé à un port attribué dynamiquement pour localhost. Le port est déterminé par l’hôte Docker et peut être interrogé avec la commande docker ps.
  • L’application est copiée dans le conteneur.
  • Le navigateur par défaut est lancé avec le débogueur attaché au conteneur, en utilisant le port attribué dynamiquement.

L’image Docker obtenue de l’application est marquée avec la balise dev. L’image est basée sur l’image de base microsoft/aspnetcore. Exécutez la commande docker images dans la fenêtre Console du Gestionnaire de package. Les images sur la machine s’affichent :

REPOSITORY            TAG  IMAGE ID      CREATED        SIZE
hellodockertools      dev  5fafe5d1ad5b  4 minutes ago  347MB
microsoft/aspnetcore  2.0  c69d39472da9  13 days ago    347MB

Notes

L’image dev n’inclut pas le contenu de l’application, car les configurations Debug utilisent le montage de volume pour fournir l’expérience itérative. Pour placer une image, utilisez la configuration release.

Exécutez la commande docker ps dans la console du Gestionnaire de package. Notez que l’application s’exécute à l’aide du conteneur :

CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                   NAMES
baf9a678c88d        hellodockertools:dev   "C:\\remote_debugge..."   21 seconds ago      Up 19 seconds       0.0.0.0:37630->80/tcp   dockercompose4642749010770307127_hellodockertools_1

Modifier & Continuer

Les modifications apportées à des fichiers statiques et à des vues Razor sont automatiquement mises à jour sans qu’une étape de compilation ne soit nécessaire. Apportez la modification, enregistrez et actualisez le navigateur pour afficher la mise à jour.

Les modifications de fichiers de code nécessitent une compilation et un redémarrage de Kestrel au sein du conteneur. Après avoir effectué la modification, utilisez CTRL+F5 pour exécuter le processus et démarrer l’application au sein du conteneur. Le conteneur Docker n’est pas regénéré ni arrêté. Exécutez la commande docker ps dans la console du Gestionnaire de package. Notez que le conteneur d’origine est toujours en cours d’exécution comme 10 minutes auparavant :

CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                   NAMES
baf9a678c88d        hellodockertools:dev   "C:\\remote_debugge..."   10 minutes ago      Up 10 minutes       0.0.0.0:37630->80/tcp   dockercompose4642749010770307127_hellodockertools_1

Publier des images Docker

Une fois terminé le cycle de développement et de débogage de l’application, les outils de conteneur Visual Studio aident à créer l’image de production de l’application. Changez la liste déroulante de configuration en Release et générez l’application. Les outils obtiennent l’image de compilation/publication auprès de Docker Hub (si elle ne se trouve pas déjà dans le cache). Une image est produite avec la balise latest, qui peut être envoyée (push) au Registre privé ou à Docker Hub.

Exécutez la commande docker images dans la console du Gestionnaire de package pour afficher la liste des images. Une sortie similaire à la suivante s’affiche à l’écran :

REPOSITORY        TAG                     IMAGE ID      CREATED             SIZE
hellodockertools  latest                  e3984a64230c  About a minute ago  258MB
hellodockertools  dev                     d72ce0f1dfe7  4 minutes ago       255MB
microsoft/dotnet  2.1-sdk                 9e243db15f91  6 days ago          1.7GB
microsoft/dotnet  2.1-aspnetcore-runtime  fcc3887985bb  6 days ago          255MB
REPOSITORY                  TAG     IMAGE ID      CREATED         SIZE
hellodockertools            latest  cd28f0d4abbd  12 seconds ago  349MB
hellodockertools            dev     5fafe5d1ad5b  23 minutes ago  347MB
microsoft/aspnetcore-build  2.0     7fed40fbb647  13 days ago     2.02GB
microsoft/aspnetcore        2.0     c69d39472da9  13 days ago     347MB

Les images microsoft/aspnetcore-build et microsoft/aspnetcore répertoriées dans la sortie précédente sont remplacées par des images microsoft/dotnet à compter de .NET Core 2.1. Pour plus d’informations, consultez l’annonce de migration des dépôts Docker.

Notes

La commande docker images retourne des images intermédiaires avec des noms de dépôt et des balises identifiées comme <none> (non répertoriées ci-dessus). Ces images sans nom sont produites par la build en plusieurs étapesDockerfile. Elles améliorent l’efficacité de la création de l’image finale ; seules les couches nécessaires sont regénérées en cas de modifications. Quand les images intermédiaires ne sont plus nécessaires, supprimez-les à l’aide de la commande docker rmi.

Vous pourriez vous attendre à ce que l’image de production ou de publication ait une taille inférieure à l’image de développement. En raison de l’utilisation du mappage de volume, le débogueur et l’application étaient exécutés à partir de l’ordinateur local et non dans le conteneur. L’image latest a empaqueté le code de l’application nécessaire pour l’exécuter sur un ordinateur hôte. Le delta correspond donc à la taille du code de l’application.

Ressources supplémentaires