# extravars: apps_dir, caddy_image, local_certs # # Docker из репозитория Docker, логи контейнеров с ротацией, автоматические обновления безопасности, папка приложений, # сеть web и ingress: приложение caddy, которое публикует 80 и 443. Caddy подключает блоки приложений # из data/caddy/sites/ и сам выпускает сертификаты для их доменов. local_certs - сертификаты своего CA Caddy. # Фаервол настраивается первым: nftables при старте стирает все правила, Docker ставит свои поверх. - name: Install Docker platform hosts: target gather_facts: true vars: caddy_dir: "{{ apps_dir }}/caddy" tasks: - ansible.builtin.import_tasks: tasks/firewall.yml vars: firewall_tcp_ports: [ "{{ ansible_port }}", 80, 443 ] firewall_udp_ports: [ 443 ] # трафик контейнеров идет через forward: его фильтрует Docker firewall_forward: true - name: Install prerequisites ansible.builtin.apt: name: [ ca-certificates, curl, python3, unattended-upgrades ] state: present update_cache: true - name: Enable automatic security updates ansible.builtin.copy: dest: /etc/apt/apt.conf.d/20auto-upgrades mode: "0644" content: | APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; - name: Create keyrings directory ansible.builtin.file: path: /etc/apt/keyrings state: directory mode: "0755" - name: Download Docker key ansible.builtin.get_url: url: https://download.docker.com/linux/debian/gpg dest: /etc/apt/keyrings/docker.asc mode: "0644" - name: Add Docker repository ansible.builtin.copy: dest: /etc/apt/sources.list.d/docker.sources mode: "0644" content: | Types: deb URIs: https://download.docker.com/linux/debian Suites: {{ ansible_facts.distribution_release }} Components: stable Architectures: {{ 'arm64' if ansible_facts.architecture == 'aarch64' else 'amd64' }} Signed-By: /etc/apt/keyrings/docker.asc - name: Create Docker config directory ansible.builtin.file: path: /etc/docker state: directory mode: "0755" - name: Configure Docker daemon ansible.builtin.copy: dest: /etc/docker/daemon.json mode: "0644" content: | { "log-driver": "local", "log-opts": {"max-size": "10m", "max-file": "3"} } register: docker_daemon - name: Install Docker ansible.builtin.apt: name: [ docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin ] state: present update_cache: true # после частых перезапусков (фаервол, release) systemd может держать Docker остановленным по лимиту запусков - name: Reset Docker start limit ansible.builtin.command: systemctl reset-failed docker.service changed_when: false failed_when: false - name: Start Docker ansible.builtin.systemd_service: name: docker enabled: true state: "{{ 'restarted' if docker_daemon.changed else 'started' }}" - name: Create apps directory ansible.builtin.file: path: "{{ apps_dir }}" state: directory mode: "0700" - name: Create web network ansible.builtin.shell: docker network inspect web >/dev/null 2>&1 || { docker network create web && echo created; } register: web_network changed_when: "'created' in web_network.stdout" - name: Create ingress directories ansible.builtin.file: path: "{{ caddy_dir }}/data/caddy/sites" state: directory mode: "0700" - name: Write ingress compose file ansible.builtin.template: src: templates/caddy-compose.yaml.j2 dest: "{{ caddy_dir }}/docker-compose.yaml" mode: "0600" # Caddyfile смонтирован папкой: файл, замененный целиком, контейнер увидел бы только после пересоздания - name: Write Caddyfile ansible.builtin.template: src: templates/Caddyfile.j2 dest: "{{ caddy_dir }}/data/caddy/Caddyfile" mode: "0644" register: caddyfile - name: Start ingress ansible.builtin.command: docker compose up -d --remove-orphans args: chdir: "{{ caddy_dir }}" register: caddy_up changed_when: "'Started' in caddy_up.stderr or 'Recreated' in caddy_up.stderr" - name: Reload Caddyfile ansible.builtin.command: docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile args: chdir: "{{ caddy_dir }}" when: caddyfile.changed and not caddy_up.changed