--- # Docker Stack Deployment Role # Deploys docker-compose stacks to hosts # # Required variables: # stack_name: Name of the stack/directory # stack_compose_file: Path to the compose file (relative to repo root) # # Optional variables: # stack_env_file: Path to .env file (relative to repo root) # stack_config_files: List of additional config files to copy # stack_deploy: Whether to deploy the stack (default: true) # stack_pull_images: Whether to pull images first (default: true) - name: Ensure stack directory exists ansible.builtin.file: path: "{{ docker_data_path }}/{{ stack_name }}" state: directory mode: '0755' become: "{{ ansible_become | default(false) }}" - name: Ensure stack subdirectories exist ansible.builtin.file: path: "{{ docker_data_path }}/{{ stack_name }}/{{ item }}" state: directory mode: '0755' loop: "{{ stack_subdirs | default(['config', 'data']) }}" become: "{{ ansible_become | default(false) }}" - name: Copy docker-compose file from repo ansible.builtin.copy: src: "{{ playbook_dir }}/../../{{ stack_compose_file }}" dest: "{{ docker_data_path }}/{{ stack_name }}/docker-compose.yml" mode: '0644' backup: true register: compose_file_result when: stack_compose_file is defined become: "{{ ansible_become | default(false) }}" - name: Copy docker-compose content directly ansible.builtin.copy: content: "{{ stack_compose_content }}" dest: "{{ docker_data_path }}/{{ stack_name }}/docker-compose.yml" mode: '0644' backup: true register: compose_content_result when: - stack_compose_content is defined - stack_compose_file is not defined become: "{{ ansible_become | default(false) }}" - name: Copy environment file from repo ansible.builtin.copy: src: "{{ playbook_dir }}/../../{{ stack_env_file }}" dest: "{{ docker_data_path }}/{{ stack_name }}/.env" mode: '0600' backup: true when: stack_env_file is defined become: "{{ ansible_become | default(false) }}" - name: Copy environment content directly ansible.builtin.copy: content: "{{ stack_env_content }}" dest: "{{ docker_data_path }}/{{ stack_name }}/.env" mode: '0600' when: - stack_env_content is defined - stack_env_file is not defined become: "{{ ansible_become | default(false) }}" - name: Copy additional config files ansible.builtin.copy: src: "{{ playbook_dir }}/../../{{ item.src }}" dest: "{{ docker_data_path }}/{{ stack_name }}/{{ item.dest }}" mode: "{{ item.mode | default('0644') }}" backup: true loop: "{{ stack_config_files | default([]) }}" when: stack_config_files is defined become: "{{ ansible_become | default(false) }}" - name: Pull Docker images ansible.builtin.command: cmd: docker compose pull chdir: "{{ docker_data_path }}/{{ stack_name }}" register: pull_result when: stack_pull_images | default(true) changed_when: "'Downloaded' in pull_result.stdout" failed_when: false become: "{{ ansible_become | default(false) }}" - name: Deploy stack with docker compose ansible.builtin.command: cmd: docker compose up -d --remove-orphans chdir: "{{ docker_data_path }}/{{ stack_name }}" register: deploy_result when: stack_deploy | default(true) changed_when: - "'Started' in deploy_result.stdout or 'Created' in deploy_result.stdout" - compose_file_result.changed | default(false) or compose_content_result.changed | default(false) become: "{{ ansible_become | default(false) }}" - name: Wait for stack to be healthy ansible.builtin.pause: seconds: "{{ stack_health_wait | default(5) }}" when: - stack_deploy | default(true) - stack_health_wait | default(5) > 0