aspnet-configuracion-entornos

Configurar entornos en ASP.NET Core

  • 5 min

Un entorno en ASP.NET Core es el contexto donde se ejecuta una aplicación y que permite cambiar su configuración y comportamiento según estemos en desarrollo, pruebas o producción.

Esto nos permite adaptar el comportamiento de la aplicación: depurar en local, probar cambios en staging y aplicar una configuración más estricta en producción. Porque una cosa es ejecutar la API en nuestro ordenador, y otra muy distinta es soltarla en un servidor con usuarios reales mirando.

Por ejemplo, en Development podemos mostrar errores detallados y habilitar Swagger. En Production, lo normal es ocultar detalles internos, activar HSTS, usar configuración real y registrar los errores de forma controlada.

Entornos habituales

ASP.NET Core permite usar cualquier nombre de entorno, pero hay tres nombres que vamos a ver constantemente:

  • Development: entorno local de desarrollo, con herramientas de depuración y mensajes de error detallados.
  • Staging: entorno de pruebas parecido a producción, útil para validar despliegues antes de abrir la puerta al público.
  • Production: entorno real, optimizado para seguridad, rendimiento y estabilidad.

Si no se configura ningún entorno, ASP.NET Core asume Production por defecto. Esto está bien pensado, porque es preferible arrancar en modo seguro antes que mostrar una página de errores con todos los detalles internos.

Variables de entorno

El entorno se indica normalmente mediante una variable de entorno. La más habitual en aplicaciones ASP.NET Core es ASPNETCORE_ENVIRONMENT.

$env:ASPNETCORE_ENVIRONMENT="Development"
Copied!

En Linux o macOS sería:

export ASPNETCORE_ENVIRONMENT=Development
Copied!

También existe DOTNET_ENVIRONMENT, que aplica al host genérico de .NET. En proyectos modernos con WebApplication.CreateBuilder, conviene no definir ambas con valores distintos, porque estaríamos pidiendo a gritos una tarde entretenida de diagnóstico.

Los nombres de las variables de entorno son sensibles a mayúsculas y minúsculas en Linux. ASPNETCORE_ENVIRONMENT y aspnetcore_environment no son lo mismo.

launchSettings.json

Cuando trabajamos en local, Visual Studio, Rider o dotnet run pueden usar el archivo Properties/launchSettings.json. Este archivo sirve para desarrollo local y no se publica con la aplicación.

{
  "profiles": {
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Staging": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      }
    }
  }
}
Copied!

Podemos ejecutar un perfil concreto desde la CLI:

dotnet run --launch-profile Staging
Copied!

Y si queremos ignorar los perfiles locales y usar lo que hay en la consola:

dotnet run --no-launch-profile
Copied!

appsettings por entorno

ASP.NET carga archivos de configuración específicos según el entorno. El patrón es:

appsettings.{Environment}.json
Copied!

Por ejemplo:

appsettings.json
appsettings.Development.json
appsettings.Staging.json
appsettings.Production.json
Copied!

La idea es sencilla: appsettings.json contiene la configuración base, y el archivo específico del entorno sobrescribe las claves que necesite cambiar.

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=prod-sql;Database=MiApp;..."
  }
}
Copied!

appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=MiAppDev;..."
  }
}
Copied!

Así, la misma aplicación puede usar más logs y una base de datos local en desarrollo, pero conectarse a la configuración real cuando se ejecuta en producción.

Orden de prioridad

La configuración en ASP.NET Core viene de varios sitios. En la configuración por defecto, el orden habitual es:

  1. appsettings.json.
  2. appsettings.{Environment}.json.
  3. User Secrets, solo en Development.
  4. Variables de entorno.
  5. Argumentos de línea de comandos.

La regla importante es esta: si la misma clave aparece en varios sitios, gana la fuente con más prioridad.

Por eso una variable de entorno puede sobrescribir un valor de appsettings.json, y un argumento de línea de comandos puede sobrescribir casi todo lo anterior.

Para claves jerárquicas en variables de entorno, usamos doble guion bajo __ en lugar de dos puntos :. Por ejemplo, ConnectionStrings__DefaultConnection.

Cambiar el comportamiento por entorno

A veces no basta con cambiar valores de configuración. También queremos activar o desactivar partes del pipeline según el entorno.

El caso típico está en Program.cs:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.Run();
Copied!

En desarrollo mostramos una página de error detallada. En producción usamos un manejador seguro y activamos HSTS.

También podemos comprobar entornos personalizados:

if (app.Environment.IsEnvironment("Testing"))
{
    // Configuración específica para pruebas automatizadas
}
Copied!

Los entornos personalizados son válidos. Solo hay que ser ordenados con los nombres y crear los archivos de configuración correspondientes, como appsettings.Testing.json.

Configurar el entorno en producción

En producción, lo normal es configurar el entorno desde la plataforma donde desplegamos.

En Azure App Service podemos definir ASPNETCORE_ENVIRONMENT desde la configuración de la aplicación:

  1. Entramos en el App Service.
  2. Vamos a Configuración > Configuración de la aplicación.
  3. Añadimos ASPNETCORE_ENVIRONMENT con el valor Production, Staging o el que corresponda.

Azure reinicia la aplicación al cambiar estos ajustes, así que el nuevo entorno se aplica en el siguiente arranque.

En Docker podemos definir el entorno en el Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080

ENV ASPNETCORE_ENVIRONMENT=Production
Copied!

O pasarlo al ejecutar el contenedor:

docker run -e ASPNETCORE_ENVIRONMENT=Production mi-app
Copied!

Si usamos Docker Compose:

services:
  web:
    image: mi-app
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
Copied!

Buenas prácticas

No guardes secretos reales en appsettings.Production.json si ese archivo va al repositorio. Para desarrollo, usamos User Secrets. Para producción, usamos variables de entorno, Azure Key Vault u otro almacén de secretos.

Tampoco conviene llenar la aplicación de if (app.Environment.IsDevelopment()). Para diferencias simples en el pipeline está bien. Para diferencias grandes, suele ser mejor usar configuración o inyección de dependencias.

Por ejemplo, en desarrollo podemos registrar un FakeEmailSender, y en producción un SmtpEmailSender. El resto de la aplicación no necesita saber dónde está corriendo.