Preparing Your Application for Deployment
Beginner
15 min read
Lesson 1 of 5
Why Preparation Matters
Proper preparation ensures your application runs smoothly in production. Before deploying, you need to configure your application for the production environment.
Key Concept
Development and production environments have different requirements. Your application must be configured appropriately for each.
1. Configuration Management
Using appsettings.json for Different Environments
// appsettings.json - Base configuration
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
// appsettings.Development.json - Development overrides
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Debug"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyApp;"
}
}
// appsettings.Production.json - Production overrides
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft.AspNetCore": "Error"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=production-server;Database=MyApp;"
}
}
Environment Variables
// In Program.cs
var builder = WebApplication.CreateBuilder(args);
// Load environment-specific configuration
builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
// Get connection string from environment
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
2. Database Migration
// Using Entity Framework Core
// In Program.cs
using Microsoft.EntityFrameworkCore;
// Apply migrations automatically
using (var scope = app.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService();
dbContext.Database.Migrate();
}
// Or use command line
// dotnet ef database update
3. Logging Configuration
// Configure logging
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();
// Log to file (using Serilog or similar)
// Install: dotnet add package Serilog.AspNetCore
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/myapp-.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
builder.Host.UseSerilog();
4. Error Handling
// In Program.cs
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// Custom error page
app.UseStatusCodePagesWithReExecute("/Error/{0}");
// Global exception handling middleware
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
// Log the error
var logger = context.RequestServices.GetRequiredService>();
logger.LogError(ex, "An unhandled exception occurred");
// Return a user-friendly error response
context.Response.StatusCode = 500;
await context.Response.WriteAsync("An error occurred. Please try again later.");
}
});
5. Security Configuration
// HTTPS Redirection
app.UseHttpsRedirection();
// Security Headers
app.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
context.Response.Headers.Add("X-Frame-Options", "DENY");
context.Response.Headers.Add("X-XSS-Protection", "1; mode=block");
context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
await next();
});
// CORS Configuration
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder
.WithOrigins("https://yourdomain.com")
.AllowAnyMethod()
.AllowAnyHeader());
});
6. Performance Optimization
// Enable Response Compression
builder.Services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
});
// Use in app
app.UseResponseCompression();
// Cache static files
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=31536000");
}
});
// Bundle and minify CSS/JS
// Use WebOptimizer or bundling
7. Health Checks
// Add health checks
builder.Services.AddHealthChecks()
.AddDbContextCheck()
.AddUrlGroup(new Uri("https://api.example.com"), "API Health")
.AddCheck("Custom Check");
// In app
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
8. Build Configuration
// In .csproj file
net10.0
enable
enable
true
// Build for production
// dotnet build -c Release
// dotnet publish -c Release -o ./publish
Complete Deployment Preparation Checklist
Pre-Deployment Checklist
- ✅ Configure appsettings for production
- ✅ Set up environment variables
- ✅ Apply database migrations
- ✅ Configure logging for production
- ✅ Implement error handling
- ✅ Add security headers and HTTPS
- ✅ Enable caching and compression
- ✅ Add health checks
- ✅ Build in Release mode
- ✅ Test in production-like environment
- ✅ Backup database and files
- ✅ Update documentation
Key Takeaway
Proper preparation is essential for successful deployment. Configure your application for the production environment, implement security measures, and optimize performance.
Exercise
Prepare your application for deployment:
- Create appsettings.Production.json
- Set up environment variables
- Configure logging for production
- Add security headers
- Enable response compression
- Create a deployment checklist