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: