Images Docker multi-stage pour .NET + Angular
node_modules dans l'image qu'on déploie en prod, c'est expédier 800 Mo d'outillage qui ne servira jamais à l'exécution. Le build multi-stage sépare ce qui compile de ce qui tourne : on obtient une image finale minuscule, ne contenant que le strict nécessaire au runtime.
Le principe : compiler puis jeter
Dockerfile multi-stage déclare plusieurs FROM . Chaque FROM ouvre un stage isolé ; seul le dernier stage devient l'image livrée. On copie sélectivement les artefacts d'un stage de build vers un stage de runtime, et tout le reste — SDK, sources, caches — est abandonné.
Cache de layers : ordonner pour ne pas tout reconstruire
COPY *.csproj puis dotnet restore avant de copier le reste, le restore n'est rejoué que si le .csproj change — pas à chaque modification d'un fichier C#. Même logique côté Angular avec package.json et npm ci avant le COPY des sources : un changement de code ne réinvalide jamais l'install des dépendances, ce qui divise les temps de build par dix.
Une image finale minuscule
aspnet:9.0-noble-chiseled ) suppriment shell, gestionnaire de paquets et binaires superflus : surface d'attaque réduite, image souvent sous les 110 Mo, exécution en utilisateur non-root par défaut. Pour servir le front Angular, nginx alpine joue le rôle de stage final.
dist/browser dans la racine nginx et on ajoute un try_files $uri /index.html dans la conf pour le fallback SPA .
Orchestrer en local avec Compose
docker-compose.yml câble les deux services et leur réseau :
--target build ) et le partage de stages, utiles pour isoler une étape de test dans le pipeline CI.
Une image de prod ne devrait contenir que ce qui s'exécute. Le multi-stage rend cette discipline gratuite : le SDK reste dans le stage de build, jamais dans ce que vous déployez .