- Docker Business, which includes Docker Desktop, provides developers an integrated, reliable, and secure developer experience that accelerates app delivery from code to the cloud. Docker Business enables organization-wide management and security for businesses that use Docker for software development at scale.
- Nano Server is being pitched as a minimalist OS - so minimal that it lacks a full version of PowerShell and cannot install programs using MSI files. We will pull down a Windows Server Core image as a basis for our container. Let's start a command prompt in a docker container to check that everything worked.
- Docker Windows Container Install Msi By Tiara Maulid June 27, 2020 Node js nano server docker base image deploy node js lication running on asp 4 5 to docker on windows implementing ruckzuck cache for the docker on windows inar q a.
The webinar Deploy Complex Apps in a Whole New Way provided a brief overview of one of today’s hottest topics (Docker) and outlined the difference between Docker and virtual appliances. We’ve captured the webinar’s top questions and answers here. Plus, we’ve thrown in some resource links to help you sort it all out. You can find more answers in the InstallAnywhere 2015 documentation, or you can contact us directly. And don’t forget the Flexera Community; start a string and share your insights.
- Q: What is the difference between Docker and any other application virtualization solution like App-V?
A: Docker is for distributed applications in the datacenter or running in the cloud, while App-V is for desktop apps. - Q: How does the build process for the virtual appliance or container deal with custom code or scripts that are normally run during the installation process on the target system?
A: We run the installer into that virtual space. It’s actually installing your apps. Anything that installer would be doing is being done in that virtual space. So we start the virtual environment, run your installer and all its logic, and save the results of that as a Docker image or virtual appliance. That way all your logic and everything is captured. - Q: Our installer prompts for a lot of information. So we would need to provide default responses for all prompts in order for the Docker container to run, right?
A: Correct, InstallAnywhere asks for command switches and parameters that you want to pass to your installer that we'll use when building your Docker container or virtual appliance. - Q: Assuming that the application layer is separate from the database layer–would you put the database into its own Docker container? And, if so, how do you ensure that the application Docker containers talk to the correct database container?
A: Docker has extensive documentation on best practices for managing data for containerized applications. Check it all out here: https://docs.docker.com/engine/userguide/containers/dockervolumes/ - Q: Will a Windows container run on an existing Microsoft Server OS, such as Server 2012 R2?
A: That's a question for Microsoft, but so far, all indications are that this will be a feature of Windows Server 2016. - Q: Which Amazon Web Service should we use with Docker?
A: Within Amazon EC2, when you build a new environment, you have a few options. You can choose to provide your own Docker image and upload that directly. Amazon and Azure also have integration with the Docker Hub. The Docker Hub is Docker’s cloud service for sharing images. You can have a baseline image that might have the LAMP stack, for example, so you don’t have to build all that out. You can build on top of that. So you would go to the Docker Hub, InstallAnywhere can do this as well. Within InstallAnywhere, you can browse the Docker Hub and find that base image to use as a starting point, or find one based on UBUNTU or Red Hat, or one that has the whole LAMP stack preinstalled and configured and optimized for Docker and then install your application on top of that. Then Amazon, Azure and InstallAnywhere can all interact with that Docker Hub. See these resources from Amazon and Azure for specifics about their integration with Docker and virtual appliances.
https://aws.amazon.com/docker
https://aws.amazon.com/ec2/vm-import/
https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-docker-vm-extension/ - Q: Does InstallAnywhere provide tools to generate the two hard disk formats in virtual appliances?
A: InstallAnywhere's Virtual Appliances use VMware's VSDK format, which is required for Amazon Workspaces and VMware Hypervisors. We have looked at Hyper-V and would like to hear back from you whether that is something that’s important to you and you would like us to have direct support. There are tools out there that can convert the VSDK to Microsoft's VHD format for use on Hyper-V, including Hyper-V itself. - Q: Do you need Docker running somewhere to do a build?
A: Docker has to be running somewhere that InstallAnywhere can access. It doesn't have to be the same build server. - Q: Is InstallAnywhere part of AdminStudio?
A: No, InstallAnywhere and AdminStudio are separate products for different audiences. InstallAnywhere helps multiplatform software developers build installations for all the platforms they support, which has traditionally been Windows, Linux, and Mac. Now with Docker and virtual appliances, we’ve extended our platform support to the cloud. AdminStudio is more focused around the enterprise use case of consuming applications and preparing them for internal deployment. We welcome any feedback from you on how you would want to use Docker or virtual appliances in your enterprise with AdminStudio. - Q: How does Docker handle installation maintenance mode, such as add/remove features?
A: Add-run programs will be a Windows feature. We don’t know yet where the Windows containers are going to handle the maintenance mode. You can open up that Docker virtual space/container space in edit mode and do maintenance and changes in there. So you can load that up, power on, make changes and commit those changes. You shouldn’t have to repair an app, because it’s non-persistent. You put it in a defined state, and every time that powers on, it’s going to be in that defined state. So if you wanted to reconfigure or make changes to that state, you can open that container in edit mode and recommit any changes you’ve made. - Q: Is there any migration path for an existing InstallShield 2015 MSI project (non-UI) to a Docker image?
A: That’s on our roadmap, so stay tuned. We are definitely looking at that in the Windows container space. We would love to hear your interest in containers in the Windows market, to really help us drive that roadmap. - Q: For InstallShield users, do we have to totally restart from zero to make our deployment with InstallAnyWhere?
A: InstallShield is for Windows applications, while InstallAnywhere is for Multiplatform, like Linux and Java applications. There is not a process to convert InstallShield installs to InstallAnywhere, but our Professional Services can help you fast track any installation development needs.
While Docker assumes (and essentially requires) its users have elevated privileges on its host systems, Singularity was designed for use in high-performance computing environments in which the protection of shared resources is paramount. Compared to Docker: Your container runs as you. No need for 'sudo” to run singularity.
InstallAnywhere is the leading multiplatform development solution for application producers who need to deliver a professional and consistent cross installation experience for physical, virtual and cloud environments. From a single project file and build environment, InstallAnywhere creates reliable installations for on-premises platforms – Windows, Linux, Apple OS X, Solaris, AIX , HP-UX, and IBM iSeries – and enables you to take existing and new software products to a virtual and cloud infrastructure and build Docker containers. Get your free trial of InstallAnywhere or contact us for more information.
InstallShield® is the world's leading Windows installation development solution. InstallShield is designed to enable development teams to be more agile, collaborative and flexible when building reliable InstallScript and Windows Installer MSI installations for desktop, server, Web, virtual and traditional applications. The software installer of choice for today's sophisticated application producers, InstallShield is the only software installer that can directly convert MSIs to Microsoft App-V virtual packages. Get your free trial of InstallShield today or contact us for more information.
You can run any application in Docker as long as it can be installed and executed unattended, and the base operating system supports the app. Windows Server Core runs in Docker which means you can run pretty much any server or console application in Docker.
TL;DR
Update! For a full walkthrough on Dockerizing Windows apps, check out my book Docker on Windows and my Pluralsight course Modernizing .NET Apps with Docker.
Check out these examples:
- openjdk:windowsservercore - Docker image with the Java runtime on Windows Server Core, by Docker CaptainStefan Scherer
- elasticsearch:nanoserver - Docker image with a Java app on Nano Server
- kibana:windowsservercore - Docker image with a Node.js app on Windows Server Core
- nats:nanoserver - Docker image with a Go app on Nano Server
- nerd-dinner - Docker image with an ASP.NET app on Windows Server Core
- dotnetapp - Docker image with a .NET Core app on Nano Server
Lately I've been Dockerizing a variety of Windows apps - from legacy .NET 2.0 WebForms apps to Java, .NET Core, Go and Node.js. Packaging Windows apps as Docker images to run in containers is straightforward - here's the 5-step guide.

1. Choose Your Base Image
Docker images for Windows apps need to be based on microsoft/nanoserver
or microsoft/windowsservercore
, or on another image based on one of those.
Which you use will depend on the application platform, runtime, and installation requirements. For any of the following you need Windows Server Core:
- .NET Framework apps
- MSI installers for apps or dependencies
- 32-bit runtime support
For anything else, you should be able to use Nano Server. I've successfully used Nano Server as the base image for Go, Java and Node.js apps.
Nano Server is preferred because it is so drastically slimmed down. It's easier to distribute, has a smaller attack surface, starts more quickly, and runs more leanly.
Being slimmed down may have problems though - certain Windows APIs just aren't present in Nano Server, so while your app may build into a Docker image it may not run correctly. You'll only find that out by testing, but if you do find problems you can just switch to using Server Core.
Unless you know you need Server Core, you should start with Nano Server. Begin by running an interactive container with docker run -it --rm microsoft/nanoserver powershell
and set up your app manually. If it all works, put the commands you ran into a Dockerfile. If something fails, try again with Server Core.
Derived Images
You don't have to use a base Windows image for your app. There are a growing number of images on Docker Hub which package app frameworks on top of Windows.
They are a good option if they get you started with the dependencies you need. These all come in Server Core and Nano Server variants:
- microsoft/iis - basic Windows with IIS installed
- microsoft/aspnet - ASP.NET installed on top of IIS
- microsoft/aspnet:3.5 - .NET 3.5 installed and ASP.NET set up
- openjdk - OpenJDK Java runtime installed
- golang - Go runtime and SDK installed
- microsoft/dotnet - .NET runtime and SDK installed.
A note of caution about derived images. When you have a Windows app running in a Docker container, you don't connect to it and run Windows Update to apply security patches. Instead, you build a new image with the latest patches and replace your running container. To support that, Microsoft release regular updates to the base images on Docker Hub, tagging them with a full version number (10.0.14393.693
is the current version).
Base image updates usually happen monthly, so the latest Windows Server Core and Nano Server images have all the latest security patches applied. If you build your images from the Windows base image, you just need to rebuild to get the latest updates. If you use a derived image, you have a dependency on the image owner to update their image, before you can update yours.
If you use a derived image, make sure it has the same release cadence as the base images. Microsoft's images are usually updated at the same time as the Windows image, but official images may not be.
Alternatively, use the Dockerfile from a derived image to make your own 'golden' image. You'll have to manage the updates for that image, but you will control the timescales. (And you can send in a PR for the official image if you get there first).
2. Install Dependencies
You'll need to understand your application's requirements, so you can set up all the dependencies in the image. Both Nano Server and Windows Server Core have PowerShell set up, so you can install any software you need using PowerShell cmdlets.
Remember that the Dockerfile will be the ultimate source of truth for how to deploy and run your application. It's worth spending time on your Dockerfile so your Docker image is:
- Repeatable. You should be able to rebuild the image at any time in the future and get exactly the same output. You should specify exact version numbers when you install software in the image.
- Secure. Software installation is completely automated, so you should make sure you trust any packages you install. If you download files as part of your install, you can capture the checksum in the Dockerfile and make sure you verify the file after download.
- Minimal. The Docker image you build for your app should be as small as possible, so it's fast to distribute and has a small surface area. Don't install anything more than you need, and clean up any installations as you go.
Adding Windows Features
Windows features can be installed with Add-WindowsFeature
. If you want to see what features are available for an image, start an interactive container with docker run -it --rm microsoft/windowsservercore powershell
and run Get-WindowsFeature
.
On Server Core you'll see that .NET 4.6 is already installed, so you don't need to add features to run .NET Framework applications.
.NET is backwards-compatible, so you can use the installed .NET 4.6 to run any .NET application, back to .NET 2.0. In theory .NET 1.x apps can run too. I haven't tried that.
If you're running an ASP.NET web app but you want to use the base Windows image and control all your dependencies, you can add the Web Server and ASP.NET features:
Downloading Files
There's a standard pattern for installing dependencies from the Internet - here's a simple example for downloading Node.js into your Docker image:
The version of Node to download and the expected SHA-256 checksum are captured as environment variables with the ENV
instruction. That makes it easy to upgrade Node in the future - just change the values in the Dockerfile and rebuild. It also makes it easy to see what version is present in a running container, you can just check the environment variable.
The download and hash check is done in a single RUN
instruction, using Invoke-WebRequest
to download the file and then Get-FileHash
to verify the checksum. If the hashes don't match, the build fails.
After these instructions run, your image has the Node.js runtime in a known location - C:nodenode.exe
. It's a known version of Node, verified from a trusted download source.
Expanding Archives

For dependencies that come packaged, you'll need to install them as part of the RUN
instruction. Here's an example for Elasticsearch which downloads and uncompresses a ZIP file:
It's the same pattern as before, capturing the checksum, downloading the file and checking the hash. In this case, if the hash is good the file is uncompressed with Expand-Archive
, moved to a known location and the Zip file is deleted.
Don't be tempted to keep the Zip file in the image, 'in case you need it'. You won't need it - if there's a problem with the image you'll build a new one. And it's important to remove the package in the same RUN
command, so the Zip file is downloaded, expanded and deleted in a single image layer.
It may take several iterations to build your image. While you're working on it, it's a good idea to store any downloads locally and add them to the image with COPY
. That saves you downloading large files every time. When you have your app working, replace the COPY
with the proper download-verify-deleteRUN
pattern.
Installing MSIs
You can download and run MSIs using the same approach. Be aware that not all MSIs will be built to support unattended installation. A well-built MSI will support command-line switches for any options available in the UI, but that isn't always the case.
If you can install the app from an MSI you'll also need to ensure that the install completed before you move on to the next Dockerfile instruction - some MSIs continue to run in the background. This example from Stefan Scherer's iisnode Dockerfile uses Start-Process ... -Wait
to run the MSI:
3. Deploy the Application
Packaging your own app will be a simplified version of step 2. If you already have a build process which generates an unattended-friendly MSI, you can can copy it from the local machine into the image and install it with msiexec
:
This example is from the Modernize ASP.NET Apps - Ops Lab from Docker Labs on GitHub. The MSI supports app configuration with the RELEASENAME
option, and it runs unattended with the qn
flag.
With MSIs and other packaged deployment options (like Web Deploy) you need to choose between using what you currently have, or changing your build output to something more Docker friendly.
Web Deploy needs an agent installed into the image which adds an unnecessary piece of software. MSIs don't need an agent, but they're opaque, so it's not clear what's happening when the app gets installed. The Dockerfile isn't an explicit deployment guide if some of the steps are hidden.
An xcopy
deployment approach is better, where you package the application and its dependencies into a folder and copy that folder into the image. Your image will only run a single app, so there won't be any dependency clashes.
This example copies an ASP.NET Web app folder into the image, and configures it with IIS using PowerShell:
If you're looking at changing an existing build process to produce your app package, you should think about building your app in Docker too. Consolidating the build in a multi-stage Dockerfile means you can build your app anywhere without needing to install .NET or Visual Studio.
See Dockerizing .NET Apps with Microsoft's Build Images on Docker Hub.
4. Configure the Entrypoint
When you run a container from an image, Docker starts the process specified in the CMD
or ENTRYPOINT
instruction in the Dockerfile.
Modern app frameworks like .NET Core, Node and Go run as console apps - even for Web applications. That's easy to set up in the Dockerfile. This is how to run the open source Docker Registry - which is a Go application - inside a container:
Here registry
is the name of the executable, and the other values are passed as options to the exe.
ENTRYPOINT
and CMD
work differently and can be used in conjunction. See how CMD and ENTRYPOINT interact to learn how to use them effectively.
Starting a single process is the ideal way to run apps in Docker. The engine monitors the process running in the container, so if it stops Docker can raise an error. If it's also a console app, then log entries written by the app are collected by Docker and can be viewed with docker logs
.
For .NET web apps running in IIS, you need to take a different approach. The actual process serving your app is w3wp.exe
, but that's managed by the IIS Windows service, which is running in the background.
IIS will keep your web app running, but Docker needs a process to start and monitor. In Microsoft's IIS image they use a tool called ServiceMonitor.exe
as the entrypoint. That tool continually checks a Windows service is running, so if IIS does fail the monitor process raises the failure to Docker.
Alternatively, you could run a PowerShell startup script to monitor IIS and add extra functionality - like tailing the IIS log files so they get exposed to Docker.
5. Add a Healthcheck
HEALTHCHECK is one of the most useful instructions in the Dockerfile and you should include one in every app you Dockerize for production. Healthchecks are how you tell Docker if the app inside your container is healthy.
Docker monitors the process running in the container, but that's just a basic liveness check. The process could be running, but your app could be in a failed state - for a .NET Core app, the dotnet
executable may be up but returning 503
to every request. Without a healthcheck, Docker has no way to know the app is failing.
A healthcheck is a script you define in the Dockerfile, which the Docker engine executes inside the container at regular intervals (30 seconds by default, but configurable at the image and container level).
This is a simple healthcheck for a web application, which makes a web request to the local host (remember the healthcheck executes inside the container) and checks for a 200
response status:
Healthcheck commands need to return 0
if the app is healthy, and 1
if not. The check you make inside the healthcheck can be as complex as you like - having a diagnostics endpoint in your app and testing that is a thorough approach.
Make sure your HEALTHCHECK
command is stable, and always returns 0
or 1
. If the command itself fails, your container may not start.
Any type of app can have a healthcheck. Michael Friis added this simple but very useful check to the Microsoft SQL Server Express image:
The command verifies that the SQL Server database engine is running, and is able to respond to a simple query.
There are additional advantages in having a comprehensive healthcheck. The command runs when the container starts, so if your check exercises the main path in your app, it acts as a warm-up. When the first user request hits, the app is already running warm so there's no delay in sending the response.
Healthchecks are also very useful if you have expiry-based caching in your app. You can rely on the regular running of the healthcheck to keep your cache up-to date, so you could cache items for 25 seconds, knowing the healthcheck will run every 30 seconds and refresh them.
Dockerizing Windows apps is straightforward. The Dockerfile syntax is clean and simple, and you only need to learn a handful of instructions to build production-grade Docker images based on Windows Server Core or Nano Server.
Docker Run Msiexec
Following these steps will get you a functioning Windows app in a Docker image - then you can look to optimizing your Dockerfile.