Ansible w/ Docker - Show current Container state
This worked for me:
- name: Get container status
shell: docker inspect --format={{ '{{.State.Running}}' }} {{ container_name }}
register: status
#Start the container if it is not running
- name: Start the container if it is in stopeed state.
shell: docker start heuristic_mestorf
when: status.stdout != "true"
Unfortunately, none of the modules around docker can currently "List containers". I did the following as work around to grab the status:
- name: get container status
shell: docker ps -a -f name={{ container }} --format {%raw%}"table {{.Status}}"{%endraw%} | awk 'FNR == 2 {print}' | awk '{print $1}'
register: status
Result will then be available in the status variable
As of Ansible 2.8 you can use the docker_container_info
, which essentially returns the input from docker inspect <container>
:
- name: Get infos on container
docker_container_info:
name: my_container
register: result
- name: Does container exist?
debug:
msg: "The container {{ 'exists' if result.exists else 'does not exist' }}"
- name: Print the status of the container
debug:
msg: "The container status is {{ result.container['State']['Status'] }}"
when: result.exists
With my Docker version, State
contains this:
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8235,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-01-25T14:10:08.3206714Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
See https://docs.ansible.com/ansible/2.8/modules/docker_container_info_module.html for more details.
Edit: If you are running Ansible 2.8+ you can use
docker_container_info
. See David Pärsson's answer for details.
Here is one way to craft it using the docker_container
module (note that it will create the container if it does not exist):
- name: "Check if container is running"
docker_container:
name: "{{ container_name }}"
state: present
register: container_test_started
ignore_errors: yes
- set_fact:
container_exists: "{{ container_test_started.ansible_facts is defined }}"
- set_fact:
container_is_running: "{{ container_test_started.ansible_facts is defined and container_test_started.ansible_facts.docker_container.State.Status == 'running' }}"
container_is_paused: "{{ container_test_started.ansible_facts is defined and container_test_started.ansible_facts.docker_container.State.Status == 'paused' }}"
For me the gotchya was that if the container doesn't exist, ansible_facts is not defined. If it does though, then that contains basically the whole docker inspect <container>
output so I navigate that for the status.
If you just need to short circuit, a simpler alternative would be to move the desired set_fact'd value into a failed_when on the docker_container task.
I do it through set_fact to keep my options open for forking behavior elsewhere.. e.g. stop, do task, then put back how it was.
I included pause because it is commonly forgotten as a state :)