🐳 Docker para desplegar aplicaciones en Azure y AWS ☁️

¿Alguna vez una aplicación te ha funcionado perfectamente en tu ordenador, pero al subirla a otro entorno empieza a fallar? Este es uno de los problemas más comunes en desarrollo backend y cloud.

A veces el fallo no está en el código, sino en el entorno: versiones distintas de .NET, dependencias que faltan, variables de entorno mal configuradas, puertos incorrectos o diferencias entre sistemas operativos.

Aquí es donde entra Docker. Gracias a la contenerización, podemos empaquetar nuestra aplicación junto con todo lo necesario para ejecutarla. Así conseguimos que funcione de forma mucho más consistente en local, en Azure, en AWS o en cualquier entorno compatible con contenedores.

En este post vamos a crear una API sencilla con ASP.NET Core, la vamos a contenerizar con Docker y la dejaremos preparada para desplegarla en servicios cloud como Azure y AWS.


🎯 ¿Qué problema vamos a resolver?

El objetivo principal es responder a esta pregunta:

¿Cómo podemos empaquetar una aplicación ASP.NET Core para ejecutarla de forma consistente en local, Azure y AWS?

Para resolverlo vamos a seguir este camino:

  • ✅ Crear una API sencilla en ASP.NET Core.
  • ✅ Añadir endpoints básicos de prueba.
  • ✅ Crear un archivo Dockerfile.
  • ✅ Construir una imagen Docker.
  • ✅ Ejecutar el contenedor en local.
  • ✅ Preparar la imagen para Azure.
  • ✅ Preparar la imagen para AWS.
  • ✅ Revisar problemas comunes y recomendaciones.

🧠 Conceptos importantes antes de empezar

Antes de meternos con comandos, conviene tener claros algunos conceptos:

  • 🐳 Docker: plataforma que permite crear, ejecutar y gestionar contenedores.
  • 📦 Imagen Docker: plantilla que contiene la aplicación y todo lo necesario para ejecutarla.
  • 🚀 Contenedor: instancia en ejecución de una imagen Docker.
  • 📝 Dockerfile: archivo con las instrucciones necesarias para construir una imagen.
  • ☁️ Registro de contenedores: lugar donde se almacenan imágenes Docker, como Azure Container Registry o Amazon ECR.
  • 🔐 Variables de entorno: valores de configuración que pueden cambiar según el entorno sin modificar el código.

🧰 Requisitos previos

Para seguir este ejemplo necesitaremos tener instalado o configurado lo siguiente:

  • ✅ .NET SDK.
  • ✅ Docker Desktop.
  • ✅ Visual Studio Code o un editor similar.
  • ✅ Una cuenta de Azure.
  • ✅ Una cuenta de AWS.
  • ✅ Azure CLI.
  • ✅ AWS CLI.
  • ✅ Conocimientos básicos de terminal.

🛠️ Paso 1: Crear una API en ASP.NET Core

Lo primero será crear una API sencilla con .NET. Abrimos una terminal y ejecutamos:

dotnet new webapi -n DockerCloudDemo.Api
cd DockerCloudDemo.Api

Después ejecutamos el proyecto para comprobar que funciona correctamente:

dotnet run

Si todo está bien, podremos abrir Swagger en el navegador. La URL dependerá del puerto que indique la consola, pero normalmente será similar a esta:

https://localhost:5001/swagger

En este punto ya tenemos una API funcionando en local, pero todavía depende de nuestro entorno de desarrollo.


🔎 Paso 2: Crear endpoints de prueba

Para este tutorial no necesitamos una base de datos ni una API demasiado compleja. El objetivo es comprobar que la aplicación funciona dentro de Docker y que después puede ejecutarse en la nube.

Podemos dejar nuestro archivo Program.cs con dos endpoints sencillos:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapGet("/", () => "API ejecutándose correctamente desde Docker 🐳");
app.MapGet("/health", () => Results.Ok(new
{
    status = "Healthy",
    environment = app.Environment.EnvironmentName,
    date = DateTime.UtcNow
}));
app.Run();

El endpoint / nos sirve para comprobar rápidamente que la API responde.

El endpoint /health funciona como una comprobación técnica del estado de la aplicación.

Al entrar en /health, deberíamos obtener una respuesta parecida a esta:

{
  "status": "Healthy",
  "environment": "Production",
  "date": "2026-06-05T16:58:18.7080119Z"
}
💡 Nota: Este endpoint no devuelve datos de negocio. Solo indica que la API está funcionando correctamente.

📄 Paso 3: Crear el Dockerfile

Ahora creamos un archivo llamado Dockerfile en la raíz del proyecto. Es importante que se llame exactamente así, sin extensión.

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY DockerCloudDemo.Api.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 8080
ENV ASPNETCORE_URLS=http://+:8080
ENTRYPOINT ["dotnet", "DockerCloudDemo.Api.dll"]

Este Dockerfile utiliza una construcción en dos fases:

  • 🔨 Fase build: usa el SDK de .NET para restaurar dependencias y publicar la aplicación.
  • 🏃 Fase runtime: usa una imagen más ligera para ejecutar la aplicación ya publicada.
✅ Ventaja: al usar una construcción en varias fases, la imagen final es más ligera y más adecuada para producción.

🧹 Paso 4: Crear el archivo .dockerignore

También es recomendable crear un archivo .dockerignore. Su función es evitar que Docker copie archivos innecesarios dentro de la imagen.

bin/
obj/
.vscode/
.git/
.gitignore
Dockerfile
docker-compose.yml

Con esto conseguimos una construcción más limpia y rápida.


📦 Paso 5: Construir la imagen Docker

Desde la carpeta donde está el Dockerfile, ejecutamos:

docker build -t dockerclouddemo-api .

Este comando construye la imagen y le asigna el nombre dockerclouddemo-api.

Podemos comprobar que la imagen se ha creado correctamente con:

docker images
⚠️ Importante: el punto final del comando docker build indica el contexto de construcción. No lo olvides.

🚀 Paso 6: Ejecutar el contenedor en local

Ahora ejecutamos la imagen como contenedor:

docker run -d -p 8080:8080 --name dockerclouddemo-container dockerclouddemo-api

Explicación rápida del comando:

  • -d: ejecuta el contenedor en segundo plano.
  • -p 8080:8080: conecta el puerto 8080 del ordenador con el puerto 8080 del contenedor.
  • --name dockerclouddemo-container: asigna un nombre al contenedor.
  • dockerclouddemo-api: indica la imagen que queremos ejecutar.

Después podemos probar la API en:

http://localhost:8080

Y el endpoint de salud en:

http://localhost:8080/health

Si todo funciona correctamente, la API ya está ejecutándose dentro de Docker. 🎉


🛑 Paso 7: Detener y eliminar el contenedor

Cuando terminemos las pruebas, podemos detener el contenedor con:

docker stop dockerclouddemo-container

Para eliminarlo:

docker rm dockerclouddemo-container

Y si queremos eliminar también la imagen:

docker rmi dockerclouddemo-api

☁️ Paso 8: Preparar la imagen para Azure

Para desplegar una imagen Docker en Azure, una opción habitual es usar Azure Container Registry junto con Azure Container Apps.

Primero iniciamos sesión en Azure:

az login

Creamos un grupo de recursos:

az group create --name rg-docker-demo --location westeurope

Creamos un Azure Container Registry:

az acr create --resource-group rg-docker-demo --name acrdockerdemo123 --sku Basic

Iniciamos sesión en el registro:

az acr login --name acrdockerdemo123

Etiquetamos la imagen local con el nombre del registro:

docker tag dockerclouddemo-api acrdockerdemo123.azurecr.io/dockerclouddemo-api:v1

Subimos la imagen:

docker push acrdockerdemo123.azurecr.io/dockerclouddemo-api:v1

Con esto, nuestra imagen ya está disponible en Azure Container Registry.


🌐 Paso 9: Desplegar en Azure Container Apps

Creamos el entorno de Container Apps:

az containerapp env create --name env-docker-demo --resource-group rg-docker-demo --location westeurope

Después desplegamos la aplicación:

az containerapp create --name ca-docker-demo --resource-group rg-docker-demo --environment env-docker-demo --image acrdockerdemo123.azurecr.io/dockerclouddemo-api:v1 --target-port 8080 --ingress external --registry-server acrdockerdemo123.azurecr.io

Al terminar, Azure generará una URL pública para acceder a la aplicación.

Podemos consultar la URL con:

az containerapp show --name ca-docker-demo --resource-group rg-docker-demo --query properties.configuration.ingress.fqdn

Una vez obtenida la URL, probamos:

https://url-generada-por-azure/

Y también:

https://url-generada-por-azure/health
💡 Consejo: si el endpoint /health responde correctamente, significa que el contenedor está levantado y la API funciona en Azure.

🟧 Paso 10: Preparar la imagen para AWS

En AWS, una opción habitual es subir la imagen a Amazon Elastic Container Registry, también conocido como Amazon ECR.

Primero configuramos AWS CLI:

aws configure

Creamos un repositorio en Amazon ECR:

aws ecr create-repository --repository-name dockerclouddemo-api

El comando devolverá información del repositorio, incluyendo una URL parecida a esta:

123456789012.dkr.ecr.eu-west-1.amazonaws.com/dockerclouddemo-api

Iniciamos sesión en ECR:

aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.eu-west-1.amazonaws.com

Etiquetamos la imagen:

docker tag dockerclouddemo-api:latest 123456789012.dkr.ecr.eu-west-1.amazonaws.com/dockerclouddemo-api:v1

Subimos la imagen:

docker push 123456789012.dkr.ecr.eu-west-1.amazonaws.com/dockerclouddemo-api:v1

Con esto, nuestra imagen ya está disponible en Amazon ECR.


🚢 Paso 11: Opciones de despliegue en AWS

Una vez la imagen está subida a ECR, podemos desplegarla de varias formas:

  • 🟧 AWS App Runner: opción sencilla para ejecutar aplicaciones web contenerizadas sin configurar servidores manualmente.
  • 🚢 Amazon ECS con Fargate: opción más avanzada y escalable para ejecutar contenedores sin administrar máquinas EC2 directamente.
  • 🌱 AWS Elastic Beanstalk: opción guiada para desplegar aplicaciones y gestionar entornos de forma más sencilla.

Para un primer videotutorial, AWS App Runner puede ser la opción más sencilla. Para un enfoque más profesional y escalable, ECS con Fargate es una alternativa muy completa.


🔐 Paso 12: Variables de entorno

En aplicaciones reales no deberíamos guardar configuraciones sensibles dentro del código ni dentro de la imagen Docker.

Por ejemplo, cadenas de conexión, claves de API o secretos deberían gestionarse con variables de entorno o servicios específicos como Azure Key Vault o AWS Secrets Manager.

En Docker podemos pasar variables de entorno así:

docker run -d -p 8080:8080 -e ASPNETCORE_ENVIRONMENT=Production --name dockerclouddemo-container dockerclouddemo-api

En Azure y AWS estas variables se pueden configurar desde el portal o mediante CLI.

🚨 Importante: nunca guardes contraseñas, tokens o cadenas de conexión sensibles dentro del Dockerfile ni dentro del repositorio de GitHub.

✅ Comprobaciones finales

Antes de dar el despliegue por terminado, conviene revisar lo siguiente:

  • ✅ La imagen se construye correctamente.
  • ✅ El contenedor funciona en local.
  • ✅ El endpoint /health responde correctamente.
  • ✅ La imagen se puede subir al registro de contenedores.
  • ✅ La aplicación arranca en Azure.
  • ✅ La aplicación arranca en AWS.
  • ✅ No se han incluido secretos dentro del código.
  • ✅ El puerto configurado en Docker coincide con el puerto configurado en la nube.

🧱 Problemas encontrados

Uno de los problemas más frecuentes al trabajar con Docker es configurar mal los puertos. Puede que la aplicación esté escuchando en el puerto 8080 dentro del contenedor, pero nosotros intentemos acceder por otro puerto desde el navegador.

Otro problema habitual es olvidar la variable ASPNETCORE_URLS. Si la aplicación no escucha correctamente en http://+:8080, puede funcionar en local con dotnet run, pero fallar dentro del contenedor.

También pueden aparecer errores al subir imágenes a Azure Container Registry o Amazon ECR si no hemos iniciado sesión correctamente con az acr login o con aws ecr get-login-password.

En AWS, un error común es usar una región diferente entre el repositorio ECR y el comando de login. Por ejemplo, crear el repositorio en eu-west-1 pero intentar iniciar sesión en otra región.


💡 Recomendaciones

  • 🧪 Probar siempre la imagen en local antes de subirla a la nube.
  • 🏷️ Usar etiquetas de versión como v1, v2 o el identificador del commit.
  • 🧹 Mantener el Dockerfile lo más limpio posible.
  • 📦 Usar construcción en varias fases para reducir el tamaño de la imagen.
  • 🙈 Añadir un archivo .dockerignore.
  • 🔐 No guardar secretos dentro del código ni del repositorio.

💬 Posibles debates

Docker facilita mucho el despliegue de aplicaciones, pero también abre algunas preguntas interesantes:

  • 🤔 ¿Es mejor desplegar una aplicación contenerizada en Azure Container Apps o en Azure App Service?
  • 🤔 ¿En AWS conviene más usar App Runner, ECS con Fargate o Elastic Beanstalk?
  • 🤔 ¿Tiene sentido usar Docker para aplicaciones pequeñas o solo aporta valor en proyectos medianos y grandes?
  • 🤔 ¿Qué estrategia de versionado de imágenes deberíamos usar en un entorno profesional?

Estas preguntas dependen del tipo de aplicación, del equipo, del presupuesto y de las necesidades de escalabilidad.


🏁 Conclusión

La contenerización con Docker permite empaquetar una aplicación junto con sus dependencias para ejecutarla de forma consistente en distintos entornos.

En este post hemos visto cómo crear una API con ASP.NET Core, añadir un Dockerfile, construir una imagen, ejecutar un contenedor en local y preparar esa imagen para despliegues en Azure y AWS.

Gracias a Docker, podemos reducir problemas típicos de configuración entre entornos y facilitar el paso de desarrollo a producción.

En definitiva, Docker es una herramienta clave para cualquier desarrollador Full Stack que quiera trabajar con despliegues modernos en la nube. 🚀


👤 Datos del autor

Autor/a: Rodrigo Ramírez López

Máster: Desarrollo Full Stack + Arquitecturas Cloud

Centro: Tajamar Tech

Año académico: 2025-2026

Código / recursos utilizados / Otros datos de interés:
GitHub: https://github.com/RodrigoRmrz/DockerCloudDemo.Api

Video: Docker para desplegar aplicaciones en Azure y AWS

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.