-
Notifications
You must be signed in to change notification settings - Fork 88
Description
The Problem
Azure App Service for Linux does not properly integrate with .NET application lifecycle hooks when stopping or restarting applications. Specifically:
az webapp stop does NOT:
- Send SIGTERM to the running container
- Trigger
IHostApplicationLifetime.ApplicationStopping - Call
BackgroundService.StopAsync()methods - Allow any graceful shutdown whatsoever
The application process is simply killed at the infrastructure level without any notification to the application code.
Why This Matters
Modern .NET applications use built-in lifecycle hooks for critical cleanup operations:
- Completing in-flight work
- Releasing database connections
- Flushing logs and telemetry
- Releasing distributed locks
- Gracefully stopping background services
- Preventing data corruption
These are not "nice-to-have" features - they are core patterns in ASP.NET Core that Microsoft itself promotes and documents extensively.
The Disconnect
Microsoft provides:
- Comprehensive documentation on graceful shutdown in .NET
IHostApplicationLifetimeAPIs specifically for shutdown hooksBackgroundServicebase class withStopAsync()methods- App Service as a managed hosting platform for .NET
But Azure App Service doesn't actually honor these lifecycle contracts when you stop or restart the service.
Current "Solutions" Are Inadequate
Deployment Slots: Not viable when your application cannot have multiple instances running simultaneously (exclusive locks, singleton processing, queue consumers, etc.)
Manual Workarounds: Developers are forced to:
- Call Kudu APIs to manually kill processes
- Implement custom shutdown endpoints
- Add complex orchestration logic to GitHub Actions
- Hope that deployment triggers proper shutdown (it often doesn't)
This is unacceptable for a Microsoft hosting platform running Microsoft frameworks.
Impact on Developer Experience
This creates:
- Frustration and wasted time troubleshooting why "standard" .NET patterns don't work
- Loss of confidence in Azure as a reliable platform
- Production issues from incomplete shutdown (data loss, corruption, orphaned resources)
- Complexity - developers forced to implement workarounds for basic functionality that should "just work"
- Bad impressions of Azure compared to competitors where lifecycle management works correctly
What Should Happen
When a developer runs az webapp stop or az webapp restart:
- Azure should send SIGTERM to the container (standard Docker practice)
- The .NET runtime should receive this and trigger
ApplicationStopping - Background services should have their
StopAsync()methods called - The application should have time (configurable via
WEBSITES_CONTAINER_STOP_TIME_LIMIT) to complete shutdown - Only then should the process be forcefully killed if needed
This is how Docker containers work. This is how Kubernetes works. This is how every other container platform works. Azure App Service should work this way too.
The Ask
Microsoft needs to:
- Fix the integration between App Service infrastructure commands and container lifecycle
- Document the current behavior honestly - don't pretend graceful shutdown works when it doesn't
- Provide a supported solution for single-instance applications that need graceful shutdown
- Test these scenarios - clearly this workflow was never properly tested with real .NET applications
Conclusion
It is utterly ridiculous that deploying a .NET application to Microsoft's own managed hosting platform requires custom workarounds to achieve basic lifecycle management that works correctly on every other container platform.
This is not about "fancy bumpless parallelism" or zero-downtime deployments. This is about basic application lifecycle management - starting and stopping an application cleanly. Microsoft promotes these patterns in .NET, documents them extensively, and then their own hosting platform doesn't support them.
This severely impacts impressions of Azure's usability and maturity as a platform. When developers can't rely on fundamental contracts between the framework and the hosting environment, trust in the entire ecosystem is damaged.
TL;DR: az webapp stop should trigger graceful shutdown in .NET applications. It doesn't. This is a critical gap that forces developers into hacky workarounds for basic functionality that should work out of the box on a Microsoft platform hosting Microsoft frameworks.