The purpose of this series is to provide a hands-on explanation and walkthrough of Windows Containers and explain why they’re such a great tool.
Rather than go into the marketing scribe about why they’re awesome and what they can do for your business, my aim is to keep this purely technical and demonstrate how easily and practically they can be used.
In short, this blog focuses on what Windows Containers they are and how we can use them. I always find practical examples easier to follow - so for this series, we'll use WordPress as our container based application.
I’ve chosen WordPress because its easy to setup, has a base image that we can already use, and can be deployed as single container or as a service which fits the purpose of this blog nicely.
I’ve broken down the series into the following parts:
- Part 1 – Deploying your First Container (You are here)
- Part 2 – Docker Build Files, Networks and repositories
- Part 3 – Docker Services and Version Control
- Part 4 – Deploying to Azure and Management Using
What are containers?
Containers are a form of virtualisation that allows an application or service to be packaged, isolated and deployed across multiple hosts. If it sounds familiar, it's similar in concept to virtual machines amongst other things.
A container is different in that it's an isolated box in which everything an application and its dependencies are contained but instead of being deployed on an operating system with other applications (or in some instances on its own dedicated operating system instance) the application shares the base level operating system with other containerised applications without any visibility of other containers or services running on the same base OS.
The core concepts of Windows Containers can be broken down as follows:
Container Host – The Virtual Machine or Physical server that is running the container feature. In virtualisation terms, this is effectively the hypervisor.
Container Image – The container image is effectively a base template from which a container is built. As changes are made within the container, they are captured in the sandbox. These changes can then be exported to a new image or discarded when the container is removed.
Sandbox - Sticking with the virtualization metaphor, the Sandbox is effectively a differencing instance built from the original image. Any changes to the base image (Registry, File System, Application Installations) are captured in the sandbox. It can then be exported to an image and deployed with the changes made.
Container OS Image – Remember how I said the Container Host is like the hypervisor? It is, but in container land (particularly Windows), the hypervisor analogy applies in two places. The base OS image is also a platform level in that once the container base is built on an OS image it cannot be changed. For example, if you build a MySQL image based on Windows Server 2016, any person also running the container service on Server 2016 can simply run the container without any changes and, in most instances will only need the changes you’ve captured from the base image. Now, if someone is running Windows Server 1709 and attempts to run the same container, they will receive an error from daemon advising you that the base OS doesn’t match and the container will not work without isolation.
Container Repository – Your container repository is effectively your template store. Any images you create locally go into a local repository by default. We’ll touch on repositories in more detail the next post. Private and public repositories are available over a network and are a necessity for deploying to multiple container hosts and Azure. For the purposes of Part 1, we’ll be using an image from the Public Docker Repository.
Isolation – Windows Containers support to forms of isolation, Kernel or Namespace Isolation and Hyper-V Isolation. Again, we’ll get stuck into the details of what each provides and where you would use each one, but for the purposes of simplifying the explanation, namespace isolation implies that containers share the same underlying host kernel and are separated by namespace only meaning that there are ways in which that isolation can be broken out of. Hyper-V Isolation isolates the container in an extremely lightweight virtual machine that prevents any potential crossover between namespaces.
Before you get stuck into the practical side of deploying containers, I highly recommend reading Microsoft’s Introduction to Containers and Mark Russinovich’s blog post, as much of the information I’ve will referenced is derived from these articles in more detail. I’ve also included the following useful links below:
Docker Hub – Looking for an application in a container? Chances are someone has built it, and you can use it as a starting block.
Before we get into deploying the container, we need to make sure we meet the necessary requirements to run it.
For this blog, I will be using Windows 10 Anniversary Edition (1709) and Server 2016 Server Core to run and deploy containers. Windows Containers are not supported in Windows 10 prior to the anniversary release, so if you haven’t upgraded, my suggestion is that you get that underway now.
Part 1 will be run exclusively on Windows 10 - we will bring in Server 2016 in later blog posts as we get into some of the more complex aspects of containers and docker.
All the above sorted?
Head to this link to download and install the latest version of Docker for Windows and run Docker Setup Wizard.
The installer will enable the Hyper-V role and require a reboot. After the reboot, we’ll need to switch from Linux Containers to Windows Containers (Linux containers are the default) which will also trigger a reboot. (In the example below I’ve already switched to Windows Containers).
That’s it for the setup for now - we’ve now got containers up and running on Windows.
Grab the image and deploy the container
Hopefully up until now its all been relatively pain free and you have a running copy of Docker on your device.
Now we’re ready to grab our images and deploy a container. I’ll provide the commands and an explanation of what they mean as we go.
First, Run PowerShell as an administrator, Docker is integrated with PowerShell so we can use all of the standard Docker commands without needing to learn different syntax. The first command we’re going to run is:
Docker is basically the root of all commands. The images component queries the docker daemon to see which images are available for use to deploy. As this is a new install, we have no images available. We’ll issue the docker pull command to download the image we plan to use for the demo. In this instance, the image is in the public repository under the name nanoserver/iis-mysql-php-wordpress. If everything behaves normally, you should see:
Now when we issue the docker images command we should see the following:
Now that we have the image we can deploy the container. The container will be deployed in Sandbox mode and any changes we make will be made only to this container. To start a container based on this image run the following command:
The command above will run a container with the name diligtest in interactive mode (-it) from the nano/iis-mysql-php-wordpress image and execute the cmd.exe command interactively. Once it completes we should be greeted with the following output:
Because we’ve specified the -it parameter, the container runs in interactive mode. What we’re seeing is the output of the ipconfig command inside the container itself. If I navigate to this http://172.21.60.181/wordpress/ in a Web browser, I am greeted with the WordPress Setup wizard:
At this point, we can complete the WordPress Setup wizard with the following details:
If you encounter an Internal Error 500 page, simply refresh the page and you should reach the screen below, click the Installing now link to continue.
Now we fill in the details below and select Install WordPress.
Congratulations, you now have a working WordPress site running in a container on your laptop.
Cleaning things up
Now that we’ve deployed the container and successfully completed the install, we’ll stop the container and remove it in preparation for the next instalment. While you don’t actually have to get rid of the container we just deployed, here's a quick word of warning; the installer will use the URL you are accessing the setup wizard from for the base install which in our case was the an IP Address, a dynamic IP Address.
By default, new containers in Windows 10 are connected to the NAT network, unless specifically specified. If we stop and restart this container, it will receive a new IP Address and break the WordPress Installation. If you do want to install the instance on your local machine for any reason, I recommend using a host entry with the domain name you want to use for the installation pointing to the NAT IP Address assigned or use the bridge network.
Before we can remove the container, we’ll need to stop or shut it down either by typing exit in the cmd.exe window of the container or by opening another PowerShell window and issuing the following docker commands:
That’s it for Part 1!
In Part 2 of our Windows Containers series, we’ll go into more detail around build file syntax, networking and repositories and ultimately look to move our WordPress container from one container host to another.