--- - name: Check for existing Traefik containers shell: docker ps -a --filter "name=traefik" --format "{{ '{{' }}.ID{{ '}}' }}" register: existing_traefik_containers changed_when: false failed_when: false - name: Stop and remove existing Traefik containers shell: docker stop {{ item }} && docker rm {{ item }} loop: "{{ existing_traefik_containers.stdout_lines }}" when: existing_traefik_containers.stdout_lines | length > 0 ignore_errors: yes - name: Check if ports 80 and 443 are in use shell: | if sudo ss -tlnp 'sport = :80' 2>/dev/null | grep -q LISTEN; then echo "port_80_in_use" fi if sudo ss -tlnp 'sport = :443' 2>/dev/null | grep -q LISTEN; then echo "port_443_in_use" fi register: port_check changed_when: false failed_when: false - name: Display port status debug: msg: - "Port 80 status: {{ 'IN USE' if 'port_80_in_use' in port_check.stdout else 'FREE' }}" - "Port 443 status: {{ 'IN USE' if 'port_443_in_use' in port_check.stdout else 'FREE' }}" - "Note: docker-proxy listening on ports is normal when Traefik container is running" - name: Warn if ports are blocked by non-docker processes debug: msg: "WARNING: Ports 80/443 appear to be in use. This may prevent Traefik from starting. Check with: sudo ss -tlnp 'sport = :80'" when: ('port_80_in_use' in port_check.stdout or 'port_443_in_use' in port_check.stdout) and existing_traefik_containers.stdout_lines | length == 0 - name: Check if acme.json exists stat: path: "{{ traefik_stack_path }}/acme.json" register: acme_json_stat - name: Remove acme.json if it's a directory (should be a file) shell: | if [ -d "{{ traefik_stack_path }}/acme.json" ]; then rm -rf "{{ traefik_stack_path }}/acme.json" fi become: yes when: acme_json_stat.stat.exists and acme_json_stat.stat.isdir - name: Ensure Traefik acme.json exists and has correct permissions file: path: "{{ traefik_stack_path }}/acme.json" state: touch mode: '0600' owner: "{{ ansible_user }}" group: "{{ ansible_user }}" become: yes when: not acme_json_stat.stat.exists or (acme_json_stat.stat.exists and acme_json_stat.stat.isdir) - name: Deploy Traefik stack community.docker.docker_compose_v2: project_src: "{{ traefik_stack_path }}" state: present pull: always register: traefik_compose_result - name: Check Traefik container status shell: | docker compose -f {{ traefik_stack_path }}/docker-compose.yml ps traefik | grep -Eiq "Up|running" register: traefik_state changed_when: false until: traefik_state.rc == 0 retries: "{{ ((traefik_wait_timeout | int) + (traefik_wait_interval | int) - 1) // (traefik_wait_interval | int) }}" delay: "{{ traefik_wait_interval | int }}" failed_when: traefik_state.rc != 0 when: not ansible_check_mode - name: Record Traefik deployment facts set_fact: traefik_stack_changed: "{{ traefik_compose_result.changed | default(false) }}" traefik_log_hint: ""