--- - name: Ensure the service directory exists ansible.builtin.file: path: "{{ reverse_proxy__base_dir }}" state: directory mode: "0750" # create the scaffold even in --check so dry-run can evaluate templates + compose (idempotent mkdir) check_mode: false tags: [config] - name: Ensure the Caddy config directory exists ansible.builtin.file: path: "{{ reverse_proxy__base_dir }}/caddy" state: directory mode: "0750" # create the scaffold even in --check so dry-run can evaluate templates + compose (idempotent mkdir) check_mode: false tags: [config] # Render into a directory that is bind-mounted whole (./caddy -> /etc/caddy). Mounting # the directory, not the single file, means an atomic template rewrite (which swaps the # file inode) stays visible inside the running container, so `caddy reload` picks it up. # A single-file bind mount pins the original inode and reload silently no-ops (ADR-024). - name: Render the Caddyfile ansible.builtin.template: src: Caddyfile.j2 dest: "{{ reverse_proxy__base_dir }}/caddy/Caddyfile" mode: "0644" notify: reload caddy tags: [config] - name: Render the Gandi DNS-01 token env file ansible.builtin.template: src: env.j2 dest: "{{ reverse_proxy__base_dir }}/env" mode: "0600" no_log: true # contains the Gandi PAT when: reverse_proxy__acme_dns_provider == 'gandi' notify: reload caddy tags: [config] - name: Render the compose file ansible.builtin.template: src: docker-compose.yml.j2 dest: "{{ reverse_proxy__base_dir }}/docker-compose.yml" mode: "0644" tags: [config] - name: Bring the reverse proxy up community.docker.docker_compose_v2: project_src: "{{ reverse_proxy__base_dir }}" state: present when: reverse_proxy__manage | bool tags: [deploy]