Running Linux Docker containers on Windows without virtualization

If your Windows development machine doesn't support virtualization you can still use Docker to run Linux containers. In this post I'll outline the steps to get it working.

My primary development machine is an Azure VM at the moment. At the time of writing Azure doesn't support nested virtualization so I can't run Linux containers on it. All is not lost however - using Docker Machine with the Azure driver I can use a remote Docker host to run my containers.

Docker client vs Docker engine

At it's core Docker is two components - the client and the engine. In most development scenarios you'll have both installed on your machine. In my case however, I can't run a local VM to host my Linux containers.

The solution is to install the Docker client from the Docker Toolbox, and then use Docker Machine to provision a Linux VM which will run the Docker engine. I'm going to host my VM on Azure, but most other cloud providers are supported too.

Getting Started

First, install the Docker Toolbox from https://docs.docker.com/toolbox/overview.

Creating the Docker host

To create your Docker host, run the following command:

docker-machine create docker-host --driver azure --azure-subscription-id {subscription-id} --azure-location northeurope --azure-static-public-ip

This tells Docker Machine to create a VM called docker-host using the Azure driver. You'll want to choose a region which is close to you.

The --azure-static-public-ip option creates the VM with a static IP address. We need this to make sure Docker Machine can find our VM after a reboot.

The docker-machine create command provisions a number of Azure resources in a docker-machine resource group:

Docker Machine ships with drivers for Amazon Web Services, Google Compute Engine, Digital Ocean and more. There is a full list on the Docker docs site.

Configure Docker client to use a remote host

The final step is to tell the Docker client to use our remote host. The client is configured using environment variables. We can run this command to discover the values for our host:

docker-machine env docker-host

And to set them for the current console session:

@FOR /f "tokens=*" %i IN ('docker-machine env docker-host') DO @%i

To verify the host is setup correctly, run this command:

docker-machine ls

Which should produce output like this:

Running a container

We are now ready to run our first container:

docker run -it hello-world

Which should produce:

Wrap up

That's it. We now have a remote host running the Docker engine and controlled from our local Docker client.

You'll also need to open ports on your docker-host-firewall network security group in the Azure portal if you want to allow inbound traffic to your containers.

References