Hits: 12532

I recently had to help a technology high growth business with the installation of Docker across their mixed Operating System estate. I figured that it would be useful to set up a small environment in my lab, to assist with the process, the inevitable debugging and potentially, the documentation. This post lists the steps that I took and hopefully, others might benefit from it too.

So, what is Docker?

To quote "In 2013, Docker introduced what would become the industry standard for containers. Containers are a standardized unit of software that allows developers to isolate their app from its environment, solving the 'it works on my machine' headache." This is really important when shipping software between environments. It is all too common to hear "it worked in UAT but it doesn't work in Production". Containers make that scenario much less likely and give a layer of abstraction so that Developers do not need to work about the underlying IT Infrastructure (and vice versa).
The Docker docs are extremely helpful in gaining a deeper understanding of the architecture and how to implement Docker. Additionally, there are further helpful posts Docker architecture, a Beginners Guide to Docker and an interview with a Docker executive here.
This post is specifically focussed at a mixed Operating System environment, where the clients are Windows based and the servers are running Linux (in this case, Ubuntu).

Installing the Docker client on Windows 10 laptop/desktop 

Since I do not have Hyper V on my Windows devices, I am opting for the legacy Docker Toolbox for Windows. This will install the Docker client so that I can control the Docker server/daemons out on my lab network. The Windows boxes are 64 bit (x64) so this is fine as it is a prerequisite.
You can get the .exe at
It will also install VirtualBox so be careful that it is not already installed.
It creates a local Docker machine on the Windows device.

Installing the Docker server installation on Ubuntu 16.04

Log onto the box and the run the following commands:
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce (CE stands for Community Edition, as opposed to Enterprise Edition)
Test that it installed ok by doing:
sudo docker run hello-world
docker --version
Start docker as a daemon and get it to start at startup next time:
sudo systemctl start docker
sudo systemctl enable docker
One last test to check all is well:
sudo docker run --rm -ti ubuntu:latest /bin/bash

Connect the Windows Docker client to the Ubuntu Docker server

This requires that you are able to ssh to the remote host (Ubuntu server) and sudo without entering a password:
Run and look at output from:
If it is not set up already then run C:\Windows\System32\OpenSSH\ssh-keygen to generate a public key ( which is located in the same directory while the public key is stored in C:\Users\<user>\.ssh
Now add the contents of to authorized_keys in .ssh on the Ubuntu server using cat.
Once complete, you should be able to ssh to the Ubuntu server from the Windows client:
ssh [email protected]<IP of Ubuntu server>
and can log in without a password.
As Docker needs to be able to sudo without a password also do on the Ubuntu server:
sudo visudo
and add the below line to the file
{username}  ALL=(ALL) NOPASSWD:ALL

To provision a remote Docker host machine

In a cmd window on the Windows 10 box
Go to C:\Program Files\Docker Toolbox
and run
docker-machine create --driver generic --generic-ip-address=<IP address of Ubuntu server> --generic-ssh-user=pgroom <hostname of Ubuntu server> where pgroom is an user on the Ubuntu server
docker-machine env <hostname of Ubuntu server>
SET DOCKER_HOST=tcp://<IP address of Ubuntu server>:2376 
SET DOCKER_CERT_PATH=C:\Users\net_k\.docker\machine\machines\remote-docker-host 
SET DOCKER_MACHINE_NAME=<hostname of Ubuntu server>
REM Run this command to configure your shell: 
REM     @FOR /f "tokens=*" %i IN ('docker-machine env remote-docker-host') DO @%i 
then run this
@FOR /f "tokens=*" %i IN ('docker-machine env nklserv02') DO @%i
to check which machine connected to:
docker-machine ls
Finally, check all is ok on the Ubuntu server:
docker run ubuntu /bin/echo hello world

Some helpful hints/commands when operating Docker containers

Removing a Docker container
If a Docker container is no longer required then you can remove it by:
docker rmi <image id>
where the <image id> is part of the output from docker images command
or by:
docker-machine rm <hosntame of Ubuntu server>
Debugging a Docker container
To debug and get to a shell inside the container do (assuming it was started by something like the below):
docker run -d -t ubuntu /bin/bash
Can look for the container ID by running docker ps and looking for the command /bin/bash - in this case 5b8c64046b71 (or use the name if you gave the container one when you created it)
Then do
docker exec -t -i 5b8c64046b71 /bin/bash
and you get a prompt of
[email protected]:/#
you can now debug the Docker container interactively

Creating and starting a Docker container
Below are the steps that I went through to create a Docker container that runs a simple Curl PHP script. It lists all recruitment agencies by UK county and is normally run as per below:
/usr/bin/php /home/pgroom/agencies.php Devon
Option 1 - interactive Bash shell
docker run --name=curl -d -v -i /home/pgroom:/home ubuntu:latest /bin/bash
However the name has to be unique so can't have 2 containers with the same name, even if one is stopped
Option 2 - Using a Dockerfile then run a machine that runs curl and exits
This is the Dockerfile
FROM ubuntu:latest
RUN apt-get update && \
apt-get install -y tzdata
RUN ln -fs /usr/share/zoneinfo/Europe/London /etc/localtime
RUN dpkg-reconfigure --frontend noninteractive tzdata
RUN apt-get install -y php && \
apt-get install -y curl

COPY agencies.php /home/pgroom
Then build the image
docker build -t jrncurl:0.1 "C:\Program Files\Docker Toolbox\dockerfiles"
where C:\Program Files\Docker Toolbox\dockerfiles is the directory that has the Dockerfile listed above and note the lowercase for the tag.
Although php install needs to know which country and city in order to proceed as it used tzdata so need to put 2 extra lines, one for /etc/localtime and the other for dpkg-reconfigure
The last couple of lines look something like this:
Removing intermediate container 4fb2c32171b3
 ---> 82df8e0dd07d
Successfully built 82df8e0dd07d
Now need to start a container based on the build so:
docker run -it jrncurl:0.1 /bin/bash
Problem: Can't access the file system so can't get to agencies.php
Tried to copy the script but no luck as could not find the file agencies.php
COPY failed: stat /var/lib/docker/tmp/docker-builder658320030/agencies.php: no such file or directory
Found a copy command that worked but this generates an error as it is outside of the Docker context i.e. directory
COPY ../../../../../home/pgroom/agencies.php /home/agencies.php
In the end, had to copy agencies.php to C:\Program Files\Docker Toolbox\dockerfiles
Then run:
docker build -t jrncurl:0.6 "C:\Program Files\Docker Toolbox\dockerfiles"
This now builds the image but need to remember that the file has to be in the same directory as the Dockerfile.
Now need to start a container based on the build so:
docker run -it jrncurl:0.6 /bin/bash
Can now run the below and get the results back
/usr/bin/php /home/pgroom/agencies.php Devon
Hopefully the above will be of use to someone and as one engineer to another, good luck with whatever you are building.
All the best.