This video is a quick rundown on what are containers how to run them on a Windows Server box, and what can they be used for. A container is an isolated environment where an application can run.
The container, the application, and all of its dependencies are constructed with pieces of the host's resources such as a Kernel operating system, CPU, and memory. And they're logically separated from other containers and from the host itself.
This diagram illustrates how a red and a yellow container coexist within the same host using the same hardware resources and the Kernel operating system, but are contained within their individual space, which allows them to run their applications without external interference.
The same hardware and the operating system installed on that hardware can run its own applications and services, also independent from what's happening on each container.
By default, this container is disposable. When it's stopped, all the software and files on it are deleted. The same happens if the host is rebooting.
The containers also leverage the firewall of the host computer. Let's compare all that with a virtual machine. First, you can run a container on a virtual machine but not vice versa.
A virtual machine simulates an entire computer. Therefore, it needs to run its own operating system which allows for a greater security, but at the same time, requires more configuration and maintenance, and this often results in idle resources.
There are multiple ways to work with containers, including Visual Studio, Azure, Kubernetes, and Windows, but in this video, let's talk about Docker.
Docker is a platform-as-a-service product that takes up the job of combining an application, all of its dependencies, and configuration information into a single package called a container.
Docker can then be used to ship, run, or delete that container. We'll return to this diagram in a moment. Let’s see some of this in action and cover some more details along the way. Here, we have a fresh installation of Windows Server 2022.
I will start the "Server Manager" wizard to add "Roles" and "Features". Notice that using this wizard, I can add the "Containers" feature. However, this does not install Docker.
We need to do that separately. So, to do that, I will cancel this wizard, and I'll open "PowerShell" to run the following line to install, first, a required provider.
Install-Module, the "DockerMsftProvider" and we're using the "PSGallery" as a source. So, I'll hit Enter. At this prompt, say "Yes" to install NuGet, and wait for it to finish.
Now, I'll run the second line to install Docker itself. Install-Package, "docker" and then specify the "DockerMsftProvider" we installed earlier. Hit Enter. And at the prompt that we'll get here in a moment, say "Yes" to continue.
Notice the prompt to restart the computer. Let's do that by typing "Restart-Computer". With the computer back up, I'll open the "Add Roles and Features Wizard" in "Server Manager" once again.
You'll notice that the "Containers" feature has already been installed. We did this with the two PowerShell lines we ran earlier. In "PowerShell", running a command such as "docker" will give us an idea of all the things that we can do.
Docker version for instance, will tell us that we’re running with engine version 20.10.9. Another command, "docker info" will tell us that we're yet to create our first container.
And this box also gives us details such as the amount of CPUs and RAM available for containers, the "Default Isolation Method" and the "Network" types that were created, which we're not going to discuss for now.
Let’s just run the steps to build and run our first container on this Windows box where we just installed Docker. Back in this diagram, let's remember Docker is a tool for packaging multiple items into a container. So, if we were to containerize a web application, for instance, we'll be needing to put several items inside that container.
First, we need a "Dockerfile". This file will have configuration information and instructions needed to create a new container. A Dockerfile looks like this. It can be very complex or very simple.
We'll be creating one in a moment. We also need a container image. An image is like a read-only template. You can build a container using the template of "Windows Server Core" or use a "Nano Server" template, for instance.
This image or template also provides some of the dependencies that the web application will be needing, such as the "IIS" service and the development framework. Finally, we need the web application itself.
Docker allows you to put all of this together to create a container. Let's see this in action. Back in the computer where we just installed Docker in PowerShell, I'll switch to the root of the C drive and create a new directory named "containers".
I'll switch to this new "containers" directory and to create our first container, we need the Dockerfile we discussed earlier. Remember, this is a text file with a set of instructions for the container.
I'll do so by typing "New-Item" and specify the name, "dockerfile". Notice that this Dockerfile does not have any extension. We can see this file created in Windows Explorer. We'll open it with Notepad.
To keep this first container simple, we'll just be adding three lines to this Dockerfile. I'll explain them one by one. First, the "From" instruction tells Docker which container image will be used for creating the container.
Remember, an image is like a template. In this case, we're instructing Docker to use an image from the Microsoft container registry that is based on Windows Server Core and also has the "IIS" role installed.
The second line specifies which commands are to be run on the new container image once it's executing. We could include commands for installing software or creating files and directories.
But in this case, we're just instructing Docker to run PowerShell on the container once it's running. The "Copy" instruction, finally, copies files or directories from the host computer to the container's file system.
In this case, we're instructing Docker to copy a file name "index.html" which will be created in a moment, and which serves as our sample web application from the host computer to this folder in the container, which happens to be the default virtual directory path for IIS.
And that is it. Let's save this Dockerfile. Now return to PowerShell to create the web page that will run in that container. I'll do so by using the "New-Item" commandlet again, and then specify "index.html" as the name of the file.
We'll open this file in Windows Explorer with Notepad. And to keep this simple, again, we’ll just be adding three lines to this sample HTML application, just a basic "Hello World" web page.
I'll be saving this. And now, we have all the components needed to create a container. Docker has been installed on this Windows Server box.
We have the Dockerfile, which we created earlier with the instructions to use the server core image from the Microsoft registry that has IIS.
And also, we included in that Dockerfile's instructions to copy the HTML web page to that new container once we build it. But all we have is that, a set of instructions. Nothing is running yet.
So, back in PowerShell to actually create an image based on those instructions we'll be running "docker", "build" and then assign the name or tag web server.
And this trailing dot in the end indicates that we're going to be working on this containers directory, where we have our Dockerfile and our "index.html" web page. I'll hit Enter.
This line creates the base image from which our containers will be created using the instructions that we specified on that Dockerfile. Because this is the first time we invoked this image on this server, it needs to download it from the Microsoft container registry.
With all of this finished, running a command such as docker images will display a recently downloaded image along with the name or tag that we assigned to it. So, we now have a container image which is just like a template, remember. But there are no containers running yet.
Just to show that it is not possible to access our sample web application yet, I'll open a web browser, and type in "localhost". This fails, and this is expected because the host doesn't have IIS and cannot host a web page.
To finally run the container using the image template we downloaded, back in PowerShell, let's type "docker run" and then specify the name for that container.
We'll be using the name "container1". We'll be using this switch to specify the container will run in the background. And this other one to specify that "port 80" on the container will be mapped to "port 80" on the host. And we're specifying that this container should be executed using the web server image that we downloaded and built previously.
So, I'll just hit Enter. And that's it. This creates and executes a container named "container1" based on the web server image that we just had prepared.
We did not have to assign any memory, notice, to this container. Neither CPUs or virtual hard disks to this container, as is the case with virtual machines.
That's because you don’t have to assign these resources to a container. They just use what they need. Let’s go back to the browser and enter "localhost" again.
We see our sample web application is up. Not on the host. Instead, the host is forwarding port 80 to the container, which was created using the settings that we specified on the web server image, and that had our HTML web page copied to it as instructed in the Dockerfile.
We can interact with this newly created container via the command line. For instance, I'll open a new PowerShell window and enter the command "docker exec -ti" to specify that we'll be connecting to this container interactively.
The name of the container, "container1", and then "powershell". This Docker command opens PowerShell in the container1 we just created, and it gives us a prompt.
In this case, if we type "hostname" for instance, we can see that this container has been assigned a computer name. Typing in a command such as "ipconfig" will show that, also, this container has been assigned an IP address that uses Network Address Translation to communicate with the host and beyond.
I'll make a small change to the HTML web page we created earlier. Edit it in Notepad and change this heading here to read "container #2" instead of "container #1". Save this file. And back in PowerShell, I will use the same two lines we used earlier to build and run our first container.
First, the "docker build" line remains unchanged. Notice when I hit Enter, it pretty much does this instantly. And this is because we already have downloaded the server core image that has the IIS role installed from the Microsoft container registry.
The second line, the "docker run" line, we're just editing it to create a new container named "container2", and we'll make this container listen at "port 8080" instead of "port 80", which is the one we assigned to "container1".
We'll hit "Enter" and when this is finished, back in the browser I'll go back to "localhost" but this time specify "port 8080". We can see that the web page listening at port 8080 is hosted by "container #2" which we just created. Whereas, the one listening at port 80, the default for HTTP is hosted by "container #1".
We can also see the same in PowerShell by running "docker ps". container #1 is listening at port 80, whereas "container #2" is listening at port 8080. container #1 and "container #2" have their own hostname, IP addresses, and host their own websites.
Any changes that occur in "container #1" will not affect "container #2". Notice, we were able to do all this without ever installing the "IIS" role or the "hyper v" role on the host server.
Neither did we have to assign resources such as RAM, or CPU, or virtual hard disks, or configure any networking. Once the base template image is local, creating the container took us between two to three seconds.
Finally, I'd like to briefly talk about what can you run in a container. First, containers on Windows were first supported in Windows Server 2016 and Windows 10. So, ideally, the hosted application is compatible with these operating systems and newer.
If an application needs a graphical user interface or drivers, it is not suitable to be deployed on a container. You can, however, use a container to host Application Frameworks such as "Asp.net" or "Apache", programming languages such as "Python", even databases in the form of services such as sqlserver-express, "mongodb" or "mysql".
Currently, it is not supported to host Windows infrastructure roles such as "domain controller", "DNS", or "DHCP" on containers, but who knows what the future might hold.
So, this has been a quick rundown on: What are containers, how to run them on a Windows server box, and what can you use them for? I hope you find this information useful, and I'd like to thank you very much for watching.