> For the complete documentation index, see [llms.txt](https://docs.appstrategy.com/apprules-r-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.appstrategy.com/apprules-r-documentation/platform/self-hosting/software-installation/iis-setting.md).

# IIS Settings

## appRulesPortal — IIS Setup Guide

### .NET 8 / Wisej 4 / Windows Server

> **Note:** As of .NET 8, appRulesPortal runs as a **self-hosted Kestrel Windows Service** and does **not require IIS** to operate. IIS is optional and only needed if you want to use it as a **reverse proxy** in front of Kestrel — for example, to handle SSL termination on port 443 and forward traffic to Kestrel on port 8080, or to host multiple sites on the same server on port 80/443.
>
> If you are deploying appRulesPortal as a standalone Windows Service (the default), skip this guide and see [HostService Settings](/apprules-r-documentation/platform/self-hosting/software-installation/hostservice.md) instead.

***

### 1. Server Prerequisites

#### Install the .NET 8 Hosting Bundle

The Hosting Bundle installs the .NET 8 runtime **and** the ASP.NET Core Module v2 (ANCM) into IIS. Without it, IIS cannot forward requests to the Kestrel process.

1. Download from: <https://dotnet.microsoft.com/en-us/download/dotnet/8.0\\>
   → Look for **".NET 8 Hosting Bundle"** (not the SDK, not the Runtime alone)
2. Run the installer as Administrator
3. After installation, run the following to confirm ANCM is registered:

   ```
   %windir%\system32\inetsrv\appcmd list modules | findstr AspNetCore
   ```

   Expected output:

   ```
   MODULE "AspNetCoreModuleV2" (image:...aspnetcorev2.dll)
   ```
4. If IIS was already running before the install, restart it:

   ```bat
   iisreset /restart
   ```

#### Enable IIS Features (Windows Server)

Open **Server Manager → Add Roles and Features → Web Server (IIS)**\
Ensure these features are enabled:

| Feature            | Path                    | Required for                |
| ------------------ | ----------------------- | --------------------------- |
| Web Server         | Web Server (IIS)        | Base IIS                    |
| Static Content     | Common HTTP Features    | Serving JS, CSS, fonts      |
| Default Document   | Common HTTP Features    | Serving Default.html        |
| HTTP Errors        | Common HTTP Features    | Error pass-through          |
| Request Filtering  | Security                | Request size limits         |
| WebSocket Protocol | Application Development | **Wisej real-time sync**    |
| ASP.NET 4.x        | Application Development | Not required — but harmless |

> ⚠️ **WebSocket Protocol is mandatory for Wisej.**\
> Without it, Wisej falls back to long-polling — all users will experience\
> significantly degraded performance and higher server CPU.

To enable WebSocket via PowerShell (run as Administrator):

```powershell
Install-WindowsFeature Web-WebSockets
# or on Windows 10/11:
Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebSockets
```

***

### 2. Create the Application Directory

```bat
mkdir C:\inetpub\appRulesPortal
mkdir C:\inetpub\appRulesPortal\logs
```

Copy the full Release build output to this folder. When using IIS as a reverse proxy, the physical path points to the site root (one level above `bin\`), not to `bin\` itself. The Kestrel service still serves the actual requests — IIS only forwards them. See `RELEASE_DEPLOYMENT.md` for the complete file/folder structure.

***

### 3. Create the Application Pool

Open **IIS Manager → Application Pools → Add Application Pool**

| Setting               | Value               |
| --------------------- | ------------------- |
| Name                  | `appRulesPortal`    |
| .NET CLR Version      | **No Managed Code** |
| Managed Pipeline Mode | Integrated          |

After creation, select the pool → **Advanced Settings**:

| Setting                         | Value                                       | Reason                                             |
| ------------------------------- | ------------------------------------------- | -------------------------------------------------- |
| Start Mode                      | `AlwaysRunning`                             | Wisej must always be running — do not lazy-start   |
| Idle Time-out (minutes)         | `0`                                         | Disable — idle shutdown kills active user sessions |
| Regular Time Interval (minutes) | `0`                                         | Disable periodic recycling during business hours   |
| Identity                        | `ApplicationPoolIdentity` or domain account | See permissions below                              |

> ⚠️ **Never enable idle timeout or periodic recycling for a Wisej application.**\
> Recycling the App Pool disconnects all active browser sessions immediately.\
> If recycling is required for memory management, schedule it outside business hours\
> using a Specific Time recycle instead.

***

### 4. Set Folder Permissions

The App Pool identity must have the following permissions on the site root:

```bat
REM Replace "IIS AppPool\appRulesPortal" with your domain account if applicable
icacls "C:\inetpub\appRulesPortal"       /grant "IIS AppPool\appRulesPortal:(OI)(CI)R"
icacls "C:\inetpub\appRulesPortal\logs"  /grant "IIS AppPool\appRulesPortal:(OI)(CI)M"
icacls "C:\inetpub\appRulesPortal\App_Data" /grant "IIS AppPool\appRulesPortal:(OI)(CI)M"
```

| Folder          | Permission | Reason                          |
| --------------- | ---------- | ------------------------------- |
| Site root (`\`) | Read       | Serve static files, load config |
| `bin\`          | Read       | Load assemblies                 |
| `logs\`         | Modify     | ANCM writes stdout logs         |
| `App_Data\`     | Modify     | Application data read/write     |

***

### 5. Create the IIS Site

#### Option A — IIS Manager (GUI)

1. Open **IIS Manager → Sites → Add Website**
2. Fill in:

| Field            | Value                                   |
| ---------------- | --------------------------------------- |
| Site name        | `appRulesPortal`                        |
| Application pool | `appRulesPortal` (created above)        |
| Physical path    | `C:\inetpub\appRulesPortal`             |
| Binding type     | `http` (add `https` binding separately) |
| Port             | `80` (or your designated port)          |
| Host name        | `yourserver.yourdomain.com`             |

3. Click **OK**

#### Option B — PowerShell

```powershell
Import-Module WebAdministration

New-WebAppPool -Name "appRulesPortal"
Set-ItemProperty IIS:\AppPools\appRulesPortal managedRuntimeVersion ""
Set-ItemProperty IIS:\AppPools\appRulesPortal startMode "AlwaysRunning"
Set-ItemProperty IIS:\AppPools\appRulesPortal processModel.idleTimeout "00:00:00"

New-Website -Name "appRulesPortal" `
            -PhysicalPath "C:\inetpub\appRulesPortal" `
            -ApplicationPool "appRulesPortal" `
            -Port 80 `
            -HostHeader "yourserver.yourdomain.com"
```

***

### 6. Configure HTTPS (Recommended)

#### Bind an SSL Certificate

1. In IIS Manager, select the server node → **Server Certificates**
2. Import your certificate (PFX) or request one via IIS
3. On the site → **Bindings → Add**:

| Field           | Value                       |
| --------------- | --------------------------- |
| Type            | `https`                     |
| Port            | `443`                       |
| Host name       | `yourserver.yourdomain.com` |
| SSL certificate | *(select your certificate)* |

#### Force HTTPS Redirect

Add to `web.config` inside `<system.webServer>`:

```xml
<rewrite>
  <rules>
    <rule name="HTTP to HTTPS" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
              redirectType="Permanent" />
    </rule>
  </rules>
</rewrite>
```

> Requires IIS URL Rewrite Module: <https://www.iis.net/downloads/microsoft/url-rewrite>

***

### 7. Verify the Deployment

#### Check ANCM is handling requests

Browse to `http://yourserver/` — you should see `Default.html` (the Wisej login page).

#### Quick verification checklist

| Test                            | Expected Result                                              |
| ------------------------------- | ------------------------------------------------------------ |
| `GET /`                         | Wisej login page loads                                       |
| `GET /Default.html`             | Same login page                                              |
| `GET /appsettings.json`         | HTTP 403 Forbidden                                           |
| `GET /Default.json`             | HTTP 200 (Wisej config — intentionally public)               |
| Login with valid credentials    | Main portal opens                                            |
| Open browser DevTools → Network | WebSocket connection established (`101 Switching Protocols`) |

#### Confirm WebSocket is working

In browser DevTools (F12) → Network tab → filter by **WS**:

* You should see a WebSocket connection to `ws://yourserver/...`
* Status should be `101 Switching Protocols`
* If you see repeated XHR polling requests instead, WebSocket is not working — check the IIS WebSocket Protocol feature

***

### 8. Startup Failure Diagnosis

If the site returns **HTTP 500.30** or a blank page:

1. Temporarily enable stdout logging in `web.config`:

   ```xml
   stdoutLogEnabled="true"
   ```
2. Ensure `.\logs\` folder exists and is writable by the App Pool identity
3. Recycle the App Pool:

   ```bat
   %windir%\system32\inetsrv\appcmd recycle apppool /apppool.name:"appRulesPortal"
   ```
4. Browse to the site to trigger the failure
5. Check `.\logs\stdout_*.log` for the exception
6. **Set `stdoutLogEnabled="false"` immediately after** — stdout logging is unbounded and will fill disk

#### Common causes

| Error                             | Cause                                  | Fix                                             |
| --------------------------------- | -------------------------------------- | ----------------------------------------------- |
| `500.19`                          | Malformed `web.config`                 | Validate XML syntax                             |
| `500.30`                          | App failed to start                    | Check stdout log                                |
| `500.35`                          | ANCM in-process handler load failure   | Reinstall .NET 8 Hosting Bundle                 |
| `403.14`                          | Directory browsing                     | Set default document to `Default.html`          |
| Blank page / no Wisej             | Wrong `arguments` path in `web.config` | Confirm `.\bin\appRulesPortal.dll` exists       |
| Long-polling instead of WebSocket | WebSocket feature not installed        | Enable IIS WebSocket Protocol                   |
| License warning banner            | Wrong or missing Wisej license key     | Check `Default.json` → `Wisej.LicenseKey`       |
| Sessions drop on recycle          | App Pool idle timeout or recycling     | Set idle timeout to 0, disable periodic recycle |

***

### 9. Maintenance

#### Recycling the App Pool (planned)

```bat
REM Graceful recycle — active sessions will disconnect
%windir%\system32\inetsrv\appcmd recycle apppool /apppool.name:"appRulesPortal"
```

Schedule maintenance windows outside business hours.

#### Deploying an Update

```bat
REM 1. Stop the site
%windir%\system32\inetsrv\appcmd stop site /site.name:"appRulesPortal"

REM 2. Copy new bin\ contents
xcopy /Y /I /Q "C:\builds\appRulesPortal\bin\*" "C:\inetpub\appRulesPortal\bin\"

REM 3. Copy updated config files if changed
copy /Y "C:\builds\appRulesPortal\web.config"        "C:\inetpub\appRulesPortal\"
copy /Y "C:\builds\appRulesPortal\appsettings.json"   "C:\inetpub\appRulesPortal\"
copy /Y "C:\builds\appRulesPortal\Default.json"       "C:\inetpub\appRulesPortal\"

REM 4. Start the site
%windir%\system32\inetsrv\appcmd start site /site.name:"appRulesPortal"
```

***

### Related Documents

| Document                              | Purpose                                          |
| ------------------------------------- | ------------------------------------------------ |
| `RELEASE_DEPLOYMENT.md`               | Primary deployment guide — Windows Service setup |
| `WindowsService-DepsJson-Patching.md` | deps.json patching guide                         |
| `deploy_appRulesPortal.ps1`           | Automated deployment script                      |

***

### Reference

| Item                    | Value                                                                       |
| ----------------------- | --------------------------------------------------------------------------- |
| .NET 8 Hosting Bundle   | <https://dotnet.microsoft.com/en-us/download/dotnet/8.0>                    |
| IIS URL Rewrite Module  | <https://www.iis.net/downloads/microsoft/url-rewrite>                       |
| Wisej deployment docs   | <https://docs.wisej.com/deployment/targets/iis>                             |
| Wisej self-hosting docs | <https://docs.wisej.com/deployment/targets/self-hosting>                    |
| ANCM troubleshooting    | <https://learn.microsoft.com/en-us/aspnet/core/test/troubleshoot-azure-iis> |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.appstrategy.com/apprules-r-documentation/platform/self-hosting/software-installation/iis-setting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
