Docker y C#: contenedorización de aplicaciones .NET
En el desarrollo de software moderno, la contenedorización se ha convertido en el estándar de facto para crear, probar e implementar aplicaciones. Docker le permite empaquetar su aplicación C# junto con todas sus dependencias en un entorno aislado: un contenedor. Esto garantiza que la aplicación funcione igual en cualquier máquina: desde el portátil del desarrollador hasta el servidor de producción en la nube.
En este artículo, analizaremos en detalle cómo contenedorizar aplicaciones .NET con Docker. Aprenderá a crear Dockerfile eficientes, utilizar compilación de múltiples etapas, trabajar con docker-compose para aplicaciones de múltiples contenedores y seguir las mejores prácticas.
¿Qué es Docker y por qué lo necesita un desarrollador de C#?
Docker es una plataforma para desarrollar, enviar y ejecutar aplicaciones en contenedores. Un contenedor es un paquete ligero, autónomo y ejecutable que contiene todo lo necesario para que la aplicación funcione: código, entorno de ejecución (runtime), herramientas del sistema, bibliotecas y configuraciones.
Para un desarrollador de C#, Docker ofrece las siguientes ventajas:
- Aislamiento del entorno — ya no es necesario configurar el entorno en cada máquina. Todas las dependencias se fijan en la imagen.
- Unificación — la aplicación funciona igual en Windows, Linux y macOS.
- Escalabilidad — es fácil ejecutar múltiples instancias de la aplicación para manejar la carga.
- Integración CI/CD — los contenedores son ideales para pipelines automáticos de compilación e implementación.
- Arquitectura de microservicios — cada servicio se puede empaquetar en un contenedor separado.
Es importante destacar que .NET Core (y los más recientes .NET 5/6/7/8) son multiplataforma y funcionan excelentemente en contenedores Linux, que son el estándar para Docker. Las aplicaciones de .NET Framework requieren contenedores Windows, lo que impone ciertas limitaciones.
Creación de un Dockerfile para una aplicación .NET
El artefacto principal para la contenedorización es el archivo Dockerfile. Contiene las instrucciones para compilar la imagen de su aplicación. Veamos un ejemplo para una Web API típica de ASP.NET Core.
Cree un archivo Dockerfile en la raíz de su proyecto:
# Etapa 1: Compilación de la aplicaciónFROM mcr.microsoft.com/dotnet/sdk:8.0 AS buildWORKDIR /src
# Copiamos el archivo del proyecto y restauramos las dependenciasCOPY ["MyApp/MyApp.csproj", "MyApp/"]RUN dotnet restore "MyApp/MyApp.csproj"
# Copiamos todo el código fuente y compilamos la aplicaciónCOPY . .WORKDIR "/src/MyApp"RUN dotnet build "MyApp.csproj" -c Release -o /app/build
# Etapa 2: Publicación de la aplicaciónFROM build AS publishRUN dotnet publish "MyApp.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Etapa 3: Imagen final para ejecuciónFROM mcr.microsoft.com/dotnet/aspnet:8.0 AS finalWORKDIR /appEXPOSE 80EXPOSE 443
# Copiamos los archivos publicados desde la etapa publishCOPY --from=publish /app/publish .
# Establecemos un usuario sin permisos de root por seguridadUSER app
ENTRYPOINT ["dotnet", "MyApp.dll"]Análisis de las instrucciones:
FROM ... AS build— usamos la imagen SDK para la compilación. Esta es la etapa de "construcción".WORKDIR— establece el directorio de trabajo.COPY— copia archivos del sistema anfitrión a la imagen.RUN dotnet restore— restaura los paquetes NuGet.RUN dotnet build— compila el proyecto.FROM ... AS publish— segunda etapa para la publicación (a menudo se combina con build).FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final— imagen final que contiene solo el runtime de ASP.NET Core. Es mucho más ligera que la imagen SDK.COPY --from=— copia los archivos publicados desde la etapa anterior.