Docker Machine

Machine makes it easy to set up Docker hosts on supported platforms, including Linux, Windows, OS X, and various cloud providers, in a standard way.

Background

You need a Docker host to run containers. A Docker host provides the ability to run processes in isolation from each other, granting each controlled access to system resources and dedicated network configuration.

This sounds a lot like the benefit of using virtual machines, but there are important differences:

  • The definition of what is needed to compose and configure the container process runtime environment is neatly encapsulated in a simple text Dockerfile.

  • Containers don't need to store an entire guest operating system and require a hypervisor to run. Instead, they are far more lightweight and efficient, running directly on the Docker host system and leveraging the isolation features of a shared Linux kernel.

docker vs vm

A Docker host is a physical computer system or virtual machine running Linux. This can be your laptop, server or virtual machine in your data center, or computing resource provided by a cloud provider.

The component on the host that does the work of building and running containers is the Docker Daemon. The daemon starts each container using a template for the container's specific runtime environment called an image, which is retrieved from an image repository, like the public repositories hosted at Docker Hub. (You can search for image repositories using the official Docker registry.)

Images might sound like guest operating systems for virtual machines, but they are much more lightweight and much more efficient. They rely on the shared Linux kernel of the host, so they only add the binaries and other resources needed by the application, and they don't go through a virtualization layer for execution.

Images are actually composed of layers of images that are cached on the host and shared across containers, and they leverage the copy-on-write union file system for storage efficiency and performance (because the image doesn't need to be copied for each new container, and unlike a guest OS, the image doesn't need to boot since the shared kernel is already running).

image layers

You manage images and containers by communicating with the Docker Daemon from a client via the Docker REST API. For interactive sessions, the Docker command line interface (CLI) provides a convenient wrapper for the API. By default, the daemon can only accept local connections over a Unix domain socket.

docker host

For a computer to be a Docker host, it needs to be running Linux. If the computer (such as your laptop) happens to be running another operating system (like OS X and Windows), then it will be necessary to use a virtual machine that runs Linux.

Enter Machine

Machine sets up Docker hosts on any supported system via provider drivers.

Currently, you can use Machine to set up a Docker host using the following providers:

Installing Machine

You can download Machine binaries to install on your own Linux, OS X, and Windows systems from here.

You can also install manually for Linux and OS X by entering the following commands:

OS X

$ curl -L https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_darwin-amd64 > /usr/local/bin/docker-machine
$ chmod +x /usr/local/bin/docker-machine

So that you don't have to ssh into the Docker host itself to run Docker commands, you can download a Docker client for OS X.

$ curl -L https://get.docker.com/builds/Darwin/x86_64/docker-latest > /usr/local/bin/docker

Linux

$ curl -L https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_linux-amd64 > /usr/local/bin/docker-machine
$ chmod +x /usr/local/bin/docker-machine

If you want to install manually on Windows, follow the instructions here.

Whichever method you choose to use for installation, you can verify that Machine is installed by checking the version like this:

$ docker-machine -v
machine version 0.2.0  

Machine test drive

As previously mentioned, on OS X and Windows systems, Docker hosts will need to run in Linux virtual machines.

Machine provider support includes VirtualBox, and so it works with directly with VirtualBox without your intervention, but VirtualBox will still need to be present on your system first. Make sure to install the latest version (at least 4.3.26) from here.

To create a new Docker host named dev that will run in a VirtualBox VM, enter the following (I've provided a few annotations for examples taken from the docs):

$ docker-machine create --driver virtualbox dev
INFO[0001] Downloading boot2docker.iso to /home/<your username>/.docker/machine/cache/boot2docker.iso...  
INFO[0011] Creating SSH key...  
INFO[0012] Creating VirtualBox VM...  
INFO[0019] Starting VirtualBox VM...  
INFO[0020] Waiting for VM to start...  
INFO[0053] "dev" has been created and is now the active machine.  
INFO[0053] To point your Docker client at it, run this in your shell: eval "$(docker-machine env dev)"  

Behind the scenes, Machine created and set up a new VM (called dev) and started it running with VirtualBox. It installed a lightweight Linux distribution (boot2docker) to host the Docker daemon. Images you use with dev will be stored in the VM and any containers you start will run inside it as well.

You can verify that a machine was created like this:

$ docker-machine ls
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM  
dev    *        virtualbox   Running   tcp://192.168.99.100:2376  

The SWARM field is empty since the host is not associated with a cluster. We'll cover Docker Swarm in another post.

dev is marked with an * as the active host, which means that any Docker commands you enter at the command line will be directed to it. But in order for that to work, you need to point your Docker client at it by configuring your environment.

You update your environment by running eval on the output of executing docker-machine env dev, which conveniently provides environment variables that Docker uses for how to communicate with a specific host.

If you want to see what variables will be exported, you can enter

$ docker-machine env dev
export DOCKER_TLS_VERIFY=1  
export DOCKER_CERT_PATH="/Users/<user>/.docker/machine/machines/dev"  
export DOCKER_HOST=tcp://192.168.99.100:2376  

To actually update the environment, enter

$ eval "$(docker-machine env dev)"

You will need to repeat this each time you open a new shell.

At this point, you can now run Docker commands against this host. See my previous blog post on getting up and running with io.js on Docker.

When you run a container on this host, any ports that the container exposes are accessible at the host's IP address. You can use the following command to get it:

$ docker-machine ip
192.168.99.100

You can start and stop the host with the following commands:

$ docker-machine stop
$ docker-machine start

If you started more than one host with Machine, you can specify the host specifically if it's not the active one by adding the name:

$ docker-machine stop dev
$ docker-machine start dev

You can find other commands here or just enter docker-machine help.

Conclusion

Although still in beta, Machine is worth trying now. It provides a simple interface for interacting with a large number of providers through its drivers to create and set up Docker hosts on various servers.

Online Meetup Videos

Nathan LeClaire gave a nice presentation, "Presenting Machine 0.2.0," on the Docker Online meetup last week. You can see the video here.

Next Tuesday, May 12, 2015, I will also be hosting a live stream for the new Node and Docker online meetup. The topic is Getting Started with io.js and Docker, and I'll also introduce Machine. You can get the details here. The session will be recorded.

I originally published this article on Codefresh.