--- - name: Create tools root directory ansible.builtin.file: path: "{{ tools_root }}" state: directory owner: "{{ deploy_user }}" group: "{{ deploy_group }}" mode: "0750" - name: Create mailserver directories ansible.builtin.file: path: "{{ tools_root }}/mailserver/{{ item }}" state: directory owner: root group: root mode: "0755" loop: - mail-data - mail-state - mail-logs - config - name: Deploy docker-compose.yml ansible.builtin.template: src: docker-compose.yml.j2 dest: "{{ tools_root }}/docker-compose.yml" owner: "{{ deploy_user }}" group: "{{ deploy_group }}" mode: "0640" - name: Deploy .env ansible.builtin.template: src: env.j2 dest: "{{ tools_root }}/.env" owner: "{{ deploy_user }}" group: "{{ deploy_group }}" mode: "0600" - name: Pull images community.docker.docker_image: name: "{{ item }}" source: pull loop: - "{{ outline_image }}" - "{{ outline_db_image }}" - "{{ outline_redis_image }}" - "{{ n8n_image }}" - "{{ mailserver_image }}" - name: Start tools stack community.docker.docker_compose_v2: project_src: "{{ tools_root }}" state: present pull: missing - name: Wait for mailserver to be ready ansible.builtin.command: docker exec mailserver postfix status register: postfix_status changed_when: false retries: 12 delay: 10 until: postfix_status.rc == 0 # Check the host-side mounted config file directly (setup email list fails if file doesn't exist yet) - name: Check if noreply mail account exists ansible.builtin.stat: path: "{{ tools_root }}/mailserver/config/postfix-accounts.cf" register: postfix_accounts_file - name: Check noreply account in postfix-accounts.cf ansible.builtin.command: > grep -q "noreply@{{ domain_base }}" {{ tools_root }}/mailserver/config/postfix-accounts.cf register: mail_account_check changed_when: false failed_when: false when: postfix_accounts_file.stat.exists - name: Create noreply mail account ansible.builtin.command: > docker exec mailserver setup email add noreply@{{ domain_base }} {{ mailserver_noreply_password }} when: > not postfix_accounts_file.stat.exists or (mail_account_check.rc is defined and mail_account_check.rc != 0) - name: Check if DKIM key exists ansible.builtin.stat: path: "{{ tools_root }}/mailserver/config/rspamd/dkim/{{ domain_base }}.private" register: dkim_key - name: Generate DKIM key ansible.builtin.command: > docker exec mailserver setup config dkim domain {{ domain_base }} when: not dkim_key.stat.exists register: dkim_generated - name: Show DKIM DNS record ansible.builtin.command: > cat {{ tools_root }}/mailserver/config/rspamd/dkim/{{ domain_base }}.txt when: dkim_generated is changed register: dkim_record - name: Print DKIM DNS instructions ansible.builtin.debug: msg: | ══════════════════════════════════════════════════════════════════ DKIM key generated! Add this TXT record to Cloudflare DNS: {{ dkim_record.stdout }} Also add SPF record: Type: TXT Name: @ Value: v=spf1 ip4:{{ ip_tools }} ~all And DMARC record: Type: TXT Name: _dmarc Value: v=DMARC1; p=none; rua=mailto:admin@{{ domain_base }} ══════════════════════════════════════════════════════════════════ when: dkim_generated is changed