Despliegue en un contenedor y Docker Hub - Creación de una API de ejemplo en C# Curso
Desplegar una aplicación .NET Core en un contenedor Docker es una habilidad crucial para los desarrolladores modernos. Los contenedores ofrecen una infraestructura inmutable, una distribución sencilla y entornos de ejecución ligeros. En esta guía en profundidad, vamos a caminar a través de la implementación de una API de muestra a un contenedor Docker, y luego empujarlo a Docker Hub, siguiendo los pasos demostrados en el video tutorial completo de Tim Corey: "Despliegue en un contenedor y Docker Hub - Creación de una API de ejemplo en C#"
Exploremos el proceso paso a paso, haciendo referencia a marcas de tiempo específicas para facilitar el seguimiento. Esta guía incluye el uso de comandos como dotnet publish, el comando docker run y términos como imagen base, imagen en tiempo de ejecución e imagen de contenedor, todos ellos conceptos importantes para desplegar una aplicación .NET mediante Docker.
Creación y comprensión de la API de ejemplo
Al principio del vídeo, Tim destaca la utilidad de una aplicación de ejemplo para aprender desarrollo web. La aplicación incluye puntos finales como /courses y /health, simula problemas del mundo real como comprobaciones de salud degradadas, y está diseñada para ejecutarse tanto en su máquina local como en un servidor remoto.
Se trata de una aplicación .NET Core (más concretamente, una API mínima ASP.NET Core) que puede ejecutarse y probarse fácilmente a través de contenedores Docker.
Cómo configurar Docker localmente
Tim comprueba que Docker está instalado en su máquina local, utilizando Docker Desktop. Observa que es posible publicar directamente en Docker Hub sin tener Docker instalado localmente, pero para la demostración, comienza con el despliegue local.
Muestra dos imágenes de Docker preinstaladas:
-
Una herramienta personal para subtítulos
- La imagen base oficial de ASP.NET Core de Microsoft: mcr.microsoft.com/dotnet/aspnet
Esta imagen de base ocupa unos 328 MB y sirve de base para nuestra imagen de contenedor. Microsoft aloja estas imágenes en su MCR (Microsoft Container Registry) y son compatibles tanto con contenedores Linux como con contenedores Windows. Para este proyecto, Linux es el sistema operativo de destino.
Publicación local en un contenedor
Tim navega hasta la carpeta del proyecto API y ejecuta el siguiente comando en la línea de comandos:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
Este comando utiliza el soporte de contenedores integrado en .NET 8 y .NET 9, que elimina la necesidad de un archivo Docker. El proceso de publicación selecciona una imagen de tiempo de ejecución adecuada y crea una imagen de contenedor independiente.
Esto es lo que ocurre bajo el capó:
-
El archivo de proyecto (.csproj) se utiliza para crear la API
-
Las dependencias se restauran mediante el comando dotnet restore
-
El resultado va a una carpeta de publicación
- Se produce un archivo DLL que se incrusta en el contenedor
La imagen resultante ocupa unos 333 MB (solo 5 MB más que la base).
Ejecutar la imagen con Docker
Una vez creada la imagen, Tim utiliza Docker Desktop para ejecutar el contenedor. Internamente, la aplicación escucha en el puerto 8080. Tim lo asigna a un puerto de host aleatorio introduciendo 0 en la configuración del puerto.
El contenedor se inicia con un nombre aleatorio (por ejemplo, elegant_hoover) y el navegador se abre para mostrar una API en funcionamiento con "Hello World" como respuesta predeterminada.
Al navegar por /courses y /health, Tim confirma que la API funciona. El punto final de comprobación de estado es útil para simular un escenario de entorno de producción.
Para ver los contenedores en ejecución, puede utilizar el comando docker ps en la CLI. Tim borra el contenedor y la imagen en ejecución para demostrar la limpieza.
Creación de un repositorio Docker Hub
A continuación, Tim pasa a la parte del despliegue en la nube. Inicia sesión en su cuenta de Docker Hub y crea un repositorio público llamado thesampleapi.
Aquí es donde la imagen Docker será empujado para que otros puedan tirar de él usando:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
Configuración del proyecto para Docker Hub
Dentro del archivo de proyecto de la API, Tim añade metadatos para definir dónde y cómo publicar la imagen Docker. Añade el siguiente bloque de código:
<ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
<ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
-
ContainerRegistry: Especifica Docker Hub como registro de destino.
-
ContainerRepository: La ruta al repositorio de Docker Hub.
- ContainerImageTags: Etiqueta la imagen para el control de versiones y la última versión.
Esto prepara la imagen para un flujo de construcción de varias etapas en el futuro, aunque Tim está manteniendo las cosas simples por ahora.
Publicación en Docker Hub
Tim vuelve a ejecutar el mismo comando de publicación:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
Al principio, el push falla porque se olvidó de guardar el archivo .csproj. Tras guardar y volver a ejecutar el comando, la imagen se carga en Docker Hub correctamente.
En Docker Hub, las etiquetas latest y 1.0.0 aparecen en el repositorio thesampleapi. Estas etiquetas permiten flexibilidad a la hora de extraer versiones específicas.
Sacar la imagen de Docker Hub
Tim demuestra cómo extraer la imagen de cualquier máquina con Docker instalado:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
Gracias al almacenamiento en caché de la capa Docker, la imagen se descarga rápidamente, puesto que la mayor parte ya existe desde la imagen base.
Para ejecutar la imagen:
docker run -p 0:8080 timcorey/thesampleapi:latest
docker run -p 0:8080 timcorey/thesampleapi:latest
Esto asigna un puerto de host aleatorio al puerto interno 8080.
Creación de una nueva versión de la imagen
Para demostrar el versionado, Tim edita el archivo .csproj para:
<ContainerImageTags>1.0.1;latest</ContainerImageTags>
<ContainerImageTags>1.0.1;latest</ContainerImageTags>
A continuación, vuelve a ejecutar el comando de publicación:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
Ahora el repositorio de Docker Hub muestra tres etiquetas:
-
1.0.0
-
1.0.1
- más reciente (ahora apunta a 1.0.1)
Tim explica que, a pesar de las múltiples etiquetas, Docker no almacena capas duplicadas, optimizando el uso del disco mediante capas distintas.
Uso de la imagen Docker para desarrollo local
Tim hace hincapié en que una vez que la imagen está en Docker Hub, se puede ejecutar en cualquier momento en cualquier máquina mediante:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
A continuación, utiliza el comando docker run para ponerlo en marcha. Cuando hayas terminado, límpialo con:
docker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the image
docker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the image
Explica que esto lo hace perfecto para el desarrollo y las pruebas bajo demanda sin sobrecargar la máquina local.
¿Que sigue?
Tim concluye mencionando el siguiente paso: desplegar esta misma API en un Servidor Privado Virtual (VPS). Se explicará cómo asignar un dominio y configurar el contenedor para que sea de acceso público.
Conclusión: De la compilación local al despliegue en la nube
Hemos utilizado la guía vídeo de Tim Corey:
-
Creación de una API .NET Core con dotnet new console
-
Uso de dotnet restore y dotnet publish para compilar y desplegar
-
Creación de un contenedor Docker sin necesidad de un Dockerfile de ejemplo
-
Subida de la imagen del contenedor a Docker Hub
-
Extracción y ejecución del contenedor mediante docker run
-
Etiquetas gestionadas y capas de imagen diferenciadas
- Preparado para entornos de producción que utilizan imágenes versionadas
Este flujo de trabajo, centrado en Docker y .NET, es perfecto para crear aplicaciones escalables, comprobables y compartibles.
