Corporate Proxy with docker-machine

Docker For Windows? Thanks, but I still prefer docker-machine. With docker machine I am able to execute VirtualBox on Windows 10.

Docker machine setup is not super-easy per se, if we add also a corporate proxy and the (WSL docker client the overall setup is a bit tricky.

This is how I glued everything together.

I won’t go into details on how to download docker-machine executable and to create a new docker VM on Virtualbox. From now on I will refer to a default docker machine running locally.

C:\> docker-machine ls
NAME     ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default  -        virtualbox   Running   tcp://192.168.99.101:2376           v18.09.1

Docker usage in WSL

A docker client is able to connect a remote engine with the proper environment configuration (e.g. DOCKER_HOST, DOCKER_CERTS, etc.).

## Detect environment on Windows

C:\> docker-machine env default --shell bash
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:2376"
export DOCKER_CERT_PATH="C:\Users\lei00021\.docker\machine\machines\docker-host"
export DOCKER_MACHINE_NAME="docker-host"
export COMPOSE_CONVERT_WINDOWS_PATHS="true"
# Run this command to configure your shell:
# eval $(docker-machine-win env docker-host --shell bash)

The docker command supports arguments for each of the previuous variables.

## Invoke docker client on WSL

$ docker -H tcp://192.168.99.101:2376 --tlsverify \
    --tlscacert /mnt/c/Users/flerro/.docker/machine/machines/default/ca.pem  \
    --tlscert /mnt/c/Users/flerro/.docker/machine/machines/default/cert.pem \
    --tlskey /mnt/c/Users/flerro/.docker/machine/machines/default/key.pem  run hello-world

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

To simplify docker client invocation, DOCKER_* variables may be sourced into shell environment at startup (e.g. in ~/.zshrc).

In case the environment is correctly set but the client still refuse to work, check docker command aliases.

$ env | grep DOCKER

DOCKER_TLS_VERIFY=1
DOCKER_HOST=tcp://192.168.99.101:2376
DOCKER_CERT_PATH=/c/Users/lei00021/.docker/machine/machines/docker-host
DOCKER_MACHINE_NAME=docker-host

$ docker run hello-world
docker: Cannot connect to the Docker daemon at tcp://localhost:2376. Is the docker daemon running?.
See 'docker run --help'.

$ alias | grep docker

alias docker=sudo docker     # <- problematic alias 
                             #    (if you need superuser, try `sudo -E docker`)

Setup a corporate proxy

Behind a corporate proxy, the docker engine will not be able to reach external network without proper configuration (error: Client Timeout).

$ docker run redis

Unable to find image 'redis:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
See 'docker run --help'.

Proxy related environment variables must be set in the machine config file:

// Config file:
// /mnt/c/Users/MY_USERNAME/.docker/machine/machines/default/config.json

"EngineOptions": {
    ...,
    "Env": [
        "HTTP_PROXY=http://user:pass@host:port",
        "HTTPS_PROXY=http://user:pass@host:port",
        "NO_PROXY=localhost,127.0.0.1"
    ],

Then the VM with docker engine must be reprovisioned:

C:\> docker-machine provision default
Waiting for SSH to be available...
Detecting the provisioner...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...

Now docker VM is able to download images, but it may not be able to .

Add custom SSL certificates

When a corporate proxy injects custom certificates in https requests for SSL inspection, the docker engine will refuse to download anything if SSL certificates in responses are not trusted (error: x509: certificate signed by unknown authority).

$ docker run openjdk:11
Unable to find image 'openjdk8:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: x509: certificate signed by unknown authority.
See 'docker run --help'.

Custom certificates must be uploaded into the /var/lib/boot2docker/certs dir of the running VM. Provided X.509 certificates must be in BASE64 encoded format, with .pem extension.

## 1. Copy custom SSL certificates to docker VM

C:\> docker-machine ssh default

docker@default:~$ mkdir -p /var/lib/boot2docker/certs
docker@default:~$ cp /c/Users/flerro/*.pem  /var/lib/boot2docker/certs
docker@default:~$ logout

## 2. Reconfigure docker engine VM

C:\> docker-machine restart default
Restarting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Waiting for SSH to be available...
Detecting the provisioner...
Restarted machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Now, hopefully, all impediments are removed and I can enjoy docker.

## Run docker client on WSL

$ docker run openjdk:11
Unable to find image 'openjdk:11' locally
11: Pulling from library/openjdk
ab1fc7e4bf91: Pull complete
35fba333ff52: Pull complete
f0cb1fa13079: Pull complete
3d1dd648b5ad: Extracting [==============================================>    ]  46.14MB/50.06MB
a9f886e483d6: Download complete
f0c295b9cf6e: Download complete
afe560095725: Download complete
dc8253cd29cd: Download complete
6885295983c8: Downloading [===>                                               ]   25.9MB/325.5MB

More info on custom certificates setup.