Hosting Models in ConnectSoft Microservice Template¶
Purpose & Overview¶
Hosting Models in the ConnectSoft Microservice Template refer to the various deployment environments and runtime configurations where microservices can be hosted. The template is designed to be hosting-model agnostic, providing a unified application codebase that adapts seamlessly to different hosting environments while maintaining consistent behavior and functionality.
Why Multiple Hosting Models?¶
Different hosting models offer distinct advantages:
- Flexibility: Choose the hosting model that best fits organizational infrastructure
- Cloud Portability: Deploy to different cloud providers or on-premises
- Cost Optimization: Select hosting models based on cost and performance requirements
- Operational Requirements: Support different operational models (containers, serverless, traditional)
- Migration Path: Enable gradual migration between hosting models
- Development Flexibility: Support different development and deployment workflows
Hosting Model Philosophy
The ConnectSoft Microservice Template is designed to be hosting-model agnostic. The same application code runs consistently across all hosting models, with environment-specific configuration handled through configuration files and environment variables. This ensures code portability and operational flexibility.
Supported Hosting Models¶
Overview¶
The template supports the following hosting models:
| Hosting Model | Platform | Use Case | Configuration |
|---|---|---|---|
| Kestrel Standalone | Cross-platform | Development, testing, simple deployments | Direct Kestrel hosting |
| IIS (In-Process) | Windows Server | Windows Server deployments | web.config with hostingModel="inprocess" |
| IIS (Out-of-Process) | Windows Server | Legacy Windows Server deployments | web.config with hostingModel="outofprocess" |
| Docker Container | Any Docker host | Containerized deployments, Kubernetes base | Dockerfile, Docker Compose |
| Linux systemd | Linux servers | Traditional Linux deployments | systemd service file + Nginx |
| Azure App Service | Azure cloud | Managed Azure hosting | ZIP deploy or container |
| Kubernetes | Any Kubernetes cluster | Container orchestration | Kubernetes manifests |
| Azure Functions | Azure cloud | Serverless workloads | Azure Functions host |
| Azure Container Apps | Azure cloud | Container-based serverless | Container registry |
Architecture Overview¶
Hosting Model Abstraction¶
Application Code (Hosting-Agnostic)
├── Program.cs (Host Builder)
├── Startup.cs (Service Registration)
├── Middleware Pipeline
└── Business Logic
↓
Hosting Model Adapter
├── Kestrel Configuration
├── Environment Detection
├── Configuration Loading
└── Hosting-Specific Setup
↓
Runtime Environment
├── Kestrel Standalone
├── IIS
├── Docker Container
├── Linux systemd
├── Azure App Service
├── Kubernetes
└── Azure Functions
Common Elements¶
All hosting models share:
- Same Application Code: Identical
Program.csandStartup.cs - Kestrel Web Server: All models use Kestrel as the web server
- Configuration System: Unified configuration via
appsettings.json - Middleware Pipeline: Same middleware pipeline across all models
- Service Registration: Consistent DI and service registration
- Environment Awareness: Environment-specific configuration
Kestrel Standalone Hosting¶
Overview¶
Kestrel Standalone is the default hosting model where the application runs directly on Kestrel without a reverse proxy or hosting platform.
Characteristics¶
- Direct Execution: Application runs directly on Kestrel
- Development Default: Used by default in
dotnet run - Cross-Platform: Works on Windows, Linux, and macOS
- Simple Deployment: No additional infrastructure required
- Full Control: Direct access to Kestrel configuration
Configuration¶
Kestrel Configuration (via appsettings.json):
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "path/to/certificate.pfx",
"Password": "password"
}
}
},
"Limits": {
"MaxRequestBodySize": 104857600,
"MaxConcurrentConnections": 100
}
}
}
Program.cs Configuration:
private static void DefineKestrel(IWebHostBuilder webBuilder)
{
webBuilder.ConfigureKestrel((context, options) =>
{
IConfigurationSection kestrelSection = context.Configuration.GetRequiredSection("Kestrel");
kestrelSection.Bind(options);
options.ConfigureEndpointDefaults(listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
}
Running¶
Development:
Production:
Use Cases¶
- Local development
- Testing and CI/CD pipelines
- Simple deployments without reverse proxy
- Containerized applications (Kestrel is the web server in containers)
Advantages¶
- ✅ Simple setup and configuration
- ✅ Full control over Kestrel settings
- ✅ Cross-platform compatibility
- ✅ No additional infrastructure required
Disadvantages¶
- ❌ No built-in reverse proxy features
- ❌ Manual SSL certificate management
- ❌ No automatic process management
- ❌ Limited production-ready features
IIS Hosting¶
Overview¶
IIS (Internet Information Services) hosting runs the application on Windows Server with IIS as the reverse proxy and process manager.
Hosting Models¶
In-Process Model (Recommended)¶
Configuration (web.config):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet"
arguments=".\ConnectSoft.MicroserviceTemplate.Application.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
Characteristics: - Performance: Faster than out-of-process (no inter-process communication) - Recommended: Default and recommended for .NET Core 3.1+ - Integration: Direct integration with IIS request pipeline - Process Management: IIS manages application lifecycle
Out-of-Process Model¶
Configuration:
<aspNetCore processPath="dotnet"
arguments=".\ConnectSoft.MicroserviceTemplate.Application.dll"
stdoutLogEnabled="true"
stdoutLogFile=".\logs\stdout"
hostingModel="outofprocess" />
Characteristics: - Compatibility: Matches Docker/Kestrel behavior - Isolation: Separate process from IIS - Debugging: Easier to debug (separate process) - Legacy: Used for compatibility with older deployments
IIS Integration¶
Auto-Detection:
// IIS integration is auto-detected when running under IIS
// No explicit configuration required in .NET 6+
Manual Configuration (if needed):
Enables: - Header forwarding (X-Forwarded-For, X-Forwarded-Proto) - Port resolution from IIS - Graceful shutdown support
Deployment¶
Publish to IIS:
# Publish application
dotnet publish -c Release -o C:\inetpub\wwwroot\MyMicroservice
# IIS Configuration
# - Create Application Pool (No Managed Code)
# - Create Application pointing to published folder
# - Configure bindings (HTTP/HTTPS)
Configuration¶
Environment Variables:
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
<environmentVariable name="ASPNETCORE_URLS" value="http://localhost:5000" />
</environmentVariables>
</aspNetCore>
Connection Strings:
Configure via IIS Manager or web.config:
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=...;Database=...;" />
</connectionStrings>
Use Cases¶
- Windows Server deployments
- Enterprise on-premises hosting
- Organizations with existing IIS infrastructure
- Windows-specific integrations
Advantages¶
- ✅ Enterprise-grade process management
- ✅ Integrated Windows authentication
- ✅ Built-in SSL termination
- ✅ Application pool isolation
- ✅ Health monitoring and recycling
Disadvantages¶
- ❌ Windows-only
- ❌ Requires IIS configuration
- ❌ Additional infrastructure overhead
- ❌ Licensing costs (Windows Server)
Docker Container Hosting¶
Overview¶
Docker Container hosting packages the application in a container image that can run on any Docker-compatible host.
See Containerization for detailed documentation.
Characteristics¶
- Portability: Run anywhere Docker is supported
- Isolation: Application and dependencies packaged together
- Orchestration: Ready for Kubernetes, Docker Swarm, etc.
- Consistency: Same environment across dev, staging, production
Configuration¶
Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 8081
EXPOSE 7279
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
# ... build stages ...
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConnectSoft.MicroserviceTemplate.Application.dll"]
Environment-Specific Configuration:
// appsettings.Docker.json
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://+:8081"
},
"Https": {
"Url": "https://+:7279"
}
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=sql,1433;Database=MyDb;..."
}
}
Environment Detection¶
// Container detection
if (Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true")
{
// Container-specific logic
}
// Environment variable
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Docker"
Running¶
Docker Compose:
Docker Run:
docker run -p 8081:8081 \
-e ASPNETCORE_ENVIRONMENT=Docker \
connectsoft.microservicetemplate.application:latest
Use Cases¶
- Containerized deployments
- Kubernetes base
- Cloud container services (Azure Container Instances, AWS ECS)
- Development environment consistency
- CI/CD pipelines
Advantages¶
- ✅ Portability across environments
- ✅ Consistent runtime environment
- ✅ Easy scaling and orchestration
- ✅ Isolation and security
- ✅ Version control for deployments
Disadvantages¶
- ❌ Requires container runtime
- ❌ Additional complexity in container management
- ❌ Image size considerations
- ❌ Network configuration complexity
Linux systemd Hosting¶
Overview¶
Linux systemd hosting runs the application as a systemd service on Linux servers, typically behind an Nginx reverse proxy.
systemd Service File¶
Service File (/etc/systemd/system/connectsoft-microservice.service):
[Unit]
Description=ConnectSoft Microservice Template
After=network.target
[Service]
Type=notify
WorkingDirectory=/opt/connectsoft/microservice
ExecStart=/usr/bin/dotnet /opt/connectsoft/microservice/ConnectSoft.MicroserviceTemplate.Application.dll
Restart=always
RestartSec=10
SyslogIdentifier=connectsoft-microservice
User=dotnet
Group=dotnet
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_URLS=http://localhost:5000
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
# Security
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/connectsoft/microservice
[Install]
WantedBy=multi-user.target
Deployment Steps¶
1. Publish Application:
2. Create systemd User (if needed):
3. Install Service:
sudo cp connectsoft-microservice.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable connectsoft-microservice
sudo systemctl start connectsoft-microservice
4. Verify Status:
5. View Logs:
Nginx Reverse Proxy¶
Nginx Configuration (/etc/nginx/sites-available/microservice):
server {
listen 80;
server_name microservice.example.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# Health check endpoint (bypass proxy)
location /health {
proxy_pass http://localhost:5000/health;
access_log off;
}
}
Enable Site:
sudo ln -s /etc/nginx/sites-available/microservice /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Configuration¶
Application Configuration:
// appsettings.Production.json
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
}
}
}
}
Forwarded Headers:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("127.0.0.1"), 8));
});
Use Cases¶
- Linux server deployments
- Traditional VPS hosting
- On-premises Linux infrastructure
- Cost-effective hosting solutions
Advantages¶
- ✅ Cost-effective (Linux servers)
- ✅ Full control over infrastructure
- ✅ systemd process management
- ✅ Nginx performance and features
- ✅ Security hardening options
Disadvantages¶
- ❌ Manual infrastructure management
- ❌ Requires Linux expertise
- ❌ No automatic scaling
- ❌ Manual SSL certificate management
Azure App Service Hosting¶
Overview¶
Azure App Service is a fully managed platform-as-a-service (PaaS) for hosting web applications in Azure.
Deployment Options¶
| Method | Tool | Artifact | Use Case |
|---|---|---|---|
| ZIP Deploy | Azure CLI, Portal | .zip archive |
Quick deployments |
| Docker | Container Registry | Docker image | Containerized apps |
| GitHub Actions | Azure Deploy Action | Build artifact | CI/CD integration |
| Azure DevOps | Azure Web App Task | Build artifact | Enterprise CI/CD |
| VS Code Extension | Azure App Service | Local publish | Development |
Configuration¶
Required App Service Settings:
| Setting | Value | Purpose |
|---|---|---|
ASPNETCORE_ENVIRONMENT |
Production |
Environment name |
WEBSITES_PORT |
5000 |
Port Kestrel listens on |
DOTNET_RUNNING_IN_CONTAINER |
false |
Container detection (if not using containers) |
APPINSIGHTS_INSTRUMENTATIONKEY |
... |
Application Insights integration |
WEBSITES_ENABLE_APP_SERVICE_STORAGE |
false |
Disable shared storage |
Connection Strings:
Configure via App Service Configuration:
ConnectionStrings__DefaultConnection = Server=tcp:...database.windows.net,1433;Database=...;User ID=...;Password=...;Encrypt=true;TrustServerCertificate=false;Connection Timeout=30;
ConnectionStrings__Redis = ...redis.cache.windows.net:6380,password=...,ssl=True,abortConnect=False
ZIP Deploy¶
Publish and Deploy:
# Publish application
dotnet publish -c Release -o ./publish
# Create ZIP archive
cd publish
zip -r ../app.zip .
# Deploy via Azure CLI
az webapp deployment source config-zip \
--resource-group MyResourceGroup \
--name MyAppService \
--src app.zip
Deploy via Portal:
- Navigate to App Service → Deployment Center
- Select "Local Git" or "ZIP Deploy"
- Upload ZIP file or configure Git repository
Container Deploy¶
Deploy Docker Image:
# Build and push to Azure Container Registry
az acr build --registry myregistry \
--image connectsoft-microservice:latest \
--file Dockerfile .
# Configure App Service to use container
az webapp config container set \
--resource-group MyResourceGroup \
--name MyAppService \
--docker-custom-image-name myregistry.azurecr.io/connectsoft-microservice:latest \
--docker-registry-server-url https://myregistry.azurecr.io
HTTPS and SSL¶
Automatic HTTPS: - Azure App Service provides automatic HTTPS certificates via Let's Encrypt - Custom domains automatically get SSL certificates - HTTPS redirection can be configured
Custom Certificates:
# Upload custom certificate
az webapp config ssl upload \
--resource-group MyResourceGroup \
--name MyAppService \
--certificate-file certificate.pfx \
--certificate-password password
Scaling¶
Manual Scaling:
az appservice plan update \
--resource-group MyResourceGroup \
--name MyAppServicePlan \
--number-of-workers 3
Auto-Scaling:
Configure via Azure Portal or Azure CLI:
az monitor autoscale create \
--resource-group MyResourceGroup \
--resource /subscriptions/.../Microsoft.Web/serverfarms/MyAppServicePlan \
--name MyAutoScale \
--min-count 1 \
--max-count 10 \
--count 2
Use Cases¶
- Managed cloud hosting
- Azure ecosystem integration
- Quick deployments
- Automatic scaling requirements
- Managed SSL certificates
Advantages¶
- ✅ Fully managed platform
- ✅ Automatic scaling
- ✅ Built-in SSL certificates
- ✅ Azure integration (Key Vault, Application Insights)
- ✅ Deployment slots for blue-green deployments
- ✅ Automatic backups
Disadvantages¶
- ❌ Platform-specific (Azure only)
- ❌ Less control over infrastructure
- ❌ Potential vendor lock-in
- ❌ Cost considerations at scale
Kubernetes Hosting¶
Overview¶
Kubernetes hosting runs containerized applications in a Kubernetes cluster with orchestration, scaling, and service discovery.
See Kubernetes for detailed documentation.
Characteristics¶
- Orchestration: Automatic container management and scaling
- Service Discovery: Built-in DNS-based service discovery
- Load Balancing: Automatic load balancing across pods
- High Availability: Pod replication and health checks
- Self-Healing: Automatic restart of failed containers
Deployment¶
Deployment Manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: connectsoft-microservice
labels:
app: connectsoft-microservice
spec:
replicas: 3
selector:
matchLabels:
app: connectsoft-microservice
template:
metadata:
labels:
app: connectsoft-microservice
spec:
containers:
- name: microservice
image: myregistry.azurecr.io/connectsoft-microservice:1.0.0
ports:
- containerPort: 8081
name: http
- containerPort: 7279
name: https
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_URLS
value: "http://+:8081;https://+:7279"
livenessProbe:
httpGet:
path: /live
port: 8081
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8081
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Service Manifest:
apiVersion: v1
kind: Service
metadata:
name: connectsoft-microservice
spec:
type: ClusterIP
selector:
app: connectsoft-microservice
ports:
- port: 80
targetPort: 8081
protocol: TCP
name: http
- port: 443
targetPort: 7279
protocol: TCP
name: https
Ingress Manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: connectsoft-microservice
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- microservice.example.com
secretName: microservice-tls
rules:
- host: microservice.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: connectsoft-microservice
port:
number: 80
Configuration¶
ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: microservice-config
data:
appsettings.json: |
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://+:8081"
}
}
}
}
Secrets:
apiVersion: v1
kind: Secret
metadata:
name: microservice-secrets
type: Opaque
stringData:
ConnectionStrings__DefaultConnection: "Server=...;Database=...;..."
Use in Deployment:
spec:
template:
spec:
containers:
- name: microservice
envFrom:
- configMapRef:
name: microservice-config
- secretRef:
name: microservice-secrets
Health Checks¶
Liveness Probe:
livenessProbe:
httpGet:
path: /live
port: 8081
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
Readiness Probe:
readinessProbe:
httpGet:
path: /ready
port: 8081
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
Startup Probe:
startupProbe:
httpGet:
path: /health
port: 8081
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 30 # Allow up to 5 minutes for startup
Scaling¶
Horizontal Pod Autoscaler:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: connectsoft-microservice-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: connectsoft-microservice
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Use Cases¶
- Container orchestration at scale
- Multi-cloud deployments
- High availability requirements
- Complex microservice architectures
- Self-hosted Kubernetes clusters
Advantages¶
- ✅ Automatic scaling and orchestration
- ✅ High availability and self-healing
- ✅ Service discovery and load balancing
- ✅ Cloud-agnostic (runs anywhere)
- ✅ Rich ecosystem and tooling
Disadvantages¶
- ❌ Complex infrastructure management
- ❌ Requires Kubernetes expertise
- ❌ Operational overhead
- ❌ Learning curve
Azure Functions Hosting¶
Overview¶
Azure Functions provides serverless hosting for event-driven workloads.
See Azure Functions for detailed documentation.
Characteristics¶
- Serverless: No infrastructure management
- Event-Driven: Triggered by events (HTTP, timer, queue, etc.)
- Pay-per-Use: Cost based on execution time and invocations
- Automatic Scaling: Scales automatically based on demand
- Integration: Built-in integration with Azure services
Configuration¶
Function App Settings:
FUNCTIONS_WORKER_RUNTIME=dotnet-isolated
FUNCTIONS_EXTENSION_VERSION=~4
ASPNETCORE_ENVIRONMENT=Production
Use Cases¶
- Event-driven workloads
- Scheduled tasks
- API endpoints with variable traffic
- Integration with Azure services
- Cost-effective for low-traffic scenarios
Advantages¶
- ✅ No infrastructure management
- ✅ Automatic scaling
- ✅ Pay-per-use pricing
- ✅ Azure service integration
- ✅ Event-driven architecture
Disadvantages¶
- ❌ Cold start latency
- ❌ Execution time limits
- ❌ Platform-specific (Azure)
- ❌ Less control over runtime
Azure Container Apps¶
Overview¶
Azure Container Apps is a serverless container platform for running containerized applications.
Characteristics¶
- Serverless Containers: Container-based serverless platform
- Automatic Scaling: Scales containers based on HTTP traffic or events
- Kubernetes-Based: Built on Kubernetes but abstracts complexity
- Dapr Integration: Built-in Dapr support for microservices
Configuration¶
Container App Manifest:
apiVersion: 2022-03-01
type: Microsoft.App/containerApps
properties:
managedEnvironmentId: /subscriptions/.../managedEnvironments/myenv
configuration:
ingress:
external: true
targetPort: 8081
transport: http
allowInsecure: false
template:
containers:
- name: microservice
image: myregistry.azurecr.io/connectsoft-microservice:1.0.0
env:
- name: ASPNETCORE_ENVIRONMENT
value: Production
resources:
cpu: 0.5
memory: 1.0Gi
scale:
minReplicas: 1
maxReplicas: 10
rules:
- name: http-scale
http:
metadata:
concurrentRequests: 100
Use Cases¶
- Container-based serverless workloads
- Microservices with variable traffic
- Dapr-based architectures
- Kubernetes-like features without Kubernetes complexity
Advantages¶
- ✅ Serverless container platform
- ✅ Automatic scaling
- ✅ Built-in Dapr support
- ✅ Kubernetes-based without complexity
- ✅ Pay-per-use pricing
Disadvantages¶
- ❌ Azure-only platform
- ❌ Less control than Kubernetes
- ❌ Newer platform (limited ecosystem)
Hosting Model Comparison¶
Feature Matrix¶
| Feature | Kestrel | IIS | Docker | Linux systemd | Azure App Service | Kubernetes | Azure Functions |
|---|---|---|---|---|---|---|---|
| Platform | Cross-platform | Windows | Any | Linux | Azure | Any | Azure |
| Process Management | Manual | IIS | Container runtime | systemd | Managed | Kubernetes | Managed |
| Scaling | Manual | Manual | Orchestrator | Manual | Automatic | Automatic | Automatic |
| SSL/TLS | Manual | Built-in | Manual | Nginx | Automatic | Ingress | Automatic |
| High Availability | Manual | IIS | Orchestrator | Manual | Built-in | Built-in | Built-in |
| Cost | Low | Medium | Low | Low | Medium-High | Medium | Pay-per-use |
| Complexity | Low | Medium | Medium | Medium | Low | High | Low |
| Portability | High | Low | High | Low | Low | High | Low |
Selection Guide¶
Choose Kestrel Standalone When: - Local development - Simple deployments - Testing environments - Container base (Docker/Kubernetes)
Choose IIS When: - Windows Server infrastructure - Enterprise Windows environments - Windows-specific integrations - Existing IIS investments
Choose Docker When: - Containerized deployments - Kubernetes base - Cloud container services - Development environment consistency
Choose Linux systemd When: - Linux server deployments - Cost-effective hosting - Full infrastructure control - Traditional VPS hosting
Choose Azure App Service When: - Managed Azure hosting - Quick deployments - Automatic scaling needs - Azure ecosystem integration
Choose Kubernetes When: - Container orchestration at scale - Multi-cloud deployments - High availability requirements - Complex microservice architectures
Choose Azure Functions When: - Event-driven workloads - Variable traffic patterns - Serverless architecture - Cost optimization for low traffic
Choose Azure Container Apps When: - Container-based serverless - Dapr integration - Kubernetes-like features without complexity - Azure-native container hosting
Configuration Adaptations¶
Environment-Specific Configuration¶
appsettings.json (Base):
appsettings.Docker.json (Docker):
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://+:8081"
}
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=sql,1433;..."
}
}
appsettings.Production.json (Production):
Forwarded Headers Configuration¶
Required for Reverse Proxies:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
// IIS
options.KnownProxies.Add(IPAddress.Parse("127.0.0.1"));
// Docker
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12));
// Kubernetes
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8));
});
Port Configuration¶
Environment Variable Override:
# Docker
ASPNETCORE_URLS=http://+:8081;https://+:7279
# Azure App Service
WEBSITES_PORT=5000
# Kubernetes
ASPNETCORE_URLS=http://+:8081
# Linux systemd
ASPNETCORE_URLS=http://localhost:5000
Migration Between Hosting Models¶
Migration Paths¶
IIS to Docker: 1. Containerize application (Dockerfile) 2. Test in Docker environment 3. Deploy to container registry 4. Update deployment pipeline 5. Deploy to container host
Docker to Kubernetes: 1. Create Kubernetes manifests 2. Configure ConfigMaps and Secrets 3. Set up ingress controller 4. Deploy to Kubernetes cluster 5. Configure monitoring and scaling
Kestrel to Azure App Service: 1. Publish application 2. Create App Service plan 3. Create App Service 4. Configure settings and connection strings 5. Deploy application
Code Compatibility¶
Hosting-Agnostic Code:
// ✅ GOOD - Works in all hosting models
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Service registration (hosting-agnostic)
services.AddControllers();
}
public void Configure(IApplicationBuilder app)
{
// Middleware pipeline (hosting-agnostic)
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
}
Hosting-Specific Configuration:
// ✅ GOOD - Environment-specific configuration
if (Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true")
{
// Container-specific setup
}
if (Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") != null)
{
// Azure App Service-specific setup
}
Best Practices¶
Do's¶
-
Use Configuration Files for Hosting Differences
-
Enable Forwarded Headers for Reverse Proxies
-
Use Environment Variables for Secrets
-
Configure Health Checks
-
Use Standard Ports or Configuration
Don'ts¶
-
Don't Hardcode Hosting-Specific Values
-
Don't Assume Process Management
-
Don't Skip Forwarded Headers
-
Don't Use Hosting-Specific APIs Directly
Troubleshooting¶
Issue: Application Not Starting¶
Symptoms: Application fails to start in specific hosting model.
Solutions: 1. Check environment variables are set correctly 2. Verify configuration files are present 3. Review logs for specific errors 4. Check port binding and availability 5. Verify dependencies are accessible
Issue: Reverse Proxy Not Working¶
Symptoms: Headers not forwarded correctly.
Solutions:
1. Verify UseForwardedHeaders() is called
2. Check KnownProxies and KnownNetworks configuration
3. Verify reverse proxy is setting correct headers
4. Check network configuration
Issue: Port Conflicts¶
Symptoms: Port already in use errors.
Solutions:
1. Check port configuration in appsettings.json
2. Verify environment variable overrides
3. Check for other services using the port
4. Use dynamic port allocation where possible
Issue: Health Checks Failing¶
Symptoms: Health checks fail in orchestrator.
Solutions: 1. Verify health check endpoints are configured 2. Check health check paths match configuration 3. Verify startup probe timing (Kubernetes) 4. Review application startup logs
Summary¶
Hosting models in the ConnectSoft Microservice Template provide:
- ✅ Hosting-Agnostic Code: Same codebase runs across all models
- ✅ Flexible Deployment: Support for multiple deployment targets
- ✅ Environment Configuration: Hosting-specific settings via configuration
- ✅ Consistent Behavior: Unified behavior across hosting models
- ✅ Migration Support: Easy migration between hosting models
- ✅ Best Practices: Security and performance optimizations for each model
By following these patterns, teams can:
- Choose Appropriately: Select hosting model based on requirements
- Deploy Flexibly: Deploy to different environments as needed
- Migrate Easily: Move between hosting models without code changes
- Maintain Consistency: Same application behavior across models
- Optimize Costs: Select hosting models based on cost and performance
- Scale Effectively: Leverage hosting model features for scaling
The hosting model abstraction ensures that ConnectSoft microservices can run consistently across any hosting environment while taking advantage of platform-specific features when available.