-.- --. .-. --..

The state in Ansible's docker container module

I spent roughly an hour on a stupid misunderstanding I had with the documentation for the docker_container today. The module has a state option that turns a few knobs. The two options I got confused between are present and started. In hindsight, why I used present when I meant “I want to start the container” is an obvious problem. But I did, and spent time trying to debug what the heck Ansible’s module was doing differently than docker run. The playbook I was writing had a bunch of local_actions to build an nginx-based image, spawn a container off of it, and trigger a few tests against it. Obviously, for the tests to succeed, the container had to be up, but since I was using state: present, it looked as if the container booted up but got shut down immediately. The docker inspect output in this case won’t have any hint as to why the container is not actually running. Turns out that state: present doesn’t actually run the container, just creates it.

So, here’s a small reminder for the future-me that if the container has to be in running state, the state should be set to started. present only ensures the container is there in the process list, and not in running state. i.e., ignoring all the other interactions that this parameter has with other options, state: present is effectively docker create, whereas state: started is analogous docker run.

Aside: Why use ansible to run docker?

This whole setup might seem convoluted, but there’s a reason why I chose this. Before I had an M1-based Macbook, I was using Vagrant for local testing of the ansible pipeline. Everytime I make code changes for the server configuration, I’ll run the entire Ansible playbook end to end to setup the local VM provisioned by Vagrant, followed by basic curl-based tests that check for status codes and cache headers against the server. Vagrant uses VirtualBox for running the virtual machines, which is not supported on M1 chips. The process of converting this exact setup to instead use Docker is not that straight forward in my experience so far. Running docker build and docker run directly won’t work in all cases since I use Ansible template that interpolates variables into the nginx configuration files, which have to be compiled before I actually build the docker image. So the short-term alternative I was trying out was to use another playbook that runs every Ansible task in it locally, which includes letting Ansible take care of building, running the server container and the tests.