Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run ad hoc docker compose commands in Ansible?

I have to run several docker-compose run commands for my Phoenix web app project. From the terminal I have to run this:

$ sudo docker-compose run web mix do deps.get, compile

$ sudo docker-compose run web mix ecto.create

$ sudo docker-compose run web mix ecto.migrate

While this works fine, I would like to automate it using Ansible. I'm well aware there is the docker_service Ansible module that consumes the docker-compose API and I'm also aware of the definition option that makes it easy to covert integrate the configuration inside docker-compose.yml into my playbook. What I don't know is how do I ensure that the commands above will be run before starting the containers. Can anyone help me with this issue?

like image 618
Razvan El Avatar asked Oct 29 '22 11:10

Razvan El


1 Answers

I faced a similar situation like yours, finding no way to run docker-compose run commands via docker dedicated modules for Ansible. However I ended using Ansible's shell module with success for my purposes. Here we have some examples, adapted for your situation.

One by one, explicit way

- name: Run mix deps.get and compile
  shell: docker-compose run web mix do deps.get, compile
  args:
    chdir: /path/to/directory/having/your/docker-compose.yml
  become: True # because you're using sudo

- name: Run mix ecto.create
  shell: docker-compose run web mix ecto.create
  args:
    chdir: /path/to/directory/having/your/docker-compose.yml
  become: True

- name: Run mix ecto.migrate
  shell: docker-compose run web mix ecto.migrate
  args:
    chdir: /path/to/directory/having/your/docker-compose.yml
  become: True

Equivalent way, but shorter

- name: Run mix commands
  shell: docker-compose run web mix "{{ item }}"
  args:
    chdir: /path/to/directory/having/your/docker-compose.yml
  loop:
    - "do deps.get, compile"
    - "ecto.create"
    - "ecto.migrate"
  become: True

To run those commands before starting the other containers defined in the docker-compose.yml file, maybe a combination of these points can help:

  • Use docker volumes to persist the results of getting dependencies, compilation and Ecto commands
  • Use the depends_on configuration option inside the docker-compose.yml file
  • Use the service parameter of Ansible's docker_service module in your playbook to run only a subset of containers
  • Use disposable containers with your docker-compose run commands, via the --rm option and possibly with the --no-deps option
  • In your playbook, execute your docker-compose run commands before the docker_service task

Some notes:

  • I'm using Ansible 2.5 at the moment of writing this answer.
  • I'm assuming that docker-compose binary is already installed, it's working fine and it's available on the standard system PATH on the managed host.
  • The docker-compose.yml file already exists and has the path /path/to/directory/having/your/docker-compose.yml, as used in the examples. A variable for that file path could also be used.

That's it!

like image 108
rodolfojcj Avatar answered Nov 14 '22 16:11

rodolfojcj