Macadamian Blog

Docker-Machine: Basic Examples

Christian Nadeau

When using a containerized application, it’s important to be able to easily deploy them in the cloud. Docker-Machine is a tool that lets you install Docker Engine on Virtual Hosts. We’ll outline how we deploy containers and how to transfer files to/from the machine.

getting started with docker machine

What is docker-machine?

When you have a containerized application, it’s important to be able to easily deploy them in the cloud, not only running them locally using Docker for Mac/Windows or from a Linux box locally. The tool to be able to create a remote virtual machine (VM) easily and manage those containers is called docker-machine.

In short, it allows you to control the docker engine of a VM created using docker-machine remotely. It even allows you to update the docker engine, restart the virtual machine (depending if the driver supports it), view its state and so on.

The main reason you would use docker-machine is when you want to create a deployment environment for your application and manage all the micro services running on it. For instance, you can easily have a development, staging and production environment accessible from your own machine and update them accordingly.

docker-machine overview
The drivers concept acts as a connector to 3rd party services such as Azure, Amazon, etc. This allows you to create a complete set of resources around the actual VM in order to easily manage it from each service’s admin portal. There is also the generic driver which allows you to convert an actual virtual machine into a docker-machine.

NOTE: Reference material may be downloaded here

How to create a docker machine?

Azure

This will create a virtual machine on Azure and install docker engine on it.

#!/usr/bin/env bash
set -e
MACHINE_NAME="VIRTUAL MACHINE NAME"
RESOURCE_GROUP="RESOURCE GROUP NAME"
SUBSCRIPTION="YOUR AZURE SUBSCRIPTION ID"
AZURE_LOCATION="eastus"
AZURE_VNET_NAME="VNET NAME"
docker-machine create --driver azure \
                      --azure-availability-set="MACHINE_NAME-as" \
                      --azure-subscription-id="${SUBSCRIPTION}" \
                      --azure-location "${AZURE_LOCATION}" \
                      --azure-open-port 80 \
                      --azure-open-port 443 \
                      --azure-size "${AZURE_MACHINE_SIZE}" \
                      --azure-subnet "${AZURE_VNET_NAME}-subnet" \
                      --azure-vnet "${AZURE_VNET_NAME}" \
                      --azure-resource-group "${RESOURCE_GROUP}" \
                        ${MACHINE_NAME}

 

VERY IMPORTANT:

docker-machine rm <machine-name>

This command will DELETE the Azure virtual machine and all related resources from your subscription! Use it with care.

VirtualBox

This will create a virtual machine on your local VirtualBox instance and install docker engine on it.

#!/usr/bin/env bash
set -e
MACHINE_NAME="MACHINE NAME"
docker-machine create --driver virtualbox ${MACHINE_NAME}

Generic

This will use the public identification key in order to connect to an existing machine (virtual or not) and install docker engine on it.

NOTE: This driver does not yet allow you to restart/shutdown the system.

#!/usr/bin/env bash
set -e
MACHINE_IP="MACHINE IP"
MACHINE_NAME="MACHINE NAME"
SSH_USER="MACHINE USERNAME"
SSH_PUBLIC_KEY="MACHINE USERNAME PUBLIC KEY PATH"
# If you did an ssh-copy-id to the machine: ~/.ssh/id_rsa
docker-machine create --driver generic \
--generic-ip-address=${MACHINE_IP} \
--generic-ssh-key ${SSH_PUBLIC_KEY}\
--generic-ssh-user ${SSH_USER}\
${MACHINE_NAME}

You have a docker-machine VM, now what?

NOTE: We’ll suppose the docker-machine is created, reachable and named demo-machine

Here is a simple docker-compose.yml example:

version: '2'
services:
web:
image: dockercloud/hello-world:latest
ports:
- "80:80"

Deploy containers locally

Start this hello world docker-compose locally:

docker-compose up -d

You can curl it locally and see the content of the index.html page:

curl localhost:80

Now stop and delete the created container of the locally started docker-compose:

docker-compose down

Deploy containers to a remote host

Let’s do the same thing but on the remote demo-machine.
Change the local docker environment variables to the demo-machine ones:

eval $(docker-machine env demo-machine)

You’re now targeting demo-machine when using any docker commands. To validate which docker-machine you point to, use this command:

$ docker-machine active
demo-machine

Start the same hello world docker-compose defined locally:

docker-compose up -d

Try to curl locally:

$ curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused

The docker commands are not run locally, they are run on the docker-machine we just configured! You must use the IP of the docker-machine itself as follow:

curl $(docker-machine ip demo-machine):80

SSH

Once the machine is created, it’s really easy to ssh into it because the SSH certificates are generated on the machine and kept locally:

docker-machine ssh demo-machine

Copy files to/from the machine

You can use SCP command to send/receive files to/from the machine.

Here is how to copy ~/localfile.txt into the home folder of the demo-machine

docker-machine scp ~/localfile.txt demo-machine:~/

Here is how to copy ~/remote.txt from the home folder of the demo-machine to the local home folder:

docker-machine scp demo-machine:~/removefile.txt ~/

Cleaning up the local docker environment

If you want to go back to your local instance:

eval $(docker-machine env -u)

To validate:

$ docker-machine active
No active host found

 

Insights delivered to your inbox

Subscribe to the dev blog to get the latest insights in IoT, Alexa Skills development, and software development.

Author Overview

Christian Nadeau

Christian is a veteran software developer at Macadamian with specialties in .NET ( WPF, Silverlight, Window Phone 8 ), java (J2EE, JBoss), C++ (Qt, BB10). He holds a bachelor's degree in computer engineering from the University of Sherbrooke.