Environment Configuration
Manage configurations across development, staging, and production.
A Simple Analogy
Environment configuration is like custom car settings. What works for the city doesn't work on the highway - you adjust settings per environment.
Why Configuration?
- Flexibility: Different settings per environment
- Security: Keep secrets separate
- Scalability: Same code, different configs
- Deployment: Smooth transitions
- Compliance: Meet environment requirements
Configuration Strategies
// appsettings.json (shared defaults)
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"Database": {
"ConnectionString": "Server=localhost;Database=mydb"
}
}
// appsettings.Development.json (overrides)
{
"Logging": {
"LogLevel": {
"Default": "Debug"
}
},
"Database": {
"ConnectionString": "Server=localhost;Database=mydb_dev"
}
}
// appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
Environment Variables
// Program.cs
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.AddUserSecrets<Program>(optional: true);
// Access configuration
var dbConnection = builder.Configuration.GetConnectionString("DefaultConnection");
var logLevel = builder.Configuration["Logging:LogLevel:Default"];
// Type-safe options
builder.Services.Configure<DatabaseOptions>(
builder.Configuration.GetSection("Database"));
Options Pattern
public class DatabaseOptions
{
public string ConnectionString { get; set; }
public int CommandTimeout { get; set; }
public int MaxPoolSize { get; set; }
}
public class MyService
{
private readonly DatabaseOptions _options;
public MyService(IOptions<DatabaseOptions> options)
{
_options = options.Value;
}
public void Connect()
{
var connection = new SqlConnection(_options.ConnectionString)
{
ConnectionTimeout = _options.CommandTimeout
};
}
}
Environment-Specific Logic
if (builder.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseDeveloperExceptionPage();
}
if (builder.Environment.IsProduction())
{
app.UseHsts();
app.UseHttpsRedirection();
}
if (builder.Environment.IsEnvironment("Staging"))
{
// Staging-specific behavior
}
Docker Configuration
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY . .
# Set environment
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://+:80
EXPOSE 80
ENTRYPOINT ["dotnet", "MyApp.dll"]
Best Practices
- Keep defaults sensible: Should work for dev
- Use environment variables: Override per environment
- Never commit secrets: Use user secrets locally
- Validate configuration: Fail fast on startup
- Document settings: Explain each configuration
Related Concepts
- Secret management
- Configuration as Code
- Feature flags
- Infrastructure as Code
Summary
Use the Options pattern with JSON files and environment variables for flexible configuration. Keep secrets in separate systems and validate on startup.
Related Articles
Environment Variables and Configuration
Manage application settings securely with environment variables.
Read More devopsUsing Environment Variables
Learn how to manage configuration and secrets using environment variables in your applications.
Read More devopsAzure Pipelines CI/CD
Automate build and deployment with Azure Pipelines.
Read More