--- - name: Backup Docker containers and volumes to storage hosts: docker become: true vars: backup_dest: "192.168.2.115:/mnt/storage/Docker_backups" compose_dir: "/home/harry" volumes_dir: "/var/lib/docker/volumes" tasks: - name: Ensure backup destination directories exist ansible.builtin.command: cmd: ssh -o StrictHostKeyChecking=no root@192.168.2.115 "mkdir -p /mnt/storage/Docker_backups/compose /mnt/storage/Docker_backups/volumes" changed_when: false - name: Rsync compose files and configs (safe while running) ansible.builtin.shell: | rsync -az --delete \ --include='*/' \ --include='docker-compose.yml' \ --include='compose.yml' \ --include='.env' \ --include='*.conf' \ --include='*.yml' \ --include='*.yaml' \ --include='*.json' \ --exclude='node_modules/' \ --exclude='.git/' \ --exclude='__pycache__/' \ {{ compose_dir }}/ root@{{ backup_dest }}/compose/ register: compose_sync - name: Get list of running containers ansible.builtin.command: docker ps -q register: running_containers changed_when: false - name: Stop all containers ansible.builtin.command: docker stop $(docker ps -q) when: running_containers.stdout | length > 0 - name: Rsync Docker volumes to storage ansible.builtin.shell: | rsync -az --delete \ {{ volumes_dir }}/ root@{{ backup_dest }}/volumes/ register: volume_sync - name: Start all containers back up ansible.builtin.command: docker start $(docker ps -aq) - name: Verify containers are running ansible.builtin.command: docker ps --format "{{ '{{' }}.Names{{ '}}' }} - {{ '{{' }}.Status{{ '}}' }}" register: container_status changed_when: false - name: Backup summary ansible.builtin.debug: msg: - "Compose sync: {{ 'OK' if compose_sync.rc == 0 else 'FAILED' }}" - "Volume sync: {{ 'OK' if volume_sync.rc == 0 else 'FAILED' }}" - "Containers running: {{ container_status.stdout_lines | length }}"