⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Utiliser des conteneurs pour le développement .NET

Prérequis

Terminez Conteneuriser une application .NET.

Aperçu

Dans cette section, vous apprendrez à mettre en place un environnement de développement pour votre application conteneurisée. Cela inclut :

  • Ajouter une base de données locale et persister les données
  • Configurer Compose pour mettre à jour automatiquement vos services Compose en cours d'exécution lorsque vous modifiez et enregistrez votre code
  • Créer un conteneur de développement contenant les outils et dépendances du SDK .NET Core

Mettre à jour l'application

Cette section utilise une branche différente du dépôt docker-dotnet-sample qui contient une application .NET mise à jour. L'application mise à jour se trouve sur la branche add-db du dépôt que vous avez cloné dans Conteneuriser une application .NET.

Pour obtenir le code mis à jour, vous devez passer à la branche add-db. Pour les modifications que vous avez apportées dans Conteneuriser une application .NET, pour cette section, vous pouvez les mettre de côté. Dans un terminal, exécutez les commandes suivantes dans le répertoire docker-dotnet-sample.

  1. Mettez de côté toutes les modifications précédentes.

    $ git stash -u
    
  2. Passez à la nouvelle branche avec l'application mise à jour.

    $ git checkout add-db
    

Dans la branche add-db, seule l'application .NET a été mise à jour. Aucune des ressources Docker n'a encore été mise à jour.

Vous devriez maintenant avoir ce qui suit dans votre répertoire docker-dotnet-sample.

├── docker-dotnet-sample/
│ ├── .git/
│ ├── src/
│ │ ├── Data/
│ │ ├── Models/
│ │ ├── Pages/
│ │ ├── Properties/
│ │ ├── wwwroot/
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ ├── myWebApp.csproj
│ │ └── Program.cs
│ ├── tests/
│ │ ├── tests.csproj
│ │ ├── UnitTest1.cs
│ │ └── Usings.cs
│ ├── .dockerignore
│ ├── .gitignore
│ ├── compose.yaml
│ ├── Dockerfile
│ ├── README.Docker.md
│ └── README.md

Ajouter une base de données locale et persister les données

Vous pouvez utiliser des conteneurs pour configurer des services locaux, comme une base de données. Dans cette section, vous mettrez à jour le fichier compose.yaml pour définir un service de base de données et un volume pour persister les données.

Ouvrez le fichier compose.yaml dans un IDE ou un éditeur de texte. Vous remarquerez qu'il contient déjà des instructions commentées pour une base de données PostgreSQL et un volume.

Ouvrez docker-dotnet-sample/src/appsettings.json dans un IDE ou un éditeur de texte. Vous remarquerez la chaîne de connexion avec toutes les informations de la base de données. Le compose.yaml contient déjà ces informations, mais elles sont commentées. Décommentez les instructions de la base de données dans le fichier compose.yaml.

Voici le fichier compose.yaml mis à jour.

services:
  server:
    build:
      context: .
      target: final
    ports:
      - 8080:8080
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
Note

Pour en savoir plus sur les instructions du fichier Compose, consultez la référence du fichier Compose.

Avant d'exécuter l'application avec Compose, notez que ce fichier Compose utilise secrets et spécifie un fichier password.txt pour contenir le mot de passe de la base de données. Vous devez créer ce fichier car il n'est pas inclus dans le dépôt source.

Dans le répertoire docker-dotnet-sample, créez un nouveau répertoire nommé db et à l'intérieur de ce répertoire, créez un fichier nommé password.txt. Ouvrez password.txt dans un IDE ou un éditeur de texte et ajoutez le mot de passe suivant. Le mot de passe doit être sur une seule ligne, sans lignes supplémentaires dans le fichier.

example

Enregistrez et fermez le fichier password.txt.

Vous devriez maintenant avoir ce qui suit dans votre répertoire docker-dotnet-sample.

├── docker-dotnet-sample/
│ ├── .git/
│ ├── db/
│ │ └── password.txt
│ ├── src/
│ ├── tests/
│ ├── .dockerignore
│ ├── .gitignore
│ ├── compose.yaml
│ ├── Dockerfile
│ ├── README.Docker.md
│ └── README.md

Exécutez la commande suivante pour démarrer votre application.

$ docker compose up --build

Ouvrez un navigateur et affichez l'application à l'adresse http://localhost:8080. Vous devriez voir une application web simple avec le texte Student name is.

L'application n'affiche pas de nom car la base de données est vide. Pour cette application, vous devez accéder à la base de données puis ajouter des enregistrements.

Ajouter des enregistrements à la base de données

Pour l'application exemple, vous devez accéder directement à la base de données pour créer des enregistrements exemples.

Vous pouvez exécuter des commandes à l'intérieur du conteneur de la base de données en utilisant la commande docker exec. Avant d'exécuter cette commande, vous devez obtenir l'ID du conteneur de la base de données. Ouvrez une nouvelle fenêtre de terminal et exécutez la commande suivante pour lister tous vos conteneurs en cours d'exécution.

$ docker container ls

Vous devriez voir une sortie comme celle-ci.

CONTAINER ID   IMAGE                  COMMAND                  CREATED              STATUS                        PORTS                    NAMES
cb36e310aa7e   docker-dotnet-server   "dotnet myWebApp.dll"    About a minute ago   Up About a minute             0.0.0.0:8080->8080/tcp   docker-dotnet-server-1
39fdcf0aff7b   postgres               "docker-entrypoint.s…"   About a minute ago   Up About a minute (healthy)   5432/tcp                 docker-dotnet-db-1

Dans l'exemple précédent, l'ID du conteneur est 39fdcf0aff7b. Exécutez la commande suivante pour vous connecter à la base de données postgres dans le conteneur. Remplacez l'ID du conteneur par votre propre ID de conteneur.

$ docker exec -it 39fdcf0aff7b psql -d example -U postgres

Et enfin, insérez un enregistrement dans la base de données.

example=# INSERT INTO "Students" ("ID", "LastName", "FirstMidName", "EnrollmentDate") VALUES (DEFAULT, 'Whale', 'Moby', '2013-03-20');

Vous devriez voir une sortie comme celle-ci.

INSERT 0 1

Fermez la connexion à la base de données et quittez le shell du conteneur en exécutant exit.

example=# exit

Vérifier que les données persistent dans la base de données

Ouvrez un navigateur et affichez l'application à l'adresse http://localhost:8080. Vous devriez voir une application web simple avec le texte Student name is Whale Moby.

Appuyez sur ctrl+c dans le terminal pour arrêter votre application.

Dans le terminal, exécutez docker compose rm pour supprimer vos conteneurs puis exécutez docker compose up pour relancer votre application.

$ docker compose rm
$ docker compose up --build

Actualisez http://localhost:8080 dans votre navigateur et vérifiez que le nom de l'étudiant a persisté, même après que les conteneurs aient été supprimés et relancés.

Appuyez sur ctrl+c dans le terminal pour arrêter votre application.

Mettre à jour automatiquement les services

Utilisez Compose Watch pour mettre à jour automatiquement vos services Compose en cours d'exécution lorsque vous modifiez et enregistrez votre code. Pour plus de détails sur Compose Watch, consultez Utiliser Compose Watch.

Ouvrez votre fichier compose.yaml dans un IDE ou un éditeur de texte, puis ajoutez les instructions Compose Watch. Voici le fichier compose.yaml mis à jour.

services:
  server:
    build:
      context: .
      target: final
    ports:
      - 8080:8080
    depends_on:
      db:
        condition: service_healthy
    develop:
      watch:
        - action: rebuild
          path: .
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt

Exécutez la commande suivante pour lancer votre application avec Compose Watch.

$ docker compose watch

Ouvrez un navigateur et vérifiez que l'application fonctionne à http://localhost:8080.

Toute modification des fichiers source de l'application sur votre machine locale sera désormais immédiatement répercutée dans le conteneur en cours d'exécution.

Ouvrez docker-dotnet-sample/src/Pages/Index.cshtml dans un IDE ou un éditeur de texte et mettez à jour le texte du nom de l'étudiant à la ligne 13 de Student name is à Student name:.

-    <p>Student Name is @Model.StudentName</p>
+    <p>Student name: @Model.StudentName</p>

Enregistrez les modifications dans Index.cshmtl puis attendez quelques secondes que l'application se reconstruise. Actualisez http://localhost:8080 dans votre navigateur et vérifiez que le texte mis à jour apparaît.

Appuyez sur ctrl+c dans le terminal pour arrêter votre application.

Créer un conteneur de développement

À ce stade, lorsque vous exécutez votre application conteneurisée, elle utilise l'image d'exécution .NET. Bien que cette petite image soit bonne pour la production, elle manque des outils et dépendances du SDK dont vous pourriez avoir besoin lors du développement. De plus, pendant le développement, vous n'aurez peut-être pas besoin d'exécuter dotnet publish. Vous pouvez utiliser des constructions multi-étapes pour construire des étapes pour le développement et la production dans le même Dockerfile. Pour plus de détails, consultez Constructions multi-étapes.

Ajoutez une nouvelle étape de développement à votre Dockerfile et mettez à jour votre fichier compose.yaml pour utiliser cette étape pour le développement local.

Voici le Dockerfile mis à jour.

# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
ARG TARGETARCH
COPY . /source
WORKDIR /source/src
RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
    dotnet publish -a ${TARGETARCH/amd64/x64} --use-current-runtime --self-contained false -o /app

FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS development
COPY . /source
WORKDIR /source/src
CMD dotnet run --no-launch-profile

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS final
WORKDIR /app
COPY --from=build /app .
ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser
USER appuser
ENTRYPOINT ["dotnet", "myWebApp.dll"]

Voici le fichier compose.yaml mis à jour.

services:
  server:
    build:
      context: .
      target: development
    ports:
      - 8080:8080
    depends_on:
      db:
        condition: service_healthy
    develop:
      watch:
        - action: rebuild
          path: .
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: ["CMD", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt

Votre application conteneurisée utilisera désormais l'image mcr.microsoft.com/dotnet/sdk:8.0-alpine, qui inclut des outils de développement comme dotnet test. Passez à la section suivante pour apprendre à exécuter dotnet test.

Résumé

Dans cette section, vous avez vu comment configurer votre fichier Compose pour ajouter une base de données locale et persister les données. Vous avez également appris à utiliser Compose Watch pour reconstruire et exécuter automatiquement votre conteneur lorsque vous mettez à jour votre code. Et enfin, vous avez appris à créer un conteneur de développement qui contient les outils et dépendances du SDK nécessaires au développement.

Informations connexes :

Prochaines étapes

Dans la section suivante, vous apprendrez à exécuter des tests unitaires en utilisant Docker.