Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from: https://blog.jermdavis.dev/posts/2023/configure-iis-recycle-containers

Configuring IIS Recycling in containers

If you don't have the UI, how do you do this?

Published 11 September 2023

I had another "things work differently in containers" moment recently. One of the fun points of changing the approach to your deployments is that sometimes you have to look differently at how some core configuration issues too. And this seems like an issue others will encounter too:

The issue

A project I was working recenly on had a long-running background process which would occasionally get terminated unexpectedly. Running on the Sitecore CM server role, it was processing some data import - but we were seeing failures to complete the job. After a bit of debugging, it turned out that these terminations were coinciding with IIS choosing to recycle the worker process for the website, which pointed us towards the underlying cause being the default behaviour of IIS where it recycles a worker process every 29 hours...

(Why 29 hours? Apparently it's because it's the smallest prime number of hours after 24. So now you know...)

Anyway, most developers are used to configuring this sort of thing via the IIS Manager tool. Right-clicking your site's application pool gives an option for "Recycling":

The Recycling Conditions dialog from IIS Manager, showing the default 'recycle every 1740 minutes' setting

If you don't want the automatic recycle, you can uncheck that first option, and you're good to go...

But if you're running your site in containers you don't have access to this UI. So what's the right approach to managing this if you're building your app for Docker and/or Kubernetes?

How to fix it

Under the surface, IIS keeps the data for .Net Apps in the ApplicationHost.config file. Under <system.applicationHost/> and <applicationPools/> there's an element for each app pool. That has an optional <recycling/> element which can define the behaviour you want. By default your config file won't have this recycle config - so to go this way you need to add it yourself.

This is doable, but patching an XML config file that ships in a base image, as part of your docker build process is a bit of a pain to set up. Is there an easier way?

Well yes - there is: PowerShell can help you here.

PowerShell has a module called WebAdministration which can help you manage settings in IIS. Once that's enabled you can use the Set-ItemProperty command to change the settings of an app pool.

You want the change to be in effect every time your image is run, so you want to set this up in your Dockerfile for the relevant role(s). You can add something like:

RUN Import-Module WebAdministration; `
    Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name Recycling.periodicRestart.time -Value 0.00:00:00;

					

Note the trailing back-tick character on that RUN line - it's necessary to ensure that both of the commands here run in the same context.

Also note that the -Name parameter can be a bit fiddly about case - the capital R in periodicRestart seems to be required for certain PowerShell and Windows Server versions, according to some comments I've seen.

You can set the -Value here to whatever recycle timespan you want here. The format is d.hh:mm:ss and zero implies no automatic recycling.

And once that's in place you can rebuild your image and this behaviour will be in place. To check, you can connect to PowerShell in a container based on the image:

docker exec -it myproject_cm_1 powershell

					

And then once that session starts up, ask what the value of this setting is:

Import-Module WebAdministration
Get-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name Recycling.periodicRestart.time

					

That should return "zero" after the change above is applied:

The result of the Get-ItemProperty command above, showing the restart time set to zero

And your container should no longer recycle itself...

↑ Back to top