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"En Linux o macOS sería:
export ASPNETCORE_ENVIRONMENT=DevelopmentTambié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"
}
}
}
}Podemos ejecutar un perfil concreto desde la CLI:
dotnet run --launch-profile StagingY si queremos ignorar los perfiles locales y usar lo que hay en la consola:
dotnet run --no-launch-profileappsettings por entorno
ASP.NET carga archivos de configuración específicos según el entorno. El patrón es:
appsettings.{Environment}.jsonPor ejemplo:
appsettings.json
appsettings.Development.json
appsettings.Staging.json
appsettings.Production.jsonLa 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;..."
}
}appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.EntityFrameworkCore": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MiAppDev;..."
}
}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:
appsettings.json.appsettings.{Environment}.json.- User Secrets, solo en
Development. - Variables de entorno.
- 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();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
}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:
- Entramos en el App Service.
- Vamos a Configuración > Configuración de la aplicación.
- Añadimos
ASPNETCORE_ENVIRONMENTcon el valorProduction,Stagingo 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=ProductionO pasarlo al ejecutar el contenedor:
docker run -e ASPNETCORE_ENVIRONMENT=Production mi-appSi usamos Docker Compose:
services:
web:
image: mi-app
environment:
- ASPNETCORE_ENVIRONMENT=ProductionBuenas 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.