docker-py: 'ImportError: No module named ssl_match_hostname' upon 'import docker' in a Python script

In a script ~/Documents/Scratch/test_import_docker.py with the single statement import docker, I’m getting the following ImportError:

Traceback (most recent call last):
  File "test_import_docker.py", line 1, in <module>
    import docker
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/__init__.py", line 6, in <module>
    from .client import Client, AutoVersionClient, from_env # flake8: noqa
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/client.py", line 11, in <module>
    from . import api
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/api/__init__.py", line 2, in <module>
    from .build import BuildApiMixin
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/api/build.py", line 9, in <module>
    from .. import utils
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/utils/__init__.py", line 2, in <module>
    from .utils import (
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/utils/utils.py", line 19, in <module>
    from .. import tls
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/tls.py", line 5, in <module>
    from .ssladapter import ssladapter
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/ssladapter/__init__.py", line 1, in <module>
    from .ssladapter import SSLAdapter # flake8: noqa
  File "/home/kurt/.local/lib/python2.7/site-packages/docker/ssladapter/ssladapter.py", line 21, in <module>
    from backports.ssl_match_hostname import match_hostname
ImportError: No module named ssl_match_hostname

Strangely, I am able to import docker from iPython:

Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import docker

In [2]: 

Why is the import not working in the first case?

My Docker version from the command line is:

kurt@kurt-ThinkPad:~$ docker --version
Docker version 1.12.3, build 6b644ec

whereas the version in Python is

In [3]: docker.version
Out[3]: '1.10.3'

Incidentally, I’ve also created a StackOverflow question about this.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 17
  • Comments: 41 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I just had this fun issue while setting up my Ubuntu 18.x machine. docker-compose was working for me, then this morning I tried to do some additional installation of some libraries, specifically using python3.6 and suddenly my docker-compose and docker wasn’t working.

I eventually figured out that the version of backports that python2 was trying to import was here: /usr/lib/python2.7/dist-packages/backports

Even though I had another version of it here: /usr/local/lib/python2.7/dist-packages/backports

So I ran: cp -r /usr/local/lib/python2.7/dist-packages/backports/ssl_match_hostname/ /usr/lib/python2.7/dist-packages/backports

And that fixed it and docker-compose works again.

I had the same problem on my ubuntu 17.04. I solved it by installing via apt get

sudo pip uninstall docker docker-compose
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install docker docker-compose

The following workaround worked for me (sudo pip install --upgrade docker didn’t):

sudo cp -r ~/.local/lib/python2.7/site-packages/backports/ssl_match_hostname/ /usr/lib/python2.7/dist-packages/backports

On Ubuntu 17.10, a workaround is to uninstall docker python module with pip and install python-docker with apt:

# pip uninstall docker
...
# apt install python-docker
...
# python2 -c 'import docker; print(docker.__version__)'
2.5.1

Another +1 to @DrewBloechl — on my Raspberry Pi 4 running Debian Buster, it seems the default install had python-configparser installed. Uninstalling it fixed docker-compose by allowing the ssl_match_hostname module to load in a path Python could see. My fix was:

$ sudo apt-get remove python-configparser

Edit: following up, I actually went with step 1 instead. I just make sure to apt-get install -y python-backports.ssl-match-hostname prior to Pip installation (Pip (python-pip package) seems to be what causes the python-configparser package to be installed, at least in my case).

in my case i solved it with apt install python-backports.ssl-match-hostname

I just ran into this after installing docker-compose, and at least on the host I was looking at (a new Debian buster installation), the cause came down to an OS package (python-configparser) shipping files under /usr/lib/python2.7/dist-packages/backports. Because of the ordering of Python’s sys.path (and I suppose the semantics of submodules), this prevents Python from looking in /usr/local/lib/python2.7/dist-packages/backports (note local in this path), where pip installed the files for backports.ssl-match-hostname.

To anyone else hitting this bug, check whether the path you see via introspection on the backports module matches the path pip installed files under:

# pip show -f backports.ssl-match-hostname
Name: backports.ssl-match-hostname
[...]
Location: /usr/local/lib/python2.7/dist-packages
Requires:
Required-by: docker, docker-compose
Files:
  backports.ssl_match_hostname-3.7.0.1.dist-info/INSTALLER
  backports.ssl_match_hostname-3.7.0.1.dist-info/LICENSE.txt
  backports.ssl_match_hostname-3.7.0.1.dist-info/METADATA
  backports.ssl_match_hostname-3.7.0.1.dist-info/RECORD
  backports.ssl_match_hostname-3.7.0.1.dist-info/WHEEL
  backports.ssl_match_hostname-3.7.0.1.dist-info/top_level.txt
  backports/__init__.py
  backports/__init__.pyc
  backports/ssl_match_hostname/__init__.py
  backports/ssl_match_hostname/__init__.pyc

# python -c 'import backports ; print(backports.__path__)'
['/usr/lib/python2.7/dist-packages/backports']

The above shows the backports module that Python found on import is not the same as the one the ssl_match_hostname submodule is nested under.

I found two possible fixes for my host’s environment, though I’d expect the fix is going to vary depending on the specific thing that is confusing the search path.

  1. Uninstall pip’s backports.ssl-match-hostname, and install Debian’s python-backports.ssl-match-hostname package (this is the approach I went with)
  2. Remove Debian’s python-configparser package (which will probably have the effect of removing some other packages that depend on it)

I’ve got the same problem and ran sudo pip install --upgrade docker and it worked 😃

Ran into the very same problem with a freshly installed Ubuntu 18.10

Edit: what worked for us is to use python3 and ensure the latest version of python module docker is installed (4.0.1 as of today)

sudo apt-get install python3
pip3 --upgrade docker

# pip3 list | grep docker
docker (4.0.1)
docker-compose (1.24.0)
docker-pycreds (0.4.0)
dockerpty (0.4.1)


# Eventually use this variable with Ansible if you're going to use python module docker with a playbook :
ansible_python_interpreter: /usr/bin/python3

you have to like reinstall your box for all the problem to go away

$ sudo pip uninstall backports.ssl_match_hostname and then install the docker-py with

$ sudo pip install docker-py

I fixed the issue by removing all my ~/.local/lib/python{2,3}, but maybe it could be fixed by running touch ~/.local/lib/python2/dist-packages/backports/__init___.py.

Let me explain the root cause of the issue. python looks for ‘backports’ directory, when it is found, python looks for ‘ssl_match_hostname’ subdirectory. If it is not found, it is an error. In other words if one has ‘/usr/lib…/backports’ and no ‘/usr/lib…/backports/ssl_match_hostname’ (any backport installed by apt), it is pointless to use pip to install anything in /usr/local/lib or in /home.

If we have a collision between distro and pip:

  1. dpkg-query -S /usr/lib/python2.7/dist-packages/backports
  2. apt remove all_found_packages
  3. pip install whatever_you_need

If we have a collision between global and local pip do similar things.

It is handy to use strace to solve such issues.

We are running into the same issue: https://plexguide.com/threads/cant-install-any-containers.1062/#post-5984

3 people reporting it via ansible and there is no good solution

On Ubuntu 17.10, outside a virtualenv, it is possible to import docker pip module with downgraded requests pip module (thanks to this thread):

# pip freeze | grep requests
requests==2.18.1
# pip freeze | grep docker
docker==2.7.0
docker-compose==1.19.0
docker-pycreds==0.2.2
dockerpty==0.4.1
# python2 -c 'import docker; print(docker.__version__)'
2.7.0

On Ubuntu 17.10, a much better workaround is to use a virtualenv.

# virtualenv awx-build-virtualenv
Running virtualenv with interpreter /usr/bin/python2
New python executable in awx-build-virtualenv/bin/python2
Also creating executable in awx-build-virtualenv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
# source awx-build-virtualenv/bin/activate
(awx-build-virtualenv) # pip install docker
Collecting docker
  Using cached docker-3.1.1-py2.py3-none-any.whl
Collecting backports.ssl-match-hostname>=3.5; python_version < "3.5" (from docker)
...
(awx-build-virtualenv) # python2 -c 'import docker; print(docker.__version__)'
3.1.1

@rafabc solution worked for me!

On Ubuntu 17.10, a workaround is to uninstall docker python module with pip and install python-docker with apt:

# pip uninstall docker
...
# apt install python-docker
...
# python2 -c 'import docker; print(docker.__version__)'
2.5.1

Worked for me on Ubuntu 18.04. The exact commands: sudo pip uninstall docker sudo apt-get install python-docker

@geerlingguy I had the same issue on a VPS running Debian Buster (amd64), which was previously working fine when using Stretch.

I just make sure to apt-get install -y python-backports.ssl-match-hostname prior to Pip installation (Pip (python-pip package) seems to be what causes the python-configparser package to be installed, at least in my case).

Installing in this order also fixed it for me!

@nischay30 something is clearly not right about your recommandation because docker-py is the old/outdated name of the pip package. We are supposed to use just simple docker.

*docker-py had last release back in 2016, is not maintained *.

After doing more testing I was able to find a way to avoid this problem by patching requirments with:

backports.ssl-match-hostname>=3.7.1; python_version=='2.7'  # PSF
# ^ workaround for https://github.com/docker/docker-py/issues/1502

If you miss to add this line, you may endup with a broken docker container on those systems that happen to have an older versions of backports.ssl-match-hostname.

Note: I am not sure which is the first version that avoids this bug but the latest one that I used worked.

Run bash command is a good solution : mv ~/.local ~/.local.bak

I had the same problem running docker-compose commands (ImportError: No module named ssl_match_hostname). After reinstall docker and docker-compose with apt the docker-compose commands are working, but I still can’t import docker with python -c 'import docker'

Hi @fjhaveri. Have you tried pip install --upgrade docker? How is your pip list?