Help with Docker module

Hello,

I am trying to implement docker in my workplace and plan on using Ansible to orchestrate my containers on my hosts. I have a few questions:

Is it possible to get the documentation the docker module page fleshed out a bit more? it’s a very capable module but a lot of the parameters have no examples and when combined with Docker can create some real confusion, such as…

Volumes. I would like to figure out what this volume module is actually capable of and I haven’t found any clear information. Is this for mounting volumes from the container onto the host? Vice versa? Bi-directional? I can’t seem to make any of them work, I just end up with empty directories that aren’t symlinks.
Syntax (tried both directions):

volumes:

  • /foo/conf/ejabberd/lars:/lars

When I destroy a container that has storage volumes assigned to it, does Ansible automatically try to destroy the storage volumes? If the answer is “yes” then that’s scary, because those volumes are supposed to persist. If the answer is “no” then that’s scary too because we’ll end up with lots of storage volumes on the host. I didn’t see an option to delete the storage volume in ansible.

What exactly do the state parameter options even mean?
What is are the exact definitions of stopped, absent and killed? Absent and killed sound identical (end result is that it’s not there), so which do I use?

How do I just ensure that a container is present but stopped? Would I refer to it by it’s given name or by the image name or…? Example:
If I deploy a container from an image (foo.com:5000/nginx:1.1) and give it the name “bob”, would I be able to later say “Ok I want Bob to be stopped now”? I have tried that with stopped and absent and neither worked, the only parameter option that had any effect was “killed”.

Thanks and forgive my ignorance, I’ve spent days googling and asking IRC. Neither have turned up much in the way of knowledge or examples.

Hey Lars,

As it happens I’m putting the finishing touches today on a pull request to revamp some of the Docker module’s functionality, specifically by adding more states and more clearly defining the ones that are there. I’m doing a bit with the documentation along the way (and I still have to touch up the examples, actually) but I doubt I’ll be able to get them that much more clear by the time 1.9 goes to prerelease. If you want to read some of the discussion, it’s here:

https://github.com/ansible/ansible-modules-core/pull/502

I believe most of your other questions are actually Docker questions more than Ansible ones! You might have better luck looking for explanations in the Docker documentation.

  • Volumes are indeed for mounting directories from the container to the host and vice-versa, read-only or read-write. The order is “host path:container path” (and an optional “:ro” or “:rw” at the end for read-only or read-write; read-write is the default).

https://docs.docker.com/userguide/dockervolumes/

If it’s not working for you: are you using boot2docker by any chance? If so, volume mounts will only work for host paths under /User on a Mac or C:\Users on Windows.

Docker will destroy volumes when you remove the final container that mounts them if and only if you provide the -v flag to the rm command. There isn’t currently a way to do this with the Ansible module.

  • What exactly do the state parameter options even mean? What is are the exact definitions of stopped, absent and killed? Absent and killed sound identical (end result is that it’s not there), so which do I use?

This is the big thing I’m working to clarify :slight_smile: “running” and “present” were (almost) functionally the same if you traced the code through the module, for example. I’m replacing “running” with “started”, made “present” mean “created but not running” (useful for data containers) and introduced “restarted” and “reloaded” to mean “always restart this container” and “restart this container if it’s configuration is different,” respectively. Hopefully the new help text will make this a little easier to follow!

“killed” and “stopped” stop the process but leave the container existing in a stopped state, while “absent” removes the container entirely – it’s the difference between docker kill and docker rm.

  • How do I just ensure that a container is present but stopped? Would I refer to it by it’s given name or by the image name or…?

Right now, you can’t; hopefully, that will be what “state=present” will do. Usually I work around this by using “state=present” and something like “command=echo”.

Containers are identified by name, or by a combination of image and command. (Command matching is bit iffy, though, the Docker daemon does some reformatting of the command string sometimes, I think.) Name is the least ambiguous for individual containers; image and command are useful for managing sets of containers with “count”.

  • If I deploy a container from an image (foo.com:5000/nginx:1.1) and give it the name “bob”, would I be able to later say “Ok I want Bob to be stopped now”? I have tried that with stopped and absent and neither worked, the only parameter option that had any effect was “killed”.

The difference between “stopped” and “killed” (or “docker stop” and “docker kill”) is the difference between SIGTERM and SIGKILL. If a process gets hung up for whatever reason, sometimes asking it nicely isn’t enough :slight_smile:

Hopefully that’s helpful!

  • Ash

That was very helpful, thank you Ash! I do understand the way that the docker volumes work, but was hoping that the ansible module would be able to add some extra functionality like the volume parameter being able to mount a directory from the docker host into the docker container post-container-creation.
Currently you cant (by design) build a docker host volume mount into the dockerfile which means if you want to mount from the container host into the container you have to do it after the container is spun up, and that’s what I’d really love to accomplish with Ansible.

Thanks again for the great reply!

Additionally I just want to mention that it appears that if you modify a playbook with a container from not having volumes mounted to mounting volumes, ansible doesnt register that as a “change” and thus won’t actually implement the changes to the task.

So if I have a playbook that just spins up a container and then I decide I want to add a volume mount to it, as far as I can tell, if I modify the playbook and rerun it, it will just get to the container piece and then will not recognize any change status. I think I have to tear down the container and rebuild it from scratch to get it to mount the container.

Is there a way we can manage the status of the volumes more intelligently?

That’s the second half of the missing functionality I wanted to add that prompted the refactor I linked before. (The first half was the ability to pull the latest version of the image on every run, not only when it’s missing, with “pull=always”.) If my PR is accepted, that will be “state=reloaded”, and it’ll work for changes not just in volume mounting but image versions, port bindings, environment variables, and just about everything else you configure on container creation or start.

I tested what I considered the more common options - there are likely bugs lurking in the options I didn’t try as in-depth. The Docker API doesn’t always round-trip container settings consistently, I’ve found.

  • Ash