Getting Started with Docker by Practice | 5. Creating a Docker Host on Windows with Docker Machine

This section introduces how to create a Docker host on a Windows PC using a tool called Docker Machine. A Docker host is an environment where Docker is installed and ready to use. The earlier “Docker image and container management mechanism” article introduced GUI tools such as Docker for Windows and Docker Toolbox for creating Docker hosts, but this time we will use Docker Machine, a CLI tool. If a virtualization tool such as VirtualBox is available, Docker Machine creates a Docker host with a single command.

Docker hosts were hard to create

Before using Docker Machine, let’s first look at why Docker Machine appeared.

One characteristic of Docker is that it improves application portability. The earlier article also explained that Docker can deploy applications to various environments and that once an application is made into a Docker container image, it can run as-is on various platforms.

This portability is only possible when an environment that can use Docker, in other words a Docker host, exists. Only when a Docker host exists can an application gain high portability.

However, creating a Docker host was never easy, especially around 2013 when Docker appeared. For example, to create a Docker host, an OS was needed, but what OS should be prepared? In the early days of Docker, only Ubuntu 12.04/12.10 was supported. You needed that Ubuntu environment, had to create it, or needed patches and other work on Linux distributions other than Ubuntu.

From Docker 0.7, released in November 2013, all major Linux distributions were supported, but technology for creating Docker hosts was still not very developed.

The appearance of Boot2Docker

Then, at a Docker Inc. event in December 2013, Boot2Docker was announced.

Boot2Docker is a tool that creates a Docker host in VirtualBox, a virtualization tool. Initially it supported only Mac, but later Windows support was added.

Boot2Docker consists of two parts.

  1. An OS image file used as the basis for creating a Docker host
  2. A CLI tool for creating and managing Docker hosts

Boot2Docker overview

The OS image file is based on a lightweight Linux distribution called Tiny Core Linux. Unlike general-purpose server OSes such as Ubuntu, it includes only the minimum required for a Docker host, so its size is very light, only tens of MB.

The CLI tool commands are intuitive and easy to understand, such as init, up, and down, and do not require much Linux knowledge.

Because the OS and tool are provided as a set, even users who are not very familiar with Docker or Linux can easily and reliably create a lightweight Docker host.

The appearance of Docker Machine

With the appearance of Boot2Docker, creating Docker hosts became very simple. Docker Machine was developed as the successor to Boot2Docker. Docker Machine was announced at DockerCon EU in December 2014.

Like Boot2Docker, Docker Machine is a tool that can easily create and manage lightweight Docker hosts. Technically, it inherits and develops Boot2Docker’s results as follows.

  1. Boot2Docker and other images can be used as the OS image file used as the basis for creating Docker hosts.
  2. The CLI tool for creating and managing Docker hosts was migrated from Boot2Docker.
  3. Various virtual environments such as Hyper-V and AWS, not only VirtualBox, can be used.

Docker Machine overview

The biggest difference from Boot2Docker is item 3, virtual environments. Docker Machine has a driver mechanism, and by switching drivers such as the VirtualBox driver or AWS driver, Docker hosts can be created in various virtual environments. Currently, more than ten types of drivers are built into Docker Machine in advance. Drivers can also be created directly, and more than 20 third-party drivers exist.

Thanks to Docker Machine, creating Docker hosts became even easier. New tools for creating Docker hosts continued to be developed after this, which is discussed in the final summary.

Preparation

Now let’s introduce concrete usage of Docker Machine. The flow is as follows.

  • Preparation
  • Install Docker Machine
  • Create a Docker host
  • Log in to the Docker host
  • Run Hello World on the Docker host

First, install VirtualBox on Windows 10 as preparation. Also, naturally, confirm that PowerShell commands can be executed.

The environment used here is as follows.

  • Windows 10 Pro
  • VirtualBox 6.1.22
  • PowerShell 5.1.19041.1023

Windows 10

The newer tool “Docker for Windows” for creating Docker hosts works on Windows 10 or later, but Docker Machine works from Windows 7 and later. Refer to this if you use Windows 7 or older.

VirtualBox

VirtualBox is Docker Machine’s default virtual environment tool. The Windows installer can be downloaded from the VirtualBox site. Docker Machine can also use AWS and other environments, but for a first Boot2Docker-style experience, VirtualBox is recommended because troubleshooting information is plentiful.

If you want to use Hyper-V on Windows, note that using Hyper-V and VirtualBox at the same time is technically impossible.

PowerShell

Many people think of Command Prompt as Windows CLI, but this article uses PowerShell.

PowerShell is installed on Windows by default, but Windows 7 may have an old version. You can display the PowerShell version by entering the following in PowerShell.

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.1023

(omitted)

$PSVersionTable is a variable automatically created by PowerShell that stores version information.

Install Docker Machine

After preparation is complete, install Docker Machine. Installation is simple. Download the binary file and configure the Path.

The Docker Machine version used here is v0.16.2. The binary file can be downloaded from the Docker Machine GitHub release page. The Windows 64-bit file name is docker-machine-Windows-x86_64.exe. Rename the downloaded file to docker-machine.exe and save it somewhere appropriate. Here, the explanation assumes the file exists at the following location.

C:\docker\docker-machine.exe

Open PowerShell and run the following command to check operation.

PS C:\> C:\docker\docker-machine.exe version
docker-machine.exe version 0.16.2, build bd45ab13

Version information is printed.

It is inconvenient to enter such a long path every time, so add C:\docker to the Windows environment variable Path. Restart PowerShell and run:

PS C:\> docker-machine version
docker-machine.exe version 0.16.2, build bd45ab13
PS C:\>

If information is printed, installation succeeded. Unlike before, .exe was omitted from the end of docker-machine. It works with .exe, but it can also be omitted.

Installation is now complete. Finally, let’s actually run Docker Machine and create a Docker host.

Create a Docker host

Docker Machine creates a Docker host with the following single command.

PS > docker-machine create --driver virtualbox devkumahost

Caution: If Hyper-V is already installed, running docker-machine create may produce an error saying that VirtualBox cannot boot a 64-bit VM while Hyper-V is enabled. As mentioned above, using Hyper-V and VirtualBox at the same time is technically impossible, so one of them should not be used. In this example, VirtualBox is used, so disable the Hyper-V feature and reboot.

create is the command that creates a Docker host, and devkumahost is the name of the Docker host. --driver, or -d, specifies the driver; here, the VirtualBox driver is specified. Since VirtualBox is the default driver, --driver can also be omitted.

PS > docker-machine create devkumahost

When executed, logs are printed showing Boot2Docker image download, VirtualBox VM creation, SSH key creation, VM startup, certificate copying, Docker daemon configuration, and connection checking.

Docker is up and running!

Docker is running on the Docker host.

Only one create command was executed. In the author’s environment, it took only a few minutes.

Check whether the Docker host was really created.

PS C:\> docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
devkumahost   -        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.12

The ls command prints the list of Docker hosts. You can confirm that a Docker host named devkumahost was created. Since the state is Running, it is running. v19.03.12 is the Docker version in use.

Log in to the Docker host

Next, log in to the Docker host you created.

Login is done with SSH. SSH settings are already completed automatically, so specifying the host name with Docker Machine’s ssh command logs you in.

PS C:\> docker-machine ssh devkumahost
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@devkumahost:~$

When you create a Docker host with Docker Machine like this, you almost do not need to worry about SSH.

Hello World on the Docker host

Now that you can log in to the Docker host, check Docker operation.

Docker is already installed on the Docker host and is ready to run. While logged in to the Docker host, create and start the hello-world container as follows.

docker@devkumahost:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:9f6ad537c5132bcce57f7a0a20e317228d382c3cd61edae14650eec68b2b345c
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

Hello from Docker! is displayed.

Now you have created a Docker host with the create command, logged in with SSH, and used Docker.

Actually, if you have Docker CLI on Windows, you can use Docker without logging in with the ssh command, but that method will be introduced later.

Start and stop a Docker host

If you have followed the steps so far, you are probably logged in to the Docker host devkumahost.

First, log out from the Docker host with Linux’s exit command.

docker@devkumahost:~$ exit
logout
PS C:\>

Even after logging out, the Docker host is running. Check the state with the status command.

PS C:\> docker-machine status devkumahost
Running

Stop it with the stop command.

PS C:\> docker-machine stop devkumahost
Stopping "devkumahost"...
Machine "devkumahost" was stopped.

Check again with status; Stopped is displayed.

Start it again with the start command.

PS C:\> docker-machine start devkumahost
Starting "devkumahost"...
Machine "devkumahost" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

If you run the restart command instead of stop and start, it stops and then starts again.

Remove a Docker host

An unnecessary Docker host can be deleted with the rm command.

PS C:\> docker-machine rm devkumahost
About to remove devkumahost
WARNING: This action will delete both local reference and remote instance.
Are you sure? (y/n): y
Successfully removed devkumahost

To check whether it was deleted, list Docker hosts with ls.

PS C:\> docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

Docker host configuration information

Running the inspect command outputs Docker host configuration information in JSON format.

PS C:\> docker-machine inspect devkumahost
{
    "ConfigVersion": 3,
    "Driver": {
        "IPAddress": "192.168.99.102",
        "MachineName": "devkumahost",
        "SSHUser": "docker",
        "SSHPort": 2644,
        (omitted)         

Configuration files are also stored in the following folder and can be opened with a text editor.

<user home directory>\.docker\machine\machines\<host name>\config.json

Specify a Boot2Docker version

If nothing is specified, Docker Machine downloads and uses the latest Boot2Docker image file.

If you want to use a specific Boot2Docker version, specify the image file URL with --virtualbox-boot2docker-url.

PS C:\> docker-machine create --virtualbox-boot2docker-url https://github.com/boot2docker/boot2docker/releases/download/v19.03.12-ce/boot2docker.isl devkumahost1903

The original article encountered an error here and leaves it for later investigation.

Execute commands on a Docker host

The ssh command can execute Docker host commands as arguments. You do not need to separately enter login and logout commands. SSH clients such as OpenSSH also have the same feature.

The following example runs ls on devkumahost and displays the contents of the /home directory.

PS C:\> docker-machine ssh devkumahost ls /home
docker
dockremap
PS C:\>

Configure proxy information on a Docker host

When running hello-world, you may see an error like this.

docker@devkumahost:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on 10.0.2.3:53: no such host.
See 'docker run --help'.

One possible cause is that a company or school HTTP proxy cannot be passed. In that case, configure proxy information on the Docker host.

Proxy information can be set with options of the create command.

PS> $http_proxy = 'https://myproxy.com:1234'
PS> $https_proxy = 'https://myproxy.com:1234'
PS> docker-machine create --engine-env HTTP_PROXY=$http_proxy --engine-env HTTPS_PROXY=$https_proxy myhost

$http_proxy and $https_proxy are PowerShell variables. --engine-env specifies environment variables referenced by Docker in variable=value format.

If a username and password are required, configure them as follows.

PS> $http_proxy = 'https://user:password@myproxy.com:1234'
PS> $https_proxy = 'https://user:password@myproxy.com:1234'
PS> docker-machine create --engine-env HTTP_PROXY=$http_proxy --engine-env HTTPS_PROXY=$https_proxy myhost

Be careful because this username and password can be seen as plain text with the inspect command. They are also stored as plain text in the Docker Machine configuration file, config.json.

Default host name “default”

It is convenient to set the Docker host name to default. Some commands can omit the host name.

For example, if you run the start command without specifying a host name, such as docker-machine start, the Docker host named default is started. Similarly, docker-machine stop stops the Docker host named default.

Help

In addition to what was introduced above, Docker Machine provides various commands and options. Help is displayed with the following command, so try practicing with it.

PS C:\> docker-machine
Usage: docker-machine.exe [OPTIONS] COMMAND [arg...]

(middle omitted)

Commands:
  active                Print which machine is active
  config                Print the connection config for machine
  create                Create a machine
  env                   Display the commands to set up the environment for the Docker client
  inspect               Inspect information about a machine
  ip                    Get the IP address of a machine

(omitted)

This article introduced how to create a Docker host on Windows using Docker Machine.

Besides Docker Machine, Docker Inc. has developed various tools. The following summarizes where Docker Machine fits among those tools.

Docker Machine-related tools and publication years:

  • Boot2Docker (2013)
  • Docker Compose (Fig) (2014)
  • Kitematic (2014)
  • Docker Machine (2014)
  • Docker Toolbox (2015)
  • Docker for Windows (2016)
  • InfraKit (2016)
  • LinuxKit (2017)

Docker was announced in March 2013. Soon after, various tools were developed outside Docker Inc., and Docker Inc. actively brought those tools in-house.

Docker Compose, introduced in the “Deploying multiple containers with Docker Compose” article, was originally a tool named Fig developed by a UK startup, but it was soon acquired by Docker Inc.

Kitematic is a GUI tool for operating Docker. It was also acquired by Docker Inc. in 2015.

Docker Machine was announced at DockerCon EU in December 2014. As explained, Docker Machine is a tool that developed Boot2Docker’s achievements further.

Docker Toolbox was a tool intended to make Docker easy to use on Windows and Mac. It packaged Docker Compose, Kitematic, Docker Machine, and other tools together. In a sense, it was a compilation of the development tools Docker Inc. had built.

Then a new flow seems to have started. Docker for Windows, like Toolbox, was intended to make Docker easy to use on Windows. However, Docker for Windows basically does not use Docker Machine as the method for creating Docker hosts. Docker Machine is evaluated as a tool used when needed, such as for creating cluster environments. It also adopts Hyper-V instead of VirtualBox as the virtualization tool.

InfraKit and LinuxKit are tools for creating and managing Docker hosts and creating image files. They can be seen as more powerful than Docker Machine and more flexibly customizable than Boot2Docker. Comments in Docker Machine’s GitHub repository indicate that Docker Inc. intended to focus on InfraKit and LinuxKit in the future, while continuing to maintain Docker Machine without adding new features.

Personally, the author still thinks Docker Machine is a good first tool for people who are not yet familiar with Docker. GUI tools such as Docker for Windows are convenient, but their internal structure is hard to see. Experience with Docker Machine makes it easier to understand roughly what Docker for Windows does and helps users become comfortable with Docker more quickly.

As introduced in this article, Docker Machine is an easy-to-use tool. To understand and use Docker efficiently, try working with Docker Machine.