Imágenes Docker multi-stage para .NET + Angular
node_modules en la imagen que desplegamos en producción es enviar 800 MB de herramientas que nunca se usarán en la ejecución. El build multi-stage separa lo que compila de lo que se ejecuta: obtenemos una imagen final diminuta, que contiene solo lo estrictamente necesario para el runtime.
El principio: compilar y descartar
Dockerfile multi-stage declara varios FROM . Cada FROM abre un stage aislado; solo el último stage se convierte en la imagen entregada. Copiamos selectivamente los artefactos de un stage de build hacia un stage de runtime, y todo lo demás — SDK, fuentes, cachés — se descarta.
Caché de layers: ordenar para no reconstruir todo
COPY *.csproj y luego dotnet restore antes de copiar el resto, el restore solo se vuelve a ejecutar si el .csproj cambia — no en cada modificación de un archivo C#. La misma lógica en el lado de Angular con package.json y npm ci antes del COPY de las fuentes: un cambio de código nunca reinvalida la instalación de dependencias, lo que divide los tiempos de build por diez.
Una imagen final diminuta
aspnet:9.0-noble-chiseled ) eliminan la shell, el gestor de paquetes y los binarios superfluos: superficie de ataque reducida, imagen frecuentemente por debajo de los 110 MB, ejecución como usuario no-root por defecto. Para servir el frontend de Angular, nginx alpine desempeña el papel de stage final.
dist/browser en la raíz de nginx y añadimos un try_files $uri /index.html en la configuración para el fallback SPA .
Orquestar en local con Compose
docker-compose.yml conecta los dos servicios y su red:
--target build ) y la compartición de stages, útiles para aislar una etapa de test en el pipeline CI.
Una imagen de prod solo debería contener lo que se ejecuta. El multi-stage hace que esta disciplina sea gratuita: el SDK permanece en el stage de build, nunca en lo que desplegáis .