Docker on Windows 2016

Docker is a tool that allows to deploy applications software in a “sandbox” (called container) to run on the host operating system (in this case Windows 2016, but also Windows 10 Professional or Enterprise, several Linux versions and MacOsx).

Nowaday the industry standard today is to use virtual machines to run software applications that provide full process isolation.

Att.: Process isolation means that a problem in the host operating system hardly can affect the software running in the guest operating system, and vice-versa.

This isolation, however, comes at great cost because of the computational overhead spent virtualizing hardware for a guest OS.

Containers take a different approach that provide almost the same level of the isolation of virtual machines, but at a fraction of the computing power and using more efficiently the underlying system and resources.

Another key benefit of Docker is that it allows users to package an application with all of its dependencies into a standardized unit: pratically it is possible to deploy software and the OS environment using a single configuration file (named dockerfile) !

In this post I’ll describe how to setup and get run Docker Windows Containers on Windows 2016: in the next post I’ll show other aspects and some pratical examples about how to create dockerfiles.

To begin ensure your Windows Server system is up-to-date by running in a power shell with administrator privileges the next command.

sconfig

Then choose option 6 to download and install all updates.

Now we have to install the Containers Windows feature.

> Install-WindowsFeature Containers

Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True Yes SuccessRest... {Containers}
WARNING: You must restart this server to finish the installation process.

You must restart to apply changes via the Restart-Computer cmdlet.

> Restart-Computer

Now you must install Docker Engine on the container host: in order to have the latest features it is possible download and install Docker directly from the official website.

Run the following commands in an power shell prompt.

> Invoke-WebRequest "https://master.dockerproject.org/windows/amd64/docker-1.14.0-dev.zip" -OutFile "$env:TEMP\docker.zip" –UseBasicParsing

Att.: Pls check in https://master.dockerproject.org/windows/amd64/ to get the very latest version available: in my case this is 1.14

> Expand-Archive -Path "$env:TEMP\docker.zip" -DestinationPath $env:ProgramFiles
> $env:path += ";$env:ProgramFiles\Docker"
> $existingMachinePath = [Environment]::GetEnvironmentVariable("Path",[System.EnvironmentVariableTarget]::Machine)
> [Environment]::SetEnvironmentVariable("Path", $existingMachinePath + ";$env:ProgramFiles\Docker", [EnvironmentVariableTarget]::Machine)
> dockerd --register-service
> Start-Service Docker

If all goes well, you’re ready to check that all works fine ! To display Docker information run the following command.

> docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 1.14.0-dev
Storage Driver: windowsfilter
Windows:
Logging Driver: json-file
Plugins:
Volume: local
Network: l2bridge l2tunnel nat null overlay transparent
Swarm: inactive
Default Isolation: process
Kernel Version: 10.0 14393 (14393.693.amd64fre.rs1_release.161220-1747)
Operating System: Windows Server 2016 Standard
OSType: windows
Architecture: x86_64
CPUs: 1
Total Memory: 2 GiB
Name: WIN-MHGJL27HUMP
ID: BPAV:7YAF:HPTJ:D74L:PEZ3:CBAA:VFQN:OEGJ:LPJZ:EFJ3:VMX7:ZU34
Docker Root Dir: C:\ProgramData\docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false

Ok now, the container host is up and running and we can deploy our first Windows container using the next command.

> docker run -it -—name infpressapochista microsoft/nanoserver powershell

Using the above command we’ve created a new container based on the image named microsoft/nanoserver, and the power shell command prompt that will appear will be “inside” the container itself !

Att.: microsoft/nanoserver, is an image of a real small windows machine. It is possible to use other images (pls check docker official website to know the list of all the avaible images) or you can create itself other.

> mkdir pippo
> dir

Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/5/2017 1:49 PM pippo
d----- 2/5/2017 1:49 PM Program Files
d----- 7/16/2016 2:09 PM Program Files (x86)
d-r--- 2/5/2017 1:49 PM Users
d----- 2/5/2017 1:49 PM Windows
-a---- 11/20/2016 12:32 PM 1894 License.txt
> exit

Using exit the container has stopped.

Reenable the same container.

> docker run -it microsoft/nanoserver powershell
> dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/5/2017 1:51 PM Program Files
d----- 7/16/2016 2:09 PM Program Files (x
d-r--- 2/5/2017 1:51 PM Users
d----- 2/5/2017 1:51 PM Windows
-a---- 11/20/2016 12:32 PM 1894 License.txt

Using exit you will end & exit from container, and all the user data inside that will be lost !

The very first time that you run a container the entire image will be downloaded from the docker officiali repository using internet connection (see linkografia): for microsoft/nanoserver the image size is approx 250 MB. The next time that you’ll try to use the same image container this dowloaded image will be re-used.

You can find other images in docker repository using the next command.

> docker search [TERM]

You can check all the locally downloaded image using the next command.

> docker images

The basic docker run command takes this form.

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG…]

You can see that the docker run command must specify an IMAGE to derive the container from: if this image does not exist in your local machine will be downloaded from the docker image repository via internet connection, if it is not present locally.

In the above commands we’ve created a container running in foreground mode: this means that the container will be started and attach the console to the process’s standard input, output, and standard error via the command [COMMAND] (in our case the shell powershell).

The container will be stopped and all the data contained in the file system will be lost if I quit using exit (because I’ve stopped powershell).

To exit from the container (detaching standard input, output, and standard error without turning off the shell power shell and the related container) the correct whey is to use Ctrl-p + Ctrl-q (or closing the shell…..).

You can see all the running container using next command.

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a42fb760f6aa microsoft/nanoserver "powershell" 18 minutes ago Up 18 minutes got
0fe7fe0eb260 microsoft/nanoserver "powershell" About an hour ago Up About an hour flamboyant_engelbart

To reenter in a running container you can use the next command.

> docker attach [CONTAINER ID]

Where [CONTAINER ID] is the id showed in docker ps command

You can stop a running container using next command.

> docker stop [CONTAINER ID]

Some important notes.
– You cannot run inside a container windows form related-applications ! Docker is really different form virtualization and software GUI are not supported yet.
– In Windows 10 it is possible run Linux-base container: using Windows 2016 it is possible to run only windows-base docker image (Linux images does not work at all).

Att.: These notes as of now 2017 are valid, but it is possible (and I’m sure !) that in the future something something will change.

Using the -d param like option we’ll obtain a container in detached mode, that start without attaching the console to the running console, and exit only when the root process used to run the container exits.

For this reason command can be any software without GUI: powershell, shell-related software.

> docker run -d microsoft/nanoserver powershell ping -t localhost

This will run a container from an image microsoft/nanoserver and -d puts the container in the detached/background. The reason for ping is that docker cares about the processes that run in the containers and as soon as the process that the Docker container was created to run exits then the container hosting the process is automatically stopped.

One solution is to make sure you specify a process that constantly runs, for example never ending ping to itself.

This is just a small introduction to docker’s world: in future post I’ll describe more interesting feature.

Linkografia
Docker official website
Docker Official Repositories
1, 2, 3, GO! Run IIS in Docker on Windows Server 2016