(Docker, Nginx, HTTPS & Production Best Practices)
Writing code is only half the job.
Deployment, security, and reliability decide whether your ASP.NET Core application survives in production.
In this article, we’ll deploy an ASP.NET Core API using Docker, secure it with Nginx + HTTPS, and apply real-world production hardening techniques.
Production Deployment Architecture
Client (Browser / Mobile)
↓ HTTPS
Nginx (Reverse Proxy)
↓
ASP.NET Core (Docker)
↓
Database / CacheWhy Use Docker?
- Environment consistency
- Easy scaling
- Faster deployments
- CI/CD friendly
Step 1: Create Dockerfile for ASP.NET Core
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o out
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/out .
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]Step 2: Docker Compose Setup
version: "3.9"
services:
api:
image: myapp-api
container_name: aspnet_api
restart: always
ports:
- "8080:8080"
environment:
ASPNETCORE_ENVIRONMENT: ProductionStep 3: Run the Application
docker build -t myapp-api .
docker compose up -dYour API is now running at:
http://localhost:8080Step 4: Nginx as Reverse Proxy
Nginx handles:
- SSL termination
- Rate limiting
- Load balancing
- Security headers
Nginx Configuration
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}Step 5: Enable HTTPS (Let’s Encrypt)
Install Certbot
sudo apt install certbot python3-certbot-nginxGenerate SSL Certificate
sudo certbot --nginx -d api.example.com✔ Auto-renewal is configured by default.
Step 6: Enforce HTTPS & Security Headers
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";Step 7: ASP.NET Core Production Configuration
appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}Step 8: Secure Application Secrets
❌ Never store secrets in code
Use Environment Variables
export ConnectionStrings__Default="Server=db;..."
export Jwt__Key="super_secret_key"Step 9: Health Checks
builder.Services.AddHealthChecks();
app.MapHealthChecks("/health");Used by:
- Load balancers
- Monitoring systems
Step 10: Logging & Monitoring
Use Structured Logging
- Serilog
- Seq
- ELK Stack
Log.Information("User {UserId} logged in", userId);Step 11: Security Hardening Checklist
✅ HTTPS only
✅ Short-lived JWTs
✅ Refresh token rotation
✅ Rate limiting
✅ CORS configuration
✅ Secure cookies
✅ Database backups
✅ Firewall rules
Step 12: Zero-Downtime Deployment (Basic Strategy)
docker compose pull
docker compose up -d --no-deps apiFor advanced setups:
- Blue–Green deployments
- Kubernetes rolling updates
Common Production Mistakes
❌ Running as root
❌ No HTTPS
❌ No monitoring
❌ Hardcoded secrets
❌ No backup strategy
Final .NET Production Stack (Recommended)
| Layer | Tool |
| ------------- | -------------- |
| API | ASP.NET Core |
| Reverse Proxy | Nginx |
| Container | Docker |
| SSL | Let’s Encrypt |
| Logging | Serilog |
| CI/CD | GitHub Actions |
🎉 Series Wrap-Up
You’ve completed a 12-week ASP.NET Core mastery journey:
- ✔ Fundamentals
- ✔ Security
- ✔ Testing
- ✔ Deployment
You can now build real-world, secure, production-ready .NET applications.