Docker & Ansible on RHEL / CentOS 7

We use Ansible to deploy Docker containers on our systems and the infrastructures of our customers. This works pretty well if your system is configured properly.

Here’s a simple playbook to run the hello-world Docker container on one of your systems:

Dependency to docker-py

Ansible is written in Python, so is the docker module. Therefor it makes use of the docker-py Python library to manage containers.

To use Ansible’s docker module, you’ve to make sure the docker-py library is installed. We do that by creating a new Ansible role named  docker and then add the installation of the required packages ( docker, docker-py) as a task. Now every role which uses Ansible’s  docker module adds our docker role as dependency, therefor the docker and docker-py packages are installed automatically.

This is where the problem starts on RHEL or CentOS 7, because docker-py is available via PyPi, therefor pip and finally via yum / RHN channels as well.


When you install the docker-py module via yum, you’ll end up with something like this:

As you can see the version 1.4.0 is installed. This can also be verified via pip and python’s help() or pydoc:

This looks quite ok, but there’s something really strange, because there is no official 1.4.0(-dev) version on PyPi or even github.
There’s a 1.4.0-dev version available on PyPi, but it’s an inofficial version from a user called sunadm.

But let’s ignore that for now, because here’s the real issue with the official docker-py RPM from Red Hat:
If you run the Ansible playbook above with the RPM docker-py-1.4.0-108.el7 installed, you’ll get a Python error / traceback:

The PyPi package

Now you might just want to remove the RPM and install docker-py via PyPi / pip .
That’s a good idea, let’s see how that works out:

Run Ansible again and you’ll catch another traceback:

While the traceback was raised by Ansible, the root cause is within the docker.client module.
Though Ansible isn’t handling exceptions properly there – especially if docker-py isn’t installed at all 😉

Let’s dig into the problem by having a look at Ansible’s docker module.
Around line 428 you’ll see the import statements for the Python docker modules / classes:

Later in that file around line 1638 you’ll see a dict which makes use of the DEFAULT_DOCKER_API_VERSION variable:

And exactly this line will raise our exception above, because DEFAULT_DOCKER_API_VERSION isn’t defined.
This happens because there was an ImportError while importing the docker.client class.

You can reproduce that by executing:

Python six dependency

The root cause is within the dependencies of the docker-py module / docker.client class.
Docker-py requires six, which is another Python library. By default RHEL / CentOS 7 provide six via RPM:

When you’ve a look at PyPi, you’ll see that the version 1.3.0 is relatively old (2013-03-18).
Though RedHat isn’t currently providing any newer version of the package and unfortunately it’s required for other RPMs as well:

The Workaround

But here’s the workaround to get Ansible with Docker up & running is the following procedure:

  • remove the OS python-docker package
  • install the official PyPi docker-py package version 1.2.3 via pip
  • upgrade the six package to version >= 1.4.0 via pip without removing the OS package

So let’s update our playbook to meet the new requirements:

Though there are some drawbacks. OS packages with dependencies to six (e.g. sos abrtmight not be tested against a newer version of it.

To look on the bright side, there’s already an official docker-py commit which requires six>=1.4.0. So in the end it’s just a matter of time until Red Hat will fix this. Hopefully we don’t have to wait another 2 years 😉


  • thomas Reply

    also make sure pip is installed (only with Python 2.7.9 and later)

    – name: make sure pip is installed
    name: pip

    • Dominique Barton Reply

      Yep you’re right. Use easy_install like in your example above or yum to install pip:

      - name: make sure pip is installed
      name: python-pip
      state: present

  • Daryn Hanright Reply


    Just wondering what version of ansible you were using for this guide? Have followed it with ansible 1.8.2 & I still get the “NameError: global name ‘DEFAULT_DOCKER_API_VERSION’ is not defined”

  • Dominique Barton Reply


    Hmm strange.

    I think it was version 1.9.2 or 1.9.3. However, we no longer use Ansible’s docker module because it was a bit of a hazzle, as you might already experienced 😉 Instead of it we’re using the template module to create a Docker Compose file and then run docker-compose up -d or whatever 🙂

    This works much better and out of the box (at least if you make sure Docker Compose is installed in advance).


Leave a Reply

Your email address will not be published. Required fields are marked *