--- # The public entry point, and the stack every other stack depends on: it owns # proxy-net and the generated vhost configuration, so site.yml runs it first. # # Demonstrates the two things a payload made of plain configuration files needs: # bind-mount directories created before the container starts, and a reload after # the payload changes. - name: Deploy the reverse proxy hosts: edge gather_facts: false tags: [reverse-proxy] roles: - role: compose_stack vars: stack_name: reverse-proxy stack_networks: - proxy-net stack_dirs: # Bind mounts the compose file declares but no payload provides. Docker # would otherwise create them root-owned on first start, and html/ in # particular has to be writable by the deploy user before banner.yml # can put a file in it. # # No `mode` on any of them on purpose: the role only applies the # attributes an entry actually sets, so a directory that already exists # on the host keeps whatever permissions it has. - path: "{{ stack_root }}/reverse-proxy/proxy-data/conf" - path: "{{ stack_root }}/reverse-proxy/proxy-data/vhost" - path: "{{ stack_root }}/reverse-proxy/proxy-data/html" - path: "{{ stack_root }}/reverse-proxy/proxy-data/dhparam" # certs/ and acme/ are deliberately absent. They hold live private keys # and are managed by acme-companion; nothing here should touch their # ownership or permissions. post_tasks: - name: Reload nginx so changed vhost and conf files take effect # conf/ and vhost/ are bind mounts, so editing a file in them never causes # Compose to recreate the container — this reload is the only thing that # applies the change. compose_stack_synced is set by the role from the # payload sync, so a run that changed nothing stays a genuine no-op. ansible.builtin.command: cmd: docker exec reverse-proxy nginx -s reload when: compose_stack_synced | default(false) changed_when: true