Problema

Muchos desarrolladores que dominan C# y ASP.NET Core quieren pasar de crear APIs CRUD a construir plataformas de infraestructura: paneles de gestión de servidores, sistemas de despliegue continuo, dashboards de monitorización y herramientas que interactúen con Docker, redes o DNS. El reto no es sólo aprender el lenguaje, sino adquirir los conceptos y habilidades de infraestructura que permitan diseñar, implementar y operar esos sistemas de forma fiable y escalable. Sin un camino estructurado, el aprendizaje se vuelve disperso, se pierden buenas prácticas y los proyectos terminan con “código que funciona pero que no se puede mantener”.

Causa

  1. Enfoque fragmentado – Saltar de una tecnología a otra sin entender cómo encajan en la cadena de entrega (CI/CD, orquestación, observabilidad).
  2. Desconocimiento de la capa de sistema – Ignorar cómo funciona systemd, sockets o los permisos de Linux lleva a errores de despliegue que aparecen solo en producción.
  3. Falta de exposición a entornos reales – Probar todo en una máquina local con Windows y sin contenedores oculta problemas de red, persistencia y escalado.
  4. Escasez de proyectos progresivos – Sin ejercicios que aumenten la complejidad, el aprendizaje se queda en “leer documentación” y no se consolida.

Solución

Adoptar una hoja de ruta basada en capas, donde cada bloque refuerza los anteriores y se valida con un proyecto concreto. La ruta se divide en cuatro fases:

1. Fundamentos de sistemas y redes (2‑4 semanas)

  • Linux básico para devs: manejo de usuarios, permisos, systemd, journald.
  • Networking esencial: TCP/UDP, puertos, NAT, firewalls (iptables/nftables).
  • SSH y gestión remota: claves, túneles, agentes de reenvío.

Proyecto: crear un script en C# que se conecte vía SSH a una VM Linux, ejecute systemctl status y registre el resultado en una tabla SQLite. Este ejercicio obliga a manejar credenciales, salida de comandos y errores de red.

2. Contenedores y orquestación (3‑5 semanas)

  • Docker: imágenes multi‑stage, volúmenes, redes bridge y host, healthchecks.
  • Docker Compose: definición de stacks locales (API, base de datos, reverse proxy).
  • Kubernetes básico: pods, deployments, services, ConfigMaps, Secrets. No es necesario profundizar en operadores, pero sí entender cómo exponer una aplicación .NET en un clúster.

Proyecto: empaquetar la API de gestión (ASP.NET Core) en una imagen multi‑stage, crear un docker-compose.yml que incluya PostgreSQL y Traefik como reverse proxy, y migrar a un clúster local de Kind. Añadir healthchecks y liveness probes para que Kubernetes reinicie la API cuando falle.

3. Automatización y CI/CD (4‑6 semanas)

  • GitHub Actions / Azure Pipelines: pipelines declarativos, artefactos, despliegue a Kubernetes con kubectl o Helm.
  • Helm charts: plantillas parametrizables, gestión de versiones.
  • Terraform (opcional): infraestructura como código para provisionar VMs, redes y bases de datos en un proveedor cloud (AWS, Azure o GCP).

Proyecto: crear un flujo completo que compile la solución .NET, genere la imagen Docker, publique el chart Helm y despliegue automáticamente a un clúster en la nube cada vez que se haga merge a main. Incluir pruebas de integración que consuman la API a través del reverse proxy.

4. Observabilidad y resiliencia (3‑4 semanas)

  • Logging estructurado: Serilog con sinks para Elasticsearch o Loki.
  • Metrics: Prometheus client para .NET, exposición de /metrics.
  • Tracing: OpenTelemetry con Jaeger o Zipkin.
  • Alerting: Alertmanager + Grafana dashboards.

Proyecto: instrumentar la API con Serilog y Prometheus, desplegar Prometheus y Grafana en el mismo clúster, crear un dashboard que muestre latencia, errores HTTP y uso de CPU. Configurar una regla de alerta que notifique por Slack cuando el 5 % de las respuestas supere 500 ms.

Cuándo aplicar esta solución

  • Nuevo stack: Cuando se parte de cero y se quiere una base sólida antes de escalar.
  • Equipos pequeños: La hoja de ruta está pensada para un solo ingeniero o un equipo de 2‑3 personas que deben cubrir todo el ciclo de vida.
  • Entornos híbridos: Si la infraestructura combina on‑premise y cloud, los conceptos de Docker, Kubernetes y Terraform siguen siendo válidos.
  • No aplicable: Si el proyecto es estrictamente una API sin necesidad de despliegue automatizado o monitorización, la fase 4 puede posponerse.

Código

# Dockerfile multi‑stage para ASP.NET Core
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app --no-restore

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app .
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s \
  CMD curl -f http://localhost/health || exit 1
ENTRYPOINT ["dotnet", "MyInfraApp.dll"]
# docker-compose.yml con Traefik como reverse proxy
version: "3.8"
services:
  api:
    build: .
    ports: ["5000:80"]
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    networks: ["frontend"]
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
    volumes: ["db-data:/var/lib/postgresql/data"]
    networks: ["backend"]
  traefik:
    image: traefik:v2.10
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
    ports: ["80:80", "8080:8080"]
    volumes: ["/var/run/docker.sock:/var/run/docker.sock"]
    networks: ["frontend"]
networks:
  frontend:
  backend:
volumes:
  db-data:

Verificación

  1. Compilacióndocker build -t myinfraapi . debe terminar sin errores.
  2. Despliegue localdocker compose up -d. Acceder a http://localhost y confirmar que Traefik redirige a la API.
  3. Healthcheckdocker inspect --format='{{json .State.Health}}' $(docker ps -q -f name=api) debe mostrar healthy.
  4. CI pipeline – Push a main y observar que GitHub Actions crea la imagen, publica el chart y ejecuta helm upgrade --install.
  5. Observabilidad – En Grafana, el panel de latencia debe mostrar datos dentro de los primeros minutos. Generar carga con hey -n 1000 -c 50 http://localhost/api/health y verificar que la métrica http_request_duration_seconds aumenta.

Notas adicionales

  • Versionado de Helm: usa appVersion y chartVersion para diferenciar cambios de código y de infraestructura.
  • Secrets: nunca almacenes contraseñas en docker-compose.yml. Usa Docker secrets o Azure Key Vault y referencia desde el chart.
  • Persistencia: en entornos de producción, sustituye los volúmenes locales por discos gestionados (EBS, Azure Disk) y habilita snapshots automáticos.
  • Escalado: una vez que la API esté estable, prueba Horizontal Pod Autoscaler con métricas de CPU y de latencia personalizada.
  • Documentación viva: mantén un README en cada repo que describa cómo levantar el stack localmente; facilita onboarding y reduce tickets de “no funciona en mi máquina”.