Introduction : pourquoi le niveau avancé ?
\nLa conteneurisation d'applications C# basées sur .NET n'est plus simplement une tendance — c'est un standard industriel. Au niveau débutant, un Dockerfile basique avec FROM mcr.microsoft.com/dotnet/aspnet suffit. Cependant, dans un environnement de production, des défis apparaissent qui nécessitent une compréhension plus approfondie : minimisation de la taille de l'image, sécurité, architecture multi-conteneurs, gestion efficace de la configuration et débogage.
Cet article est destiné aux développeurs qui connaissent déjà les bases de Docker et C#, mais souhaitent passer au niveau supérieur. Nous aborderons des techniques avancées qui vous permettront de créer des images légères, sécurisées et facilement évolutives pour vos applications .NET.
\n\n1. Construction multi-étapes (Multi-stage build) : l'art des images légères
\nLe problème classique — les images .NET SDK pèsent plus de 1,5 Go. Les emporter en production est inutile et dangereux. La construction multi-étapes résout ce problème en séparant l'étape de compilation et l'étape d'exécution.
\n\nDockerfile avancé avec multi-stage
\nAu lieu de simplement copier les fichiers binaires, nous utilisons les images SDK officielles pour la compilation, puis nous copions le résultat dans une image minimale aspnet.
# Étape 1 : Compilation\nFROM mcr.microsoft.com/dotnet/sdk:8.0 AS build\nWORKDIR /app\n\n# Copier uniquement les fichiers du projet (optimisation du cache)\nCOPY src/MyApp.csproj .\nRUN dotnet restore\n\n# Copier le reste du code\nCOPY src/ .\nRUN dotnet publish -c Release -o /app/publish\n\n# Étape 2 : Runtime\nFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime\nWORKDIR /app\n\n# Ajouter un utilisateur non privilégié\nRUN adduser --disabled-password --gecos '' appuser\nUSER appuser\n\nCOPY --from=build /app/publish .\n\nEXPOSE 8080\nENV ASPNETCORE_URLS=http://+:8080\nENTRYPOINT ["dotnet", "MyApp.dll"]\nCe qui est important ici :
\n- \n
- Mise en cache des couches : d'abord, seul le fichier
.csprojest copié etdotnet restoreest exécuté. Tant que les dépendances ne changent pas, Docker utilisera le cache pour cette couche. \n - Utilisateur non privilégié :
appuser— crucial pour la sécurité en production. \n - Port 8080 : dans .NET 8, le port 8080 est utilisé par défaut, ce qui correspond aux normes cloud modernes. \n
Astuce : Compilation Trimmed et AOT
\nPour réduire encore plus la taille, utilisez Trimming (suppression du code inutilisé) ou Native AOT. Cela permet d'obtenir des images de 10 à 30 Mo.
\n# Pour ReadyToRun (R2R) et Trimming\nRUN dotnet publish -c Release -r linux-x64 --self-contained true \\\n -p:PublishTrimmed=true \\\n -p:PublishSingleFile=true \\\n -o /app/publish\nImportant : AOT impose des limitations sur la réflexion et le chargement dynamique d'assemblages. Avant de l'utiliser, assurez-vous que votre code est compatible.
\n\n2. Gestion de la configuration et des secrets
\nStocker les chaînes de connexion et les clés API à l'intérieur de l'image est une erreur grossière. Au niveau avancé, nous utilisons Docker Secrets, les variables d'environnement et la liaison avec appsettings.json.
Surcharge de appsettings via Docker
\nDans .NET, il existe un mécanisme intégré de priorités de configuration. Nous pouvons transmettre les paramètres via des variables d'environnement, qui sont automatiquement mappées aux sections de configuration.
\n// Dans le code C#\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Configuration\n .AddJsonFile("appsettings.json", optional: false)\n .AddEnvironmentVariables(); // Surcharge les valeurs du JSON\nLancement du conteneur :
\ndocker run -d -p 8080:8080 \\\n -e "ConnectionStrings__DefaultConnection=Server=db;Database=myapp;User Id=sa;Password=MyPass123!" \\\n -e "Logging__LogLevel__Default=Warning" \\\n