Ansible for Docker Containers | Just YAML Things
Ansible for Docker Containers | Just YAML Things
Background
Why Even Run Docker Containers with Ansible?
Well, I’m running my stuff in a Swarm. The problem is that Swarm does not (yet) allow you to configure Linux Kernel Capabilities on a container. But you can configure them with docker-compose
or docker run
. Lame.
Fortunately, I’m using Ansible to deploy some things on this server, so I have things in place already to use it to run a container.
Error Messages
I’m using Traefik as my Reverse Proxy. Traefik works best for dynamic service discovery through the use of Container Labels , or Service Labels. The distinction is very important, depending upon how you’re scheduling your containers.
What’s weird though, is with the labels shown below for my Ansible play… I would get cryptic errors about type conversion. YAML tries to implicitly detect the type of the value (See Ansible Docs on YAML for more detail).
labels:
traefik.port: 9980
Will yield this error:
msg: 'Error creating container: 500 Server Error: Internal Server Error ("json: cannot unmarshal number into Go value of type string")'
labels:
traefik.enable: true
Will yield this error
msg: 'Error creating container: 500 Server Error: Internal Server Error ("json: cannot unmarshal bool into Go struct field ContainerConfigWrapper.Labels of type string")'
To avoid YAML interpreting the type for the value of a dictionary, enclose the value in quotes:
labels:
traefik.enable: "true"
traefik.port: "9980"
Ansible Troubleshooting Tip
One pain about Ansible is the inconsistency with configuration files. It’s just all over the place with presenting data structures..
- Ansible’s config file,
ansible.cfg
, by default is in anini
format. Same forhosts
, except that can be in YAML too. stdout
from Ansible is not composed in a very structured way, by default.
But you can have it output things in a more consistent way (since plays are written in YAML ). Export this environment variable to make verbose output print as YAML :
ANSIBLE_STDOUT_CALLBACK=yaml
And here’s example output of an error when using -vvv
flags, but much more readable than default:
The full traceback is:
File "/tmp/ansible_xhulz3r_/ansible_module_docker_container.py", line 1966, in container_create
new_container = self.client.create_container(image, **create_parameters)
File "/usr/lib/python3/dist-packages/docker/api/container.py", line 449, in create_container
return self.create_container_from_config(config, name)
File "/usr/lib/python3/dist-packages/docker/api/container.py", line 460, in create_container_from_config
return self._result(res, True)
File "/usr/lib/python3/dist-packages/docker/api/client.py", line 226, in _result
self._raise_for_status(response)
File "/usr/lib/python3/dist-packages/docker/api/client.py", line 222, in _raise_for_status
raise create_api_error_from_http_exception(e)
File "/usr/lib/python3/dist-packages/docker/errors.py", line 31, in create_api_error_from_http_exception
raise cls(e, response=response, explanation=explanation)
fatal: [104.248.184.48]: FAILED! => changed=false
invocation:
module_args:
api_version: null
auto_remove: false
blkio_weight: null
cacert_path: null
capabilities:
- MKNOD