Dans cet article nous allons aborder :
-
La création d'une application console .NET 5
-
La conteneuriser avec Docker
-
Et la déployer sur Azure à l'aide des actions Github
Notre poste de développement se base sur un OS Windows Version 10.0.19041.1165, vous pouvez bien évidement utiliser d'autres OS.
-
Installez Visual Studio Code. (Optionnel)
-
Installez Windows Terminal. (Optionnel)
Si vous souhaitez tester le déploiement et l'intégration continue, il vous faut :
-
Un compte Azure : Compte Gratuit
-
Un compte Github : Compte Gratuit
-
Vérifiez la version de .NET installée
dotnet --version 5.0.400
dotnet --info SDK .NET (reflétant tous les fichiers global.json) : Version: 5.0.400 Commit: d61950f9bf Environnement : OS Name: Windows OS Version: 10.0.19043 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.400\ ...
-
Listez les modèles disponibles :
dotnet new --list
Nom du modèle Nom court Langue Balises Console Application console [C#],F#,VB Common/Console Class library classlib [C#],F#,VB Common/Library ... ... ... ... ASP.NET Core Web API webapi [C#],F# Web/WebAPI ASP.NET Core gRPC Service grpc [C#] Web/gRPC ... ... ... ...
-
Créez un répertoire dotnetanddocker (en minuscule) et positionnez vous dans ce répertoire
cd dotnetdocker
Remarque : Les chemins d'accès lors de l'exécution de toutes les instructions qui vont suivre, seront relatif à ce répertoire.
-
Créez l’application console
dotnet new console -f net5.0 -o app -n dotnetanddocker
Cette commande créée une application console net5 nommée dotnetanddocker dans le répertoire .\app
-
Ouvrez le code dans Visual Studio Code ou dans tout autre éditeur
code .
-
Ajoutez les lignes suivantes dans le fichier program.cs
Console.WriteLine(System.Environment.OSVersion); Console.WriteLine("Entrez pour terminer le programme"); Console.Read();
L'instruction Console.WriteLine(System.Environment.OSVersion) nous permettra de vérifier le système d'exploitation sur lequel tournera l'application.
-
Construisez et exécutez l’application
dotnet run --project .\app\dotnetanddocker.csproj
-
Publiez le binaire de l'application console dans le répertoire .\app\publier
dotnet publish -c release ./app/dotnetanddocker.csproj -o ./app/publier Microsoft (R) Build Engine version 16.11.0+0538acc04 pour .NET Copyright (C) Microsoft Corporation. Tous droits réservés. Identification des projets à restaurer... Restauration effectuée de C:\dotnetanddocker\app\dotnetanddocker.csproj (en 85 ms). dotnetanddocker -> C:\dotnetanddocker\app\bin\release\net5.0\dotnetanddocker.dll dotnetanddocker -> C:\dotnetanddocker\app\publier\
Note : Gardez bien à l'esprit le chemin d'accès ./app/publier que nous utiliserons ultérieurement pour la conteneurisation de l'application.
-
Exécutez l'application
dotnet .\app\publier\dotnetanddocker.dll
Comme vous le voyez sur l'image suivante, l'application console .NET 5 tourne à la fois sur Windows mais aussi sur Linux à partir du même binaire.
Exécution de l'application sur Linux et Windows
La conteneurisation d'une application passe par la génération d'une image qui contiendra tous les élèments nécessaires pour que l'application fonctionne.
Pour générer cette image, il nous faut un fichier texte (en régle générale nommé Dockerfile). C'est comme un script de commandes qui contient des instructions, sur l'image de base à utiliser, l'installation de l'application etc. jusqu’à obtenir l’environnement de travail dont vous avez besoin.
Introduction aux conteneurs docker avec .NET 5
FROM mcr.microsoft.com/dotnet/runtime:5.0
COPY /app/publier /app
WORKDIR /app
ENTRYPOINT [ "dotnet","dotnetandocker.dll" ]
Ici notre fichier Dockerfile est simplifié au maximum, il contient les instructions suivantes :
-
L'image de base du runtime .NET 5 à utiliser dans notre image
FROM mcr.microsoft.com/dotnet/runtime:5.0
-
La copie des binaires de l'application se trouvant sur le poste local dans le répertoire /app/publier, vers le répertoire /app qui sera crée lors de la copie
COPY /app/publier /app
-
L'instruction qui permet de se positionner dans le répertoire /app avant l'exécution des instructions qui suivent
WORKDIR /app
-
L'instruction pour exécuter l'application console
ENTRYPOINT [ "dotnet","dotnetandocker.dll" ]
Reportez-vous à la documentation officielle Docker, pour de plus amples informations.
-
Pour construire l'image il faut utiliser l'instruction docker build de la manière suivante :
docker build --tag dotnetanddocker:1.0.0 --file ./app/Dockerfile .
Option Argument Description --tag dotnetanddocker:1.0.0 Nom de l'image avec ça balise. --file ./app/Dockerfile Chemin du fichier Dockerfile. . Contexte d'exécution de la génération de l'image. Le point (.) signifie que le répertoire courant dans notre exemple c:\dotnetdocker, sera la racine d'exécution de la génération de l'image. Ceci aura une incidence capitale dans notre fichier Dockerfile, sur l'instruction de copie des binaires de l'application ou nous précisons d'aller les chercher sur /app/publier. Plus d'info ici Génération d'une image Linux
-
Listez les images sur le poste local
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE dotnetanddocker 1.0.0 71457a3d3799 2 minutes ago 186MB -
Exécutez l'application
Docker run --rm -it dotnetanddocker:1.0.0
Exécution d'un conteneur Linux
Lors de l'exécution de cette commande, un conteneur est crée.
Option Description --rm Supprime le conteneur automatiquement à la fin de son exécution. -i Exécute le conteneur en mode interactif. Cela permet au conteneur de ne pas s'arrêter automatiquement. dotnetanddocker:1.0.0 Image de base utilisée pour la création du conteneur. -
Exécutez la commande suivante, pour lister les conteneurs en cours d'exécution
Docker ps
conteneur ID IMAGE COMMAND CREATED STATUS PORTS NAMES f7d60abdf162 dotnetanddocker:1.0.0 "dotnet DotNetAndDoc…" About a minute ago Up About a minute modest_lalande
Pour créer une image et un conteneur Windows, il faut basculer Docker pour qu'il utilise Windows, comme illustré sur l'image suivante :
Basculement sur les conteneurs Windows
-
Listez les conteneurs disponibles
docker images
Logiquement la liste est vide.
REPOSITORY TAG IMAGE ID CREATED SIZE -
Ensuite, pour générer une image docker, il suffit d'exécuter les mêmes commandes que précedement
docker build --tag dotnetanddocker:1.0.0 --file ./app/Dockerfile . docker run --rm -i dotnetanddocker:1.0.0
Parfois il est nécessaire d'aller vérifier directement dans le conteneur si tous les élèments nécessaire ont bien été copiés, installés etc. Pour cela il est possible d'exécuter un shell de commande en mode interactif.
-
Tout d'abord il faut lister les conteneurs encours d'exécution pour récupèrer l'ID du conteneur qui nous intéresse
docker ps
Note: L'instruction docker ps --all permet de lister tous les conteneurs, y compris ceux qui sont arrêtés.
conteneur ID IMAGE COMMAND CREATED STATUS PORTS NAMES f7d60abdf162 dotnetanddocker:v1 "dotnet DotNetAndDoc…" About a minute ago Up About a minute modest_lalande -
Ensuite il suffit d'exécuter la commande suivante avec le bon ID
# Linux docker exec -it [conteneur ID] bash ou # Windows docker exec -it [conteneur ID] cmd
L'option -it permet d'exécuter le shell bash ou cmd dans le conteneur en mode interactif.
-
Tout d'abord il vous faut créer un nouveau repo dans Github. https://docs.github.com/en/get-started/quickstart/create-a-repo
-
Positionnez vous dans le répertoire dotnetanddocker et exécutez les commandes suivantes :
# Initialisation du nouveau repo git git init # Ajout de tous les fichiers sauf ceux définis dans le fichier .gitignore git add . # Commit des changements git commit -m "Commit Initial"
Note: Avant d'exécuter la commande git add ., il serait de bon ton de supprimer les répertoires ./app/obj, ./app/bin, ./app/publier pour éviter de les ajouter au commit initial, sinon vous pouvez ajouter le fichier .gitignore qui se trouve dans ce repo.
-
Ajoutez le repo distant github au repo local git et poussez les modifications sur le repo github
git remote add origin https://github.com/[user]/[repo].git git branch -M main git push -u origin main
Remplacez [user] et [repo] par votre nom github et le nom du repo que vous avez donné lors de la création du repo.
-
Sur le poste local exécutez les commandes Azure suivantes :
az login az account set --subscription [SUBSCRIPTION ID] # Création du groupe de ressources az group create -g [NOM DU GROUPE DE RESSOURCES] -l "Francecentral" # Création du registre de conteneurs Azure az acr create --name [NOM DU REGISTRE] --resource-group [NOM DU GROUPE DE RESSOURCES] --sku Basic --admin-enabled true --output none # Récupère le mot de passe az acr credential show --resource-group [NOM DU GROUPE DE RESSOURCES] --name [NOM DU REGISTRE] --query passwords[0].value --output tsv H96viJEVr......
Remplacez les variables entre crochets par vos propres noms.
Copiez le mot de passe, nous le réutiliserons plus tard en tant que secret avec les actions Github.
-
Création d'un principal de service et l'ajouter comme contributeur au groupe de ressources
az ad sp create-for-rbac --name [NOM DU PRINCIPAL DE SERVICE] --sdk-auth --role contributor --scopes /subscriptions/{subscription-id}/resourceGroups/[NOM DU GROUPE DE RESSOURCES]
L'option --sdk-auth, permet de récupèrer en sortie les informations de login (au format json) que nous réutiliserons par la suite dans Github Action en tant que secret.
{ "clientId": [GUID], "clientSecret": [GUID], "subscriptionId": [GUID], "tenantId": [GUID], ... }
Copiez le JSON, nous le réutiliserons plus tard avec les actions Github.
-
Sur Github, sélectionnez Actions
-
Choisir le modèle Docker Image comme point de départ
-
Remplacez par le code yaml suivant :
name: Meetup DotNet And Docker on: #push: #branches: [ main ] # Déclencheur lorsque la commande git push est exécutée. workflow_dispatch: # Déclencher manuel env: # variables RG_NAME: [NOM DU GROUPE DE RESSOURCES] ACR_NAME: [NOM DU REGISTRE] IMAGE_NAME: dotnetanddocker ACR_SERVER: [NOM DU REGISTRE].azurecr.io jobs: build: runs-on: ubuntu-latest # Agent Linux pour l'exécution du Workflow steps: - uses: actions/checkout@v2 # Action qui récupère le code du repo et le copie sur l'agent - name: Récupère .NET uses: actions/setup-dotnet@v1 # Action qui configure .NET 5 sur l'agent with: dotnet-version: 5.0.x - name: Publier le code source run: # Action qui permet d'exécuter la publication du code binaire .NET dotnet publish -c release ./app/dotnetanddocker.csproj -o ./app/publier - name: Tester le code run: | # Pas de tests dans cette démo. echo "Il faudrait tester le code !!" - name: Connexion à Azure conteneur Registry uses: docker/[email protected] # Action qui va permettre de se loguer au Registre de conteneurs Azure with: registry: ${{ env.ACR_SERVER }} username: ${{ env.ACR_NAME }} password: ${{ secrets.PASSREGISTRY }} - name: Extraire les métadonnées docker id: meta uses: docker/[email protected] # Action qui va permettre d'extraire les méta-données docker with: images: ${{ env.ACR_SERVER }}/${{ env.IMAGE_NAME }} tags: | type=semver,pattern={{version}},value=v1.0.0 - name: Construire et pousser une image Docker uses: docker/[email protected] # Action pour la génération et le déploiement de l'image sur le Registre Azure with: context: ./ file: ./app/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }}
Remplacez les variables entre crochets par vos propres noms.
Enfin appuyez sur le bouton StartCommit.
Note: Pour merger ce fichier avec votre repo local, exécutez la commande git pull.
-
Sur Github ajoutez en tant que secret les informations de login à Azure
-
De la même manière, vous allez ajouter le secret correspondant au mot de passe du registre de conteneurs Azure
-
Nom du secret : PASSREGISTRY
Collez le mot de passe du registre de conteneurs Azure.
-
Démarrez le Workflow manuellement
Les étapes contenues dans le fichier yaml s'éxecute une à une jusqu'au déploiement de l'image sur Azure.
Note: Si vous souhaitez que le déclenchement du workflow démarre lorsque la commande git push est invoquée, décommentez les lignes, push: et branches: [ main ] du fichier yaml.
-
Vérifiez sur le portail Azure que l'image dotnetanddocker est bien présente
-
Testez l'application
13.1 Se connecter au registre de conteneur Azure
docker login [NOM DU REGISTRE].azurecr.io -u [NOM DU REGISTRE] -p [MOT DE PASSE DU REGISTRE]
13.2 Exécutez l'application
docker run -it [NOM DU REGISTRE].azurecr.io/dotnetanddocker:1.0.0
Si l'image n'est pas présente sur le poste, elle se télécharge avant d'exécuter le conteneur.
Vue d'ensemble des commandes dotnet
Microservices .NET : Architecture pour les applications .NET en conteneur
Introduction aux conteneurs docker avec .NET 5
Référence des commandes az CLI