6

Context

I am trying to use docker-py to connect to docker-machine on OSX.

I can't simply use the standard Client(base_url='unix://var/run/docker.sock') since docker is running on a docker-machine Virtual Machine, not my local OS.

Instead, I am trying to connect securely to the VM using docker.tls:

from docker import Client
import docker.tls as tls
from os import path

CERTS = path.join(path.expanduser('~'), '.docker', 'machine', 'certs')

tls_config = tls.TLSConfig(
    client_cert=(path.join(CERTS, 'cert.pem'), path.join(CERTS,'key.pem')),
    ca_cert=path.join(CERTS, 'ca.pem'),
    verify=True
#verify=False
)
client = docker.Client(base_url='https://192.168.99.100:2376', tls=tls_config)

Problem

When I try to run this code (running something like print client.containers() on the next line), I get this error:

requests.exceptions.SSLError: hostname '192.168.99.100' doesn't match 'localhost'

I've been trying to follow the github issue on a similar problem with boot2docker, ie. the old version of docker-machine, but I don't know much about how SSL certificates are implemented. I tried adding 192.168.99.100 localhost to the end of my /etc/hosts file as suggested in the github issue, but that did not fix the issue (even after export DOCKER_HOST=tcp://localhost:2376).

Maybe connecting via the certificates is not the way to go for docker-machine, so any answers with alternative methods of connecting to a particular docker-machine via docker-py are acceptable too.

UPDATE Seems like v0.5.2 of docker-machine tries to solve this via the --tls-san flag for the create command. Need to verify but installation via brew is still giving v0.5.1, so I'll have to install manually.

Pedro Cattori
  • 2,735
  • 1
  • 25
  • 43

2 Answers2

6

Looks like with the Docker-py v1.8.0 you can connect to Docker-machine like below;

import docker
client = docker.from_env(assert_hostname=False)
print client.version()

See the doc here

cdagli
  • 1,578
  • 16
  • 23
  • 1
    thanks @cdagli but I wanted to remove dependency on environment variables and have all the configuration done by python code – Pedro Cattori Mar 27 '16 at 15:39
4

I installed docker-machine v0.5.2 as detailed in the release on github. Then I just had to create a new machine as follows:

$ docker-machine create -d virtualbox --tls-san <hostname> <machine-name>

Then I added <hostname> <machine-ip> to /etc/hosts. The code worked after that

from docker import Client
import docker.tls as tls
from os import path

CERTS = path.join(path.expanduser('~'), '.docker', 'machine', 'machines', <machine-name>)

tls_config = tls.TLSConfig(
    client_cert=(path.join(CERTS, 'cert.pem'), path.join(CERTS,'key.pem')),
    ca_cert=path.join(CERTS, 'ca.pem'),
    verify=True
)
client = docker.Client(base_url='https://<machine-ip>:2376', tls=tls_config)

where I replaced <machine-name> in the CERTS path and replaced <machine-ip> in the base_url.

Pedro Cattori
  • 2,735
  • 1
  • 25
  • 43
  • I'm trying this solution, but I keep running into the following issue: requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://192.168.99.100:2376/v1.21/containers/create In /etc/hosts I've tried both: dockerhost 192.168.99.100 and: 192.168.99.100 dockerhost – Berco Beute Mar 09 '16 at 14:40
  • @BercoBeute run `docker-machine ip` and use that IP. – enderland Mar 15 '16 at 21:20