Skip to main content

Hosting: Windows Service vs IIS

Erde installs in one of two hosting shapes: a Windows Service or behind IIS (Internet Information Services). You pick the shape at install time on the MSI's Deployment Configuration screen. This page explains how each shape works and which one to choose. Both run the same server binary — the difference is only what sits in front of it.

Both shapes run the same server

In both shapes, the Kestrel web server serves the full application. Kestrel handles the API routes (/api/*), the Blazor WebAssembly client (static files from the sibling client\wwwroot\ directory), and the single-page-application fallback (index.html for client-side routing). The only thing that changes between shapes is what process hosts Kestrel and what sits in front of it. Both shapes serve on the same HTTP port (default 5000) and against the same database.

The Server project wires Windows-Service hosting in unconditionally — Program.cs always calls UseWindowsService() with service name Erde. IIS hosting is configured separately at install time when you choose IIS mode; the same binary then runs in-process inside the IIS worker process.

Figure: In both shapes Kestrel serves the API and the client; IIS only adds a worker process in front of it.

How the two shapes compare

AspectWindows ServiceIIS
Best forSmall firm (1–5 users), single officeMulti-office, field crews, 5+ users
ProcessErde.Server.exe (standalone)w3wp.exe (IIS worker process)
How Kestrel runsDirectly, via UseWindowsService()In-process, via ASP.NET Core Module v2 (ANCM)
Port binding--urls http://0.0.0.0:{port}IIS site binding on {port}
Process managementWindows Service Control Manager (auto-restart on failure)IIS app pool (health monitoring, crash restart)
Environment variableRegistry key under the service<environmentVariable> in web.config
Static filesKestrel UseStaticFiles middlewareSame — Kestrel middleware, not IIS
NetworkLAN or VPN onlyLAN, VPN, or internet-facing
SSL / HTTPSRequires a reverse proxy (Caddy, etc.)IIS Manager built-in certificate UI
PrerequisitesNone beyond the .NET runtimeIIS enabled before install
ComplexityLow — runs as a background serviceModerate — IIS must be enabled first

In IIS mode, the IIS site points directly at the api\ folder. ANCM loads the .NET runtime in-process within w3wp.exe and hands all requests to Kestrel. There is no separate client site and no virtual directory or application for the client — the client\ folder is never an IIS application. The API's web.config sets <httpErrors existingResponse="PassThrough" /> so ASP.NET Core error responses (such as 451 license errors) reach the browser unchanged, sets ASPNETCORE_ENVIRONMENT to Production, and uses hostingModel="inprocess". This in-process IIS hosting shape is distinct from putting a separate IIS or proxy in front of the Windows Service shape (out-of-process); for that case, see Put Erde behind a reverse proxy for HTTPS.

In Windows Service mode, the MSI installs a service named Erde (display name Erde Environmental Data Management) running as LocalSystem with start type Automatic. Its recovery policy restarts the service after 3 seconds on all failures, and it starts with the arguments --urls http://0.0.0.0:{port}. The ASPNETCORE_ENVIRONMENT=Production value is set through a registry key under the service instead of a web.config.

When to choose each

Choose Windows Service for a small firm — roughly 1–5 users in a single office on a LAN or VPN. It needs nothing beyond the .NET 10 Hosting Bundle and runs as a background service that the Windows Service Control Manager keeps alive. If you need HTTPS in this shape, put a reverse proxy (such as Caddy) in front of Erde.

Choose IIS for multi-office work, field crews, or 5 or more users, including internet-facing deployments. IIS gives you the app pool's health monitoring and crash restart and lets you manage TLS certificates from IIS Manager's built-in UI. IIS must be enabled before you install the .NET 10 Hosting Bundle; if it was enabled afterward, run a repair install of the Hosting Bundle so ANCM registers with IIS.

The installer configures the Erde app pool to run continuously: idle timeout and periodic recycling are disabled, the pool's start mode is AlwaysRunning, and the application is preloaded. IIS's defaults (a 20-minute idle stop and a 29-hour recycle) would silently stop the in-memory background import queue, so leave these settings as installed.

Verify the keep-alive settings after an IIS install

The start-mode and preload settings are applied by a best-effort installer step that is not rolled back if it fails. After an IIS install, confirm them — and re-apply if either is wrong:

& "$env:windir\System32\inetsrv\appcmd.exe" list apppool "Erde" /text:startMode # expect: AlwaysRunning
& "$env:windir\System32\inetsrv\appcmd.exe" list app "Erde/" /text:preloadEnabled # expect: true
note

The hosting shape is set per install, not stored in the database. To switch shapes, uninstall Erde and reinstall, picking the other option on the Deployment Configuration screen.

After the MSI finishes, the server still needs first-run configuration. On first start, with no appsettings.Production.json present, it boots into setup mode and serves the wizard at /setup regardless of which hosting shape you chose. See First-run setup.

Run a single worker process

Whichever shape you choose, run Erde as exactly one worker process: one Windows Service instance, or one IIS worker process. In IIS, leave the application pool's Maximum Worker Processes at 1 — do not enable a web garden — and do not load-balance several Erde nodes against the same database.

Erde keeps caches in process memory, including the per-user authorization access maps that back Site- and Project-level permissions. When an administrator changes a user's roles or access, the process that handled the change drops that user's cached map immediately — but a second worker process has its own cache and keeps serving the old permissions until its copy expires, up to five minutes later.