docker_image and path

Hello,

I’m trying to use Docker with Ansible to build a Docker image, but am running into an issue. Any help would be appreciated.

Basically, I want to put my docker files in my role’s ‘files’ directory and not have to specify a path for the docker_image task. Or, if I do have to specify a path, I’d like it to be relative.

Ansible → v1.7.1
Python ->2.7.6
Docker-py → 0.5.0

Relevant bit of my Ansible files look like this, following the Best Practices section of the docs:

roles/jenkins-slave/tasks/main.yml
roles/jenkins-slave/files/Dockerfile

My task in that main.yml looks like this:

  • name: check or build jenkins-slave image
    docker_image: name=jenkins_java8 state=present

Note the lack of a path variable, which according to the docs is not a required field.

When I run ansible-playbook, which then runs that task, I get this:

TASK: [jenkins-slave | check or build jenkins-slave image] ********************
fatal: [bucket1.closely.com] => failed to parse: SUDO-SUCCESS-pmqhkrvacsxgejgtwrskjhunvzyegvbj
Traceback (most recent call last):
File “/home/closely/.ansible/tmp/ansible-tmp-1411528307.53-162772271271910/docker_image”, line 1598, in
main()
File “/home/closely/.ansible/tmp/ansible-tmp-1411528307.53-162772271271910/docker_image”, line 234, in main
image_id = manager.build()
File “/home/closely/.ansible/tmp/ansible-tmp-1411528307.53-162772271271910/docker_image”, line 139, in build
stream = self.client.build(self.path, tag=‘:’.join([self.name, self.tag]), nocache=self.nocache, rm=True, stream=True)
File “/usr/local/lib/python2.7/dist-packages/docker/client.py”, line 386, in build
raise TypeError(“Either path or fileobj needs to be provided.”)
TypeError: Either path or fileobj needs to be provided.

FATAL: all hosts have already failed – aborting

Specifying an absolute path for docker_image works, but that seems less than ideal. I haven’t found a relative path that works at all.

I’m admittedly a n00b to Ansible, so it’s very likely I’m missing something very basic here. Any kind of debugging help would be useful too - like how could I trap the actual issued command to see what it thinks the path is?

Thanks,
topher

Hi,

There’s been a bit of discussion about the docker-image module recently.

In particular, see Toshio’s post and my follow up here on the devel list:

https://groups.google.com/forum/#!topic/ansible-devel/ddlEteAgjIk

I’m currently feeling that docker-image got accepted too early, the normal “docker” module is great, but Dockerfiles belong to be called from a build system.

(A major reason for this is they also won’t block ansible runs, and don’t make sense in host loops so much either)

Thoughts to the contrary would be welcome, but I’d suggest following - http://www.ansible.com/blog/2014/02/12/installing-and-building-docker-with-ansible for a primer on how to use playbooks inside a docker file - and we have some suprises coming out about that hopefully this week that will simplify further.

Hope that helps!

–Michael

Hi Michael,

I can appreciate the approach you referenced above in the blog post, but there is an alternative that I think is worth some discussion before moving too far ahead with ansible/docker integration. The Ansible blog post is basically recommending a post-deployment container configuration using ansible (e.g. docker → ansible). The alternative (re: https://groups.google.com/forum/#!topic/ansible-project/H43hAKRtdhM) would be to use Ansible to generate a Dockerfile (and related content, as required). In other words: ansible → docker. This has a number of advantages:

  • Pre-existing Ansible scripts can be reused to build Docker containers.
  • Generated Dockerfiles facilitate how docker detects changes to your containers (thus better exploiting Docker’s caching mechanism for image trees).
  • Your built images are now largely pre-configured, which helps reason about the behavior of your Docker containers at runtime.
    We’re currently taking this approach in our shop, which started with Ansible deployments to EC2 instances. We’re transitioning to Docker containers and have found the above to be reliable and a better “best practice” for the reasons stated.

Thoughts?

"

  • Pre-existing Ansible scripts can be reused to build Docker containers.
    Using ansible playbooks from the dockerfile still allow this.
  • Generated Dockerfiles facilitate how docker detects changes to your containers (thus better exploiting Docker’s caching mechanism for image trees).

I think you’ll be happy with what we have coming.

Please hold on this one just a bit and we have some things to show later in the week :slight_smile:

  • Your built images are now largely pre-configured, which helps reason about the behavior of your Docker containers at runtime."

The above approach was still building them ahead of runtime.

Thanks for the reply. I am very excited to hear you have some updates coming this week!

Running Ansible inside the container minimally requires Python (and related py libs) and probably git (to pull down your Ansible repo). This could be included in a base Docker image though, so not a huge deal.

After thinking through the differences between these two approaches I think the only major issue is Docker layer caching (my 2nd bullet). If you have something coming that will help address this, then I would be inclined to follow the approach mentioned in the blog post. :slight_smile: