--- - name: Install Docker runtime packages ansible.builtin.apt: name: "{{ lxc_docker_host_all_packages }}" state: present update_cache: "{{ lxc_docker_host_update_cache }}" vars: lxc_docker_host_all_packages: >- {{ (lxc_docker_host_packages + lxc_docker_host_extra_packages + (['docker-compose'] if lxc_docker_host_install_compose_package else []) + (['prometheus-node-exporter'] if lxc_docker_host_install_node_exporter else []) + (['ufw'] if (lxc_docker_host_manage_ufw and lxc_docker_host_install_ufw) else [])) | unique | sort }} - name: Check the FUSE device ansible.builtin.stat: path: "{{ lxc_docker_host_fuse_device }}" register: lxc_docker_host_fuse when: lxc_docker_host_require_fuse - name: Require the FUSE device ansible.builtin.assert: that: - lxc_docker_host_fuse.stat.exists - lxc_docker_host_fuse.stat.ischr fail_msg: >- {{ lxc_docker_host_fuse_device }} отсутствует или не является символьным устройством. Добавьте в /etc/pve/lxc/.conf на узле PVE: "lxc.cgroup2.devices.allow: c 10:229 rwm" и "lxc.mount.entry: /dev/fuse dev/fuse none bind,create=file", затем перезапустите контейнер. when: lxc_docker_host_require_fuse - name: Ensure the Docker config directory exists ansible.builtin.file: path: "{{ lxc_docker_host_daemon_config_path | dirname }}" state: directory owner: root group: root mode: "0755" - name: Configure the Docker storage driver for the unprivileged LXC ansible.builtin.copy: dest: "{{ lxc_docker_host_daemon_config_path }}" owner: root group: root mode: "0644" content: "{{ lxc_docker_host_daemon_config | to_nice_json(indent=2) }}\n" register: lxc_docker_host_daemon_config_result - name: Ensure the Docker service is enabled and running ansible.builtin.systemd: name: docker enabled: true state: "{{ 'restarted' if lxc_docker_host_daemon_config_result.changed else 'started' }}" # --- UFW ------------------------------------------------------------------- # Порядок важен: сначала разрешающие правила, только потом включение политики # deny incoming — иначе SSH обрывается прямо во время прогона. - name: Allow SSH from the trusted networks community.general.ufw: rule: allow port: "{{ lxc_docker_host_ssh_port | string }}" proto: tcp src: "{{ item }}" loop: "{{ lxc_docker_host_ssh_sources }}" when: lxc_docker_host_manage_ufw - name: Allow the declared service ports community.general.ufw: rule: allow port: "{{ item.0.port | string }}" proto: "{{ item.0.proto | default('tcp') }}" src: "{{ item.1 }}" comment: "{{ item.0.comment | default(omit) }}" loop: "{{ lxc_docker_host_ufw_service_rules | subelements('sources') }}" loop_control: label: "{{ item.0.port }}/{{ item.0.proto | default('tcp') }} from {{ item.1 }}" when: lxc_docker_host_manage_ufw - name: Allow Node Exporter from the monitoring host community.general.ufw: rule: allow port: "{{ lxc_docker_host_node_exporter_port | string }}" proto: tcp src: "{{ lxc_docker_host_monitoring_host }}" when: - lxc_docker_host_manage_ufw - lxc_docker_host_allow_node_exporter - name: Enable the restrictive firewall community.general.ufw: state: enabled policy: "{{ lxc_docker_host_ufw_policy }}" direction: incoming when: - lxc_docker_host_manage_ufw - lxc_docker_host_ufw_enable # --- Verification ---------------------------------------------------------- - name: Verify the effective Docker storage driver ansible.builtin.command: argv: - docker - info - --format - "{% raw %}{{.Driver}}{% endraw %}" register: lxc_docker_host_driver changed_when: false failed_when: lxc_docker_host_driver.stdout != lxc_docker_host_storage_driver when: lxc_docker_host_verify_storage_driver