Overview
The Dev Showcase portfolio is an ASP.NET Core 9.0 application that can be hosted on various platforms. This guide covers deployment options, configuration, and best practices for production hosting.
Choose a hosting platform based on your needs:
Azure App Service Managed PaaS with built-in scaling and deployment
IIS Windows Server hosting with IIS integration
Linux Servers Ubuntu, Debian, or RHEL with systemd
Docker Container-based deployment for any platform
Azure App Service Deployment
Azure App Service provides the easiest deployment path for ASP.NET Core applications.
Create App Service
Create an Azure App Service resource: az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name dev-showcase-portfolio \
--runtime "DOTNET|9.0"
Configure Settings
Set environment variables: az webapp config appsettings set \
--resource-group myResourceGroup \
--name dev-showcase-portfolio \
--settings ASPNETCORE_ENVIRONMENT=Production
Deploy
Deploy using the Azure CLI or GitHub Actions: az webapp deployment source config-zip \
--resource-group myResourceGroup \
--name dev-showcase-portfolio \
--src ./publish.zip
Configure HTTPS
Enable HTTPS-only traffic: az webapp update \
--resource-group myResourceGroup \
--name dev-showcase-portfolio \
--https-only true
Azure App Service automatically handles certificate management, scaling, and load balancing.
IIS Hosting (Windows Server)
Deploy to Internet Information Services on Windows Server.
Install Prerequisites
Install required components:
.NET 9.0 Hosting Bundle
IIS with ASP.NET Core Module
URL Rewrite Module (for HTTPS redirection)
Publish Application
Create deployment package: dotnet publish -c Release -o C: \i netpub \d ev-showcase
Create IIS Site
Configure in IIS Manager:
Application Pool: No Managed Code
Physical Path: C:\inetpub\dev-showcase
Binding: HTTPS on port 443
Configure App Pool
Set application pool identity:
Identity: ApplicationPoolIdentity
.NET CLR Version: No Managed Code
Pipeline Mode: Integrated
web.config Configuration
IIS requires a web.config file (auto-generated during publish):
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
< system.webServer >
< handlers >
< add name = "aspNetCore" path = "*" verb = "*"
modules = "AspNetCoreModuleV2"
resourceType = "Unspecified" />
</ handlers >
< aspNetCore processPath = "dotnet"
arguments = ".\dev-showcase.dll"
stdoutLogEnabled = "false"
stdoutLogFile = ".\logs\stdout"
hostingModel = "InProcess" />
</ system.webServer >
</ configuration >
The ASP.NET Core Module bridges IIS and Kestrel, providing process management and performance optimizations.
Linux Server Deployment
Deploy to Ubuntu or other Linux distributions using systemd.
Install .NET Runtime
Install the .NET 9.0 runtime: wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --channel 9.0 --runtime aspnetcore
Copy Application Files
Upload the published files: scp -r ./publish/ * user@server:/var/www/dev-showcase/
Create Systemd Service
Create /etc/systemd/system/dev-showcase.service: [Unit]
Description =Dev Showcase Portfolio
After =network.target
[Service]
Type =notify
WorkingDirectory =/var/www/dev-showcase
ExecStart =/usr/bin/dotnet /var/www/dev-showcase/dev-showcase.dll
Restart =always
RestartSec =10
KillSignal =SIGINT
SyslogIdentifier =dev-showcase
User =www-data
Environment = ASPNETCORE_ENVIRONMENT =Production
Environment = DOTNET_PRINT_TELEMETRY_MESSAGE =false
[Install]
WantedBy =multi-user.target
Start Service
Enable and start the service: sudo systemctl enable dev-showcase
sudo systemctl start dev-showcase
sudo systemctl status dev-showcase
Configure Nginx Reverse Proxy
Create /etc/nginx/sites-available/dev-showcase: server {
listen 80 ;
listen [::]:80;
server_name your-domain.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_cache_bypass $ http_upgrade ;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $ scheme ;
}
}
Enable the site: sudo ln -s /etc/nginx/sites-available/dev-showcase /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Always run the application under a restricted user account (like www-data), never as root.
Docker Deployment
Containerize the application for portable deployment.
Dockerfile
Create a Dockerfile in the project root:
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY dev-showcase.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 8080
EXPOSE 8081
ENV ASPNETCORE_URLS=http://+:8080
ENV ASPNETCORE_ENVIRONMENT=Production
ENTRYPOINT [ "dotnet" , "dev-showcase.dll" ]
Build and Run
# Build image
docker build -t dev-showcase:latest .
# Run container
docker run -d \
--name dev-showcase \
-p 8080:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
dev-showcase:latest
# View logs
docker logs dev-showcase
Create docker-compose.yml: version : '3.8'
services :
web :
build : .
ports :
- "8080:8080"
environment :
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:8080
restart : unless-stopped
Deploy:
Environment Configuration
Set critical environment variables for production:
Required Variables
# Environment
ASPNETCORE_ENVIRONMENT = Production
# URLs (if not using default 5000/5001)
ASPNETCORE_URLS = http://+:8080 ; https://+:8443
# Forwarded headers (behind reverse proxy)
ASPNETCORE_FORWARDEDHEADERS_ENABLED = true
Logging Configuration
Update appsettings.Production.json:
{
"Logging" : {
"LogLevel" : {
"Default" : "Warning" ,
"Microsoft.AspNetCore" : "Warning" ,
"Microsoft.Hosting.Lifetime" : "Information"
}
},
"AllowedHosts" : "your-domain.com"
}
Use structured logging with providers like Azure Application Insights, Seq, or Serilog for production monitoring.
HTTPS Configuration
Certificate Options
Free SSL certificates with automatic renewal: sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
Azure App Service provides free managed certificates:
Navigate to TLS/SSL settings
Add Private Key Certificate
Select “Create App Service Managed Certificate”
Use your own certificate: builder . WebHost . ConfigureKestrel ( options =>
{
options . ConfigureHttpsDefaults ( httpsOptions =>
{
httpsOptions . ServerCertificate =
new X509Certificate2 ( "certificate.pfx" , "password" );
});
});
HSTS Configuration
From Program.cs:8:
HTTP Strict Transport Security (HSTS) forces HTTPS connections. Configured in production mode only.
Monitoring and Logging
Health Checks
Add health check endpoints:
builder . Services . AddHealthChecks ();
app . MapHealthChecks ( "/health" );
Application Insights
For Azure deployments:
dotnet add package Microsoft.ApplicationInsights.AspNetCore
builder . Services . AddApplicationInsightsTelemetry ();
Log Aggregation
Common log destinations:
File logs : Write to /var/log/dev-showcase/
Serilog : Structured logging to multiple sinks
Azure Monitor : Cloud-native monitoring
ELK Stack : Elasticsearch, Logstash, Kibana
Production Best Practices
Security
Enable HTTPS only
Configure AllowedHosts
Use secure headers
Regular security updates
Performance
Enable response compression
Configure output caching
Use CDN for static assets
Monitor application metrics
Reliability
Configure health checks
Set up automatic restarts
Implement graceful shutdown
Use load balancing
Maintenance
Automated backups
Blue-green deployments
Rolling updates
Rollback procedures
Troubleshooting
Check the logs for startup errors: # Systemd
sudo journalctl -u dev-showcase -n 50
# Docker
docker logs dev-showcase
# Azure
az webapp log tail --name dev-showcase-portfolio --resource-group myResourceGroup
Verify the application is running: sudo systemctl status dev-showcase
curl http://localhost:5000
Check Nginx proxy configuration and firewall rules.
Ensure static file middleware is configured: app . UseStaticFiles ();
app . MapStaticAssets ();
Verify files are included in the publish output.
Check that wwwroot/languages/ directory is published: ls publish/wwwroot/languages/
Should contain en.json and es.json.
Next Steps
Building Learn about the build process
Customization Customize your portfolio