Once upon a time before Functions, we had Web Jobs on Azure App Services and the 'engine' behind it was Kudu. I originally planned to detail this out last year but with the project now archived by MS it was now or never.

Kudu is not dead, the repo and Azure were never like for like. The addition of support for Linux & containers, means it's evolving. On Windows it was truly a showcase for the capabilities of IIS.

Now for the disclaimer. Kudu was built to support Azure PaaS and work within the Azure App Service's sandbox so somethings may not work without tweaking or never work such as RUN FROM PACKAGE/ZIP which I wish came to IIS as my anecdotal observation is that the read-only aspect provides a perf improvement across tech stacks & platforms.

One of Kudu's initial developers, David Ebbo did a post on running Kudu locally. The other David Fowler, needs no introduction.
The gist is you need Node.js & Git on the Windows instance where Kudu is going to be deployed.

The next step is to clone the repo & build it, but if you're lazy and run random things from random people, I've already done it for you. You do you boo.
Now we have to create the folders for Kudu, you can customise the path but we are just going with the defaults.

C:\kudu\apps
C:\kudu\Kudu.Services.Web
C:\kudu\wwwroot
Assign IIS_IUSRS full control for C:\kudu\

From the S100 archive copy the contents from:
\KuduWeb to C:\kudu\wwwroot
\SiteExtensions\Kudu to C:\kudu\Kudu.Services.Web
The apps dir is where new sites will be created.
You should have a structure like

C:\kudu
├───apps
├───Kudu.Services.Web
│   │   commit.txt
│   │   Default.cshtml
│   │   Env.cshtml
│   │   favicon.ico
│   │   package-lock.json
│   │   package.json
│   │   scmApplicationHost.xdt
│   │   updateNodeModules.cmd
│   │   Web.config
│   │   WebHooks.cshtml
│   │   _Layout.cshtml
│   ├───bin
│   ├───Content
│   ├───DebugConsole
│   ├───Detectors
│   ├───node_modules
│   ├───ProcessExplorer
│   ├───SiteExtensions
│   ├───Support
│   └───ZipDeployUI
└───wwwroot
    │   Global.asax
    │   packages.config
    │   Web.config
    ├───App_Data
    ├───bin
    ├───Content
    ├───fonts
    ├───images
    ├───Scripts
    └───Views

The script for updateNodeModules.cmd which will create the node_modules dir under Kudu.Services.Web

@echo off
setlocal enabledelayedexpansion

pushd %1

set attempts=5
set counter=0

:retry
set /a counter+=1
echo Attempt %counter% out of %attempts%

cmd /c npm install https://github.com/projectkudu/KuduScript/tarball/aadbe2bd33543483dd9659d35fc591a992e7aa6f
IF %ERRORLEVEL% NEQ 0 goto error

goto end

:error
if %counter% GEQ %attempts% goto :lastError
goto retry

:lastError
popd
echo An error has occurred during npm install.
exit /b 1

:end
popd
echo Finished successfully.
exit /b 0

Now to tweak the web.config files. You can read the wiki to know what these configs do as they're not there by default

C:\kudu\Kudu.Services.Web\web.config

  <appSettings>
    <add key="SCM_SKIP_SSL_VALIDATION" value="1" />
    <add key="SCM_TRACE_LEVEL" value="4" />
    <add key="SCM_NO_REPOSITORY" value="1" />
    <add key="SCM_DO_BUILD_DURING_DEPLOYMENT" value="0" />
    <add key="WEBSITE_DISABLE_SCM_SEPARATION" value="1" /> 
    <add key="WEBJOBS_HISTORY_SIZE" value="100" /> 
    
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="true" />
    <add key="webactivator:assembliesToScan" value="Kudu.Services.Web" />
  </appSettings>

C:\kudu\wwwroot\web.config

  <kudu.management enableCustomHostNames="true">
    <serviceSite path="..\Kudu.Services.Web" />
    <applications path="..\apps" />

Time to create Kudu's admin app pool in IIS.
Note the identity is LocalSystem and recycling has been 'disabled' so that aspects like Web Jobs can run without issues based on your cron config.
kudu-admin app pool

After the app pool is created, we need to create the website.
The physical path being C:\kudu\wwwroot, you can bind a random port on localhost
kudu-admin site

Afterwards we can browse to kudu-admin to create an app.
kudu-admin dashboard
kudu-admin create app

Kudu when creating an app will create the website and the scm aspect.
website => contoso.azurewebsites.net
website kudu => contoso.scm.azurewebsites.net
These settings such as site bindings(DNS) if added will reflect in IIS Manager.
app created
app site-bindings

website
website
website-scm(Kudu)
scm-website

Apps are created using ApplicationPoolIdentity. Now the choice is yours, if you don't want the typical features of Kudu like access to the file system to drag & drop files, executing commandline/powershell scripts etc. Then you're good to go otherwise hence the creation of the 'admin' app. The app pool just needs to be set to kudu-admin which we initally created with LocalSystem privileges.
Remember Kudu has no authentication or authorisation, that's handled by the Azure layer in-front of it.
created-app app-pool

The debug console is awesome but if the clicking is too much, you can quickly navigate the virtual file system by using the console in your browser's dev tools.

var v = viewModel.selected();
v.href = 'https://scm-kudu.local/api/vfs/SystemDrive/Windows/system32/drivers/etc/';
updateSelectedAndNotifyCommandLine(v);

Site extensions also work. Like if you have the iis-node module enabled, you can use something like the Monaco Editor. Since that's not publically available I can't share it so just download the source from your Azure Web App & you'll figure it out.
Monaco Editor

And yes, since Functions are an evolution of Web Jobs, they can also be run outside of Azure but that's a post for another time.