--- # Not a Compose stack, and deliberately not forced into the role. # # banner.html is a single shared file that belongs to the *reverse-proxy* stack's # directory. There is no payload directory of its own and no compose file to # bring up, and compose_stack syncs a whole directory and then calls # `docker compose up`, so it cannot express this. Plain tasks instead. # # This is the escape hatch, and it is a small one. If you find yourself writing a # third playbook like this, that is a sign the role's contract should grow # instead — see AGENTS.md. - name: Deploy the shared default-vhost banner hosts: - edge - app gather_facts: false tags: [banner] vars: # One file, shared by both hosts, unlike the per-host stack payloads. banner_src: "{{ repo_root }}/server/shared/components/banner.html" banner_html_dir: "{{ stack_root }}/reverse-proxy/proxy-data/html" tasks: - name: Ensure the reverse proxy's html directory exists # reverse-proxy.yml creates this too. Repeated here so this playbook runs # standalone on a host where the proxy payload has never been synced — # every playbook in this repository stands on its own (AGENTS.md, rule 2). ansible.builtin.file: path: "{{ banner_html_dir }}" state: directory mode: "0755" - name: Install the shared banner ansible.builtin.copy: src: "{{ banner_src }}" dest: "{{ banner_html_dir }}/index.html" mode: "0644" notify: Reload nginx handlers: # html/ is a bind mount, so the container is never recreated for this file; # the reload is the only thing that applies it. It fires only when the copy # above reported a change, so a repeat run is a genuine no-op. It fails if # the reverse proxy is not running, which means reverse-proxy.yml has never # run on this host. - name: Reload nginx ansible.builtin.command: cmd: docker exec reverse-proxy nginx -s reload changed_when: true