Installation in Windows Containers (Docker and Kubernetes)
Audience:
System/Security AdministratorsSkill Prerequisites:
System Administration and Maintenance,Docker,Windows Server
Plant an App can run in Windows Server containers, on your own servers or in the cloud. The container runs IIS and Plant an App, the same way as an installation on Windows Server. The database stays on SQL Server, outside the container.
This page shows how to:
- Prepare a container host with Windows Server 2022 or 2025
- Build the Plant an App image from Microsoft's official ASP.NET image
- Run it with Docker on-premises
- Run it on Kubernetes, on-premises or in the cloud (Azure AKS, Amazon EKS)
Architecture
| Part | Where it runs | Notes |
|---|---|---|
| Web container | Windows Server Core container with IIS and ASP.NET 4.8 | Runs Plant an App. You can run one or more. |
| Site files | A persistent volume, mounted into the container at C:\inetpub\wwwroot | Plant an App writes to the site folder during installation, upgrades and normal work, so it must survive container restarts. |
| Database | SQL Server, outside the containers | A SQL Server VM, cluster or managed service. Back it up as usual. |
| TLS / load balancer | In front of the containers | Ends HTTPS and spreads traffic when several containers run. |
Because the site files and the database live outside the container, a container can be replaced at any time, for example to apply Windows updates, without losing data.
Plant an App runs on .NET Framework, so it needs Windows containers. It doesn't run in Linux containers, and Windows containers can't run on a Linux host.
Requirements
| Item | Requirement |
|---|---|
| Container host | Windows Server 2022 or Windows Server 2025, with the Containers feature. For development and testing only: Windows 10 or 11 Pro / Enterprise with Docker Desktop in Windows containers mode. |
| Container runtime | Docker Engine for Windows (or Mirantis Container Runtime), or containerd on Kubernetes nodes |
| Base image | mcr.microsoft.com/dotnet/framework/aspnet:4.8.1-windowsservercore-ltsc2022 or …-ltsc2025 (Microsoft) |
| SQL Server | As for the standard installation, reachable from the containers over the network |
| Hardware | As for the standard installation, per container. Add disk space for images: a Windows Server Core image takes several GB. |
| Plant an App | The Plant an App installation package (PlantAnApp_<version>.zip), from Plant an App support |
Match the image to the host
Windows containers share the host's kernel, so the image version must match the host:
| Host | Image tag | Isolation |
|---|---|---|
| Windows Server 2022 | ltsc2022 | process (recommended) |
| Windows Server 2025 | ltsc2025 | process (recommended) |
| Windows Server 2025 | ltsc2022 | hyperv only |
| Windows 10 / 11 (development) | ltsc2022 or ltsc2025 | hyperv |
With process isolation, the container runs directly on the host kernel and uses the least memory. Hyper-V isolation runs each container in a small virtual machine, which lets an older image run on a newer host. See Microsoft's Windows container version compatibility.
1. Prepare the Container Host
-
Install Windows Server 2022 or 2025 with the latest updates.
-
Install the Containers feature and a container runtime, following Microsoft's guide Get started: Prep Windows for containers.
-
Check that Windows containers work:
docker versiondocker run --rm mcr.microsoft.com/windows/servercore:ltsc2022 cmd /c verUse
ltsc2025on Windows Server 2025. -
Create a folder with a short path for the site files, for example
D:\PlantAnApp\site. See Site folder path length.
2. Build the Image
The image adds the IIS settings that Plant an App needs to Microsoft's ASP.NET 4.8 image. It doesn't contain the site itself: the site files stay on the volume.
Create a folder, for example D:\PlantAnApp\image, with these two files.
Dockerfile
# escape=`
ARG WINDOWS_VERSION=ltsc2022
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8.1-windowsservercore-${WINDOWS_VERSION}
SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop';"]
# IIS features used by Plant an App (most are already in the base image)
RUN Install-WindowsFeature Web-Default-Doc, Web-Http-Errors, Web-Static-Content, `
Web-Http-Logging, Web-Stat-Compression, Web-Filtering, Web-AppInit, `
Web-Asp-Net45, Web-Net-Ext45, Web-ISAPI-Ext, Web-ISAPI-Filter
# Application pool: .NET 4, integrated pipeline, 64-bit, always running
RUN & $env:windir\System32\inetsrv\appcmd.exe set apppool DefaultAppPool `
/managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated `
/enable32BitAppOnWin64:false /startMode:AlwaysRunning `
/processModel.idleTimeout:00:00:00
COPY start.ps1 C:/start.ps1
EXPOSE 80
ENTRYPOINT ["powershell", "-NoProfile", "-File", "C:\\start.ps1"]
start.ps1
# Give IIS full control of the mounted site folder, then start IIS
icacls C:\inetpub\wwwroot /grant "IIS_IUSRS:(OI)(CI)F" /T /C /Q | Out-Null
& C:\ServiceMonitor.exe w3svc
ServiceMonitor.exe comes with Microsoft's image. It keeps the container running as long as IIS runs.
Build the image. On Windows Server 2025, use --build-arg WINDOWS_VERSION=ltsc2025:
cd D:\PlantAnApp\image
docker build -t plantanapp-web:ltsc2022 --build-arg WINDOWS_VERSION=ltsc2022 .
To run the image on other hosts or on Kubernetes, push it to your private container registry.
3. Prepare the Site Files
Do this once, in the site folder on the host (for example D:\PlantAnApp\site):
-
Unpack the Plant an App installation package (
PlantAnApp_<version>.zip) into the site folder. -
On the SQL Server, create an empty database and a SQL login with
db_ownermembership on it. See Defining the SQL User. -
In the site's
web.config, set theSiteSqlServerconnection string:<add name="SiteSqlServer" connectionString="Data Source=sql-host;Initial Catalog=PlantAnApp;User ID=PlantAnApp_user;Password=********" providerName="System.Data.SqlClient" />Use the SQL Server's host name or IP address.
localhostinside the container means the container itself, not the host. -
In the same file, remove the
PlantAnApp_DeploymentTypeentry from<appSettings>, if it's there. The install script does the same.
4. Run the Container
Create D:\PlantAnApp\docker-compose.yml:
services:
web:
image: plantanapp-web:ltsc2022
isolation: process
restart: always
ports:
- "8080:80"
volumes:
- D:\PlantAnApp\site:C:\inetpub\wwwroot
Start it:
cd D:\PlantAnApp
docker compose up -d
docker compose logs -f
Open http://<host>:8080 in a browser. The installation wizard starts. Enter the system administrator account and the site name, keep the default database setup (the connection string is already set), and finish. Plant an App is installed in the same run. Then open http://<host>:8080/Configuration and activate it, as in Step 3: Activate Plant an App.
HTTPS
Serve the site to users only over HTTPS. The simplest way is to end TLS in front of the container: on a load balancer, a reverse proxy, or a Kubernetes ingress controller. Then forward traffic to the container's port 80 on a protected network. In the site settings, turn on SSL Enabled and SSL Enforced. See also Data Security.
Updates
| What | How |
|---|---|
| Plant an App | Upgrade from inside the application, as for any installation. The new files are written to the site volume, so they stay after the container is replaced. |
| Windows and .NET security updates | Microsoft publishes updated base images every month. Rebuild the image with docker build --pull ..., then recreate the container with docker compose up -d. The site files and the database aren't affected. |
| Container host | Update Windows Server as usual. When you move the host to a new Windows Server version, rebuild the image with the matching tag. |
Back up the site volume and the database together, as for a standard installation.
Several Containers
To run more than one web container, for more capacity or high availability:
- All containers must use the same site files. Put them on a shared SMB file share and mount the share in every container, or use a Kubernetes volume that several pods can write to at once (
ReadWriteMany). - All containers use the same database.
- A load balancer spreads requests across the containers.
- Configure web farm mode: in
web.config, setIsWebFarmtotrue. Each container then needs a unique, reachable name.
Run on Kubernetes
Plant an App runs on Kubernetes clusters with Windows worker nodes, for example:
| Platform | Windows nodes |
|---|---|
| Azure Kubernetes Service (AKS) | Windows Server node pools. See Windows containers on AKS. |
| Amazon EKS | Windows nodes with the EKS-optimized Windows Server AMIs. See Deploy Windows nodes on EKS clusters. |
| On-premises Kubernetes | Any distribution that supports Windows worker nodes. The control plane runs on Linux. |
Check the supported Windows Server versions in your platform's documentation, and use the matching image tag (ltsc2022 or ltsc2025).
Example deployment, with the site files on a shared volume and two replicas:
apiVersion: apps/v1
kind: Deployment
metadata:
name: plantanapp-web
spec:
replicas: 2
selector:
matchLabels:
app: plantanapp-web
template:
metadata:
labels:
app: plantanapp-web
spec:
nodeSelector:
kubernetes.io/os: windows
containers:
- name: web
image: registry.example.local/plantanapp-web:ltsc2022
ports:
- containerPort: 80
resources:
requests:
cpu: "2"
memory: 4Gi
volumeMounts:
- name: site
mountPath: C:\inetpub\wwwroot
volumes:
- name: site
persistentVolumeClaim:
claimName: plantanapp-site # ReadWriteMany, for example SMB / Azure Files
---
apiVersion: v1
kind: Service
metadata:
name: plantanapp-web
spec:
selector:
app: plantanapp-web
ports:
- port: 80
targetPort: 80
Publish the service through your ingress controller or load balancer, with TLS. With more than one replica, also follow Several Containers.
Run in the Cloud
There are two ways to run Plant an App containers in a cloud, public or private:
- Windows Server VMs with Docker. Use a Windows Server 2022 or 2025 VM as the container host and follow the steps on this page. This works in any cloud that offers Windows Server VMs.
- Managed Kubernetes with Windows nodes, such as AKS or EKS. See Run on Kubernetes.
In both cases, use a SQL Server VM or a managed SQL Server service for the database, and shared file storage for the site files when you run several containers.
Considerations
- SQL Server in a container. Microsoft doesn't provide supported SQL Server images for Windows containers. Run SQL Server outside the containers in production.
- Image size. The first download of a Windows Server Core image takes several GB. Keep images in a registry close to the hosts.
- Memory. Hyper-V isolation needs more memory per container than process isolation.
- File permissions. If the installation wizard reports access errors, check that the site folder can be written from the container (see
start.ps1). - Database connection. Use the SQL Server's host name or IP address, and allow connections from the container host through the firewall.
Revised 11/12/2026