Key lessons learned in containerizing Windows-based applications

The latest advancements in container deployment and orchestration offer immense potential to help enterprises increase operational efficiency across applications. Since containerized applications always run the same way, regardless of infrastructure, businesses are now investing in containers on several fronts — from cloud-native initiatives to legacy applications.
This blog shares our experience of containerizing a Windows-based application while upgrading a data platform for a US-based healthcare technology company. The client’s legacy Java-based monolithic data platform, which had a native dependency on Windows, was making on-premise installations complex and time-consuming. While they were already rearchitecting this platform to microservices, they wanted an innovative solution to quickly move it as-is to containers.
Key challenges of Kubernetes and Docker Swarm
While evaluating containerization options, we chose to use the latest version of Docker as it supports Windows containers. We set up Docker in the Windows Server 2019 environment. To enable auto-scaling and self-healing capabilities, we set up an on-premise Kubernetes cluster. However, during feasibility analysis, a network plugin (Flannel) caused issues, disturbing the entire cluster networking during machine reboot.
Then, we tried leveraging Docker Swarm as an orchestrator framework. Here too, we faced several challenges, including issues with rolling updates, and the inability to access applications and create services in Replication mode.
To overcome these challenges, we validated the Kubernetes cluster using Amazon Elastic Kubernetes Services (EKS). After being able to successfully run Windows images on the cloud, we realized that Kubernetes’ on-premise platform was not compatible with Windows. Since we needed an on-premise solution to meet the client’s requirements, we decided to build our custom orchestrator.
Enabling zero downtime with a customized solution
Using PowerShell script, we built a custom orchestrator that helped us create a robust network of multiple Windows servers and seamlessly manage application containers.

Given below are the solution highlights:
1. Leveraged CodeCommit for version control, which triggered a Jenkins build for building code and Docker images
2. Pushed ready images to the Docker registry
3. Deployed Docker images using the following steps:
a. Obtained details of the target deployment environment either through parameterized jobs or automatic identification using Git branch command
b. The orchestrator spun new containers using available ports in the port pool and mapped these to HAProxy with the respective replica count
c. The orchestrator performed a health check on each newly launched container. On successful completion, it removed old containers
d. The ports released by old containers became a part of the free port pool
e. In case a health check failed, the deployment stopped and all the newly launched containers were removed
f. Upgraded one container at a time and ensured that user traffic was served by existing containers to achieve zero downtime
Our learnings
If you’re looking to containerize a Windows-based application in an on-premise environment, you can create a custom orchestrator or use native Docker, as the current versions of both Kubernetes and Docker Swarm do not support containerization in on-premise environments. By building a custom orchestrator, we reduced the platform upgradation time from 3 hours to 30 minutes. With containerization at the core, we successfully created a cloud-agnostic deployment, empowering our client with greater flexibility. The as-is containerization of their existing application helped them start their modernization journey without waiting for their legacy platform to be fully rearchitected, saving them valuable time and money.