00_core.ymlΒΆ

---
- include_tasks: utils/once/flag.yml

- name: "βœ… Assert the mail domain is provisionable by Stalwart"
  ansible.builtin.assert:
    that:
      - STALWART_DOMAIN.split('.')[-1] not in ['example', 'invalid']
    fail_msg: >-
      Stalwart rejects the mail domain '{{ STALWART_DOMAIN }}' (TLD
      '.{{ STALWART_DOMAIN.split('.')[-1] }}'). Use a real domain, or a
      `.test` domain for local/CI stacks.
    quiet: true

- name: "πŸ›‘οΈ Refuse to replace a Stalwart that serves a store from before 1.0"
  include_tasks: store_guard.yml
  when: IS_STACK_HOST | bool

- name: "πŸ”΄ Disable SMTP to avoid port conflicts"
  include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-mail-smtp/tasks/disable.yml') }}"

- name: βœ… Ensure Stalwart config directory exists
  file:
    path: "{{ STALWART_CONFIG_DIR }}"
    state: directory
    mode: "0755"

- name: βœ… Ensure certs bind-source directory exists (host)
  file:
    path: "{{ [ STALWART_VOLUMES_DIR, 'certs' ] | path_join }}"
    state: directory
    mode: "0755"

- name: πŸ“„ Render Stalwart bootstrap configuration
  stack_host_template:
    src: config.json.j2
    dest: "{{ STALWART_CONFIG_FILE }}"
    mode: "0644"

- name: "βœ… Ensure the WebUI cache directory exists"
  ansible.builtin.file:
    path: "{{ STALWART_WEBUI_CACHE_FILE | dirname }}"
    state: directory
    mode: "0755"

- name: "⬇️ Download the Stalwart WebUI bundle (skipped when cached)"
  get_url_retry:
    url: "{{ STALWART_WEBUI_RESOURCE_URL }}"
    dest: "{{ STALWART_WEBUI_CACHE_FILE }}"
    mode: "0644"
  when: IS_STACK_HOST | bool

- name: "πŸ“¦ Install the cached WebUI bundle into the instance dir"
  stack_host_copy:
    src: "{{ STALWART_WEBUI_CACHE_FILE }}"
    dest: "{{ STALWART_WEBUI_LOCAL_FILE }}"
    remote_src: true
    mode: "0644"

- name: βœ… Ensure Roundcube custom-config directory exists
  file:
    path: "{{ STALWART_WEBMAIL_CONFIG_DIR }}"
    state: directory
    mode: "0755"

- name: πŸ“„ Render Roundcube OAuth (Keycloak SSO) configuration
  stack_host_template:
    src: roundcube-oauth.inc.php.j2
    dest: "{{ STALWART_WEBMAIL_OAUTH_CONFIG }}"
    mode: "0644"
  register: stalwart_webmail_conf

- name: 🎨 Render Roundcube corporate design configuration
  stack_host_template:
    src: webmail-design.inc.php.j2
    dest: "{{ STALWART_WEBMAIL_DESIGN_CONFIG }}"
    mode: "0644"
  register: stalwart_webmail_design_conf

- name: πŸ“„ Render clamav-milter configuration
  stack_host_template:
    src: clamav-milter.conf.j2
    dest: "{{ STALWART_CLAMAV_MILTER_CONF }}"
    mode: "0644"
  register: stalwart_clamav_conf
  when: STALWART_ANTIVIRUS_ENABLED | bool

- name: "🧩 load docker, db and proxy for {{ application_id }}"
  include_role:
    name: sys-stk-full
  vars:
    compose_handlers_flush: true
    webserver_vhost_flavour: "basic"
    webserver_extra_configuration: "location ^~ /webmail { return 301 {{ STALWART_WEBMAIL_BASE_URL }}/; }"
    proxy_forwarded_client_address: true
    domain: "{{ STALWART_WEB_DOMAIN }}"

- name: "🚿 Flush Docker Compose handlers"
  meta: flush_handlers

- name: "🌐 Proxy the Roundcube webmail at {{ STALWART_WEBMAIL_DOMAIN }}"
  include_role:
    name: sys-stk-front-proxy
  vars:
    domain: "{{ STALWART_WEBMAIL_DOMAIN }}"
    http_port: "{{ STALWART_WEBMAIL_HTTP_PORT }}"
    webserver_proxy_service_key: "{{ 'webmail' if IS_SWARM_MODE else (application_id | entity_name) }}"
    proxy_internal_port: "{{ lookup('config', application_id, 'services.webmail.ports.internal.http') if IS_SWARM_MODE else '' }}"
    webserver_vhost_flavour: "basic"

- name: "πŸ‘” Stalwart manager-side operations (container exec + provisioning)"
  include_tasks: manager_ops.yml
  when: IS_STACK_HOST | bool