Fluent Bytes

"The only source of knowledge is experience" - Albert Einstein-

Deploying ASP.NET 4.5 to Docker on Windows

At the moment of this writing you can search the internet on ASP.NET and docker and all you will find is how to deploy ASP.NET Core applications to a Linux docker container. Although I love the initiative of ASP.NET core, I do believe that ASP.NET 4.5 is something many of you know and love already and nobody talks about how we can leverage docker on windows to run this full version of ASP.NET

To get you started we need to have a Windows version that is capable of natively running docker. With natively running docker I mean that docker is build into the OS. So no use of docker for windows tools, since we don’t want Linux containers, we want to run windows containers! At this moment you can use Windows 10 Anniversary edition and Windows Server 2016 Technical Preview 5 to go through the steps that I describe here to get your ASP.NET 4.5 website running in a docker on windows container.

What do we need to rollout an ASP.NET website to a windows docker container?

When you run an ASP.NET 4.5 website then you need the following things:

  • The Operating system with IIS installed
  • ASP.NET 4.5 installed
  • Webdeploy installed

I personally love to use web deploy to deploy the website after build, so it can be done exactly the same way as you would deploy to Azure App Services or your local IIS Server on any server you already know and love.

Building the container with IIS, ASP.NET and Webdeploy

Here are the steps you need to take to create a docker container that has all these required ingredients:

Fist we need a basic operating system image from docker hub. For this you can run the following command from the command line:

now we have the image in our images gallery, you can check this with the following command:

This should output something similar to the following screenshot:

image

 

Now we can start adding the first layer and that is installing IIS. For this you can use the dism command on windows and pass it in the arguments to install the IIS webserver role to windows server core. You can do this at an interactive prompt or use the docker build command. I prefer the later and for this we create a dockerfile that contains the following statements:

After saving the file under the name dockerfile without any extensions you run a command line to build the image:

The command tells docker to build an image, give it the tag windowsserveriis and use the current folder (denoted with the dot) as the context to build the image. this means that everything stated in the dockerfile is relative to that context. Note that you are only allowed to use lowercase characters for the tagename.

After running the command you now have a new docker image with the name windowsserveriis

If you now run the command:

you will see the new image available

image

We can take the next step and that is to install ASP.NET 4.5

We can do this in a similar way, by creating a docker file with the following commands:

and again after saving the file you can run the command line to build the image:

Now we have an image that is capable of running an ASP.NET application. The next step is that we need webdepoy to be installed in the container. For this we need to download the installer for webdeploy and then issue an command that will install and wait for the installation to finish. We first download the installer in the same folder as the dockerfile and then we will add it to the image. In the following steps I assume you already downloaded the MSI (WebDeploy_2_10_amd64_en-US.msi) and have it in the same folder as the dockerfile. When installing the msi we will use msiexec and need to start a process that we can wait on to be done. If we would only run msiexec, then this command returns and runs in the background, making the container to exit, leaving us in an undefined state.

When you create the following dockerfile, you install webdeploy:

Note that we are using powershell start-process with the –wait option, so we wait for the installation to finish, before we commit the new layer.

Now run the docker command again to build the image using the new dockerfile:

Now we have an image that is capable to host our website in IIS and use webdeploy to install our website.

Doing it all in one dockerfile

In the previous steps we created a new docker file for each step. But it is probably better to do this in one file, batching all commands together leaving you with the same endstate. We can also optimize the process a bit, since Microsoft already provides an image called microsoft/iis that has the iis feature enabled. This means we can use that image as the base layer and skip the install of IIS.

The simplified docker file looks as follows:

Now again we run the docker build command to get the docker image capable of running our website and use the webdeploy packages that can be produced by a standard ASP.NET build procedure.

The final step is to deploy your webdeploy package to the image.

Getting the webdeploy package

Now before we can deploy our website we need to get the webdeploy package.

I assume you have a standard ASP.NET web project in Visual Studio. In this case you can very easily create the deploy package inside Visual Studio (in the next post I show you how to do this using VSTS/TFS builds)

When you right click the Visual Studio project you can select the publish option:

image

After selecting publish you will see the following dialog:

image

In order to just create a package in stead of deploying to a server or Azure, I select Custom

image

then you give the profile a name, in my case dockerdeploydemo

image

then we select web deploy package from the dropdown and provide the required information, package location and the name of the website

image

next you can setup any database connections if you have any, in my case I have no database

image

next, click publish and you will find the resulting deployment package and accompanying deployment files in the c:\temp folder

image

Now that we have the webdeploy package and the accompanying deployment artifacts, we can again create a docker file that will then upload the package to the container and install the website in the container. This will then leave you with a complete docker image that runs your website.

Publish the website in the docker container

The dockerfile to deploy your website looks as follows:

We build the container again using the docker build command:

This now finally results in our web application in a container that we can then run on any windows server that has windows containers enabled.

Running the website in the container

In order to test if we succeeded we now issue the docker run command and then map the container port 80 to a port on our host. This can be done by using the –p option, where you specify a source and destination port. We also need to specify a command that ensures the container keeps running. For this we now use e.g. a command like ping –t which will result in an endless ping loop, that is enough to keep the container running. so to test the container we now run the following command:

Now we can browse to the website. Be aware that you can only reach the container from the outside, so if you would browse to localhost, which results in the 127.0.0.0 you will not see any results. You need to address your machine on its actual hostname or outside IP address.

Summary

To summarize what we have done, we first created a docker image capable of running IIS, then we added ASP.NET 4.5, then we added webdeploy and finally we deployed our website to the container using webdeploy and the package generated by Visual Studio.

In the next post I will show you how we can use this image in build and release management using VSTS and then deploy the container to a server so we can run automated tests as a stage in the delivery pipeline.

CTO at Xpirit, Microsoft Regional Director, Visual studio ALM MVP, Speaker, Pluralsight Author and IT Architect Consultant

15 Comments

  1. I was stuck at the “docker pull microsoft/iis” step for a while because it kept timing out saying “unknown blob”. The problem was resolved by getting docker 1.13 using this link. I thought this would be helpful for someone. https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_10

  2. Forgot to mention, this guide is very helpful and exactly what I was looking for. Great job! Thank a lot

  3. Thanks for this guide. I tried it on Windows Server 2016.

    I needed to use “Default Web Site/dockerdeploydemo” as my site name when publishing otherwise web deploy gives me Error Code: ERROR_SITE_DOES_NOT_EXIST.

    Once past this web deploy adds all the files to the site then I get this error:
    “Info: Adding ACL’s for path (Default Web Site\dockerdeploydemo)
    Error: This access control list is not in canonical form and therefore cannot be modified.
    Error count: 1.”
    Is this important ?

  4. Hello Marcel,

    Like in your post, I see a lot of blog posts about Docker on Windows where authors are using microsoft/windowsservercore image instead of using microsoft/aspnet image

    Is there any reason for this choice ?

    Thanks

    • Good point, no I did not have a specific reason. I have not tried it, but I assume you could then skip at least the first steps and only do the steps where you add webdeploy

  5. Hi Marcle,
    Very good article.
    I have one query while run below command
    “docker build –t mycontainerizedwebsite .”
    it gives me error like (unauthorized: authentication required)

    So what can be the resolution?

    Regards,
    Shyam

  6. Kasper Joergensen

    December 20, 2016 at 2:04 pm

    I am trying to follow along, but I am getting a weird error… I installed the windowsserveriis image, and I get to the ASP.NET installation. I should add that I created a folder in my directory for each Dockerfile. After I navigate to the local directory of ‘new’ dockerfile and run the command:
    docker build –t windowsserveriisaspnet .
    I get an error with the following message: docker : “docker build” requires exactly 1 argument(s)
    This initially I just thought I missed the dot on the end, but this is not the case. I have also tried changing the name of the dockerfile, and pointing to it with the command:
    docker build -windowsserveriisaspnet –file=”newdockerfile”

    Any helpful insight?

  7. was this Error Code: ERROR_SITE_DOES_NOT_EXIST resolved?
    Thank you.

  8. Step 7/10 : ADD WebDeploy_2_10_amd64_en-US.msi /install/WebDeploy_2_10_amd64_en-US.msi
    GetFileAttributesEx WebDeploy_2_10_amd64_en-US.msi: The system cannot find the file specified.

    Showing error while building.

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑