docker with ansible wait for database docker with ansible wait for database docker docker

docker with ansible wait for database


wait_for does not work for the MySQL docker container because it only checks that the port is connectable (which is true straight away for the Docker container). However, wait_for does not check that the service inside the container listens the port and sends responses to the client.

This is how I am waiting in the ansible playbook for the MySQL service becoming fully operational inside the Docker container:

- name: Start MySQL container  docker:    name: some-name    image: mysql:latest    state: started    ports:    - "8306:3306" # it's important to expose the port for waiting requests    env:        MYSQL_ROOT_PASSWORD: "{{ mysql_root_password }}"- template: mode="a+rx,o=rwx" src=telnet.sh.j2 dest=/home/ubuntu/telnet.sh# wait while MySQL is starting- action: shell /home/ubuntu/telnet.sh  register: result  until: result.stdout.find("mysql_native_password") != -1  retries: 10  delay: 3

And the telnet.sh.j2 is

#!/bin/bash -etelnet localhost 8306 || true


To avoid the sh and I don't normally have telnet installed...

- name: Wait for database to be available  shell: docker run --rm --link mysql:mysql mysql sh -c 'mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p{{mysql_password}} || true'  register: result  until: result.stderr.find("Can't connect to MySQL") == -1  retries: 10  delay: 3


As etrubenok said:

wait_for does not work for the MySQL docker container because it only checks that the port is connectable (which is true straight away for the Docker container). However, wait_for does not check that the service inside the container listens the port and sends responses to the client.

Using Andy Shinn's suggestion of FreshPow's answer, you can wait without needing a shell script or telnet:

- name: Wait for mariadb  command: >    docker exec {{ container|quote }}    mysqladmin ping -u{{ superuser|quote }} -p{{ superuser_password|quote }}  register: result  until: not result.rc  # or result.rc == 0 if you prefer  retries: 20  delay: 3

This runs mysqladmin ping ... until it succeeds (return code 0). Usually superuser is root. I tested using podman instead of docker but I believe the command is the same regardless. |quote does shell escaping, which according to the Ansible docs should also be done when using command: