services.ymlΒΆ

---
# nocheck: seaweedfs-required β€” object storage not implemented for this role
sso:
  bond: 1
  enabled: "{{ 'web-app-keycloak' in group_names }}"
  shared: "{{ 'web-app-keycloak' in group_names }}"
  flavor: oidc
  oidc:
    email_by_username: true
    enable_user_creation: true
logout:
  bond: 1
  enabled: "{{ 'web-svc-logout' in group_names }}"
  shared: "{{ 'web-svc-logout' in group_names }}"
dashboard:
  bond: 1
  enabled: "{{ 'web-app-dashboard' in group_names }}"
  shared: "{{ 'web-app-dashboard' in group_names }}"
matomo:
  bond: 1
  enabled: "{{ 'web-app-matomo' in group_names }}"
  shared: "{{ 'web-app-matomo' in group_names }}"
# nocheck: dynamic-flag
email:
  bond: 1
  enabled: "{{ MAIL_PROVIDER in group_names }}"
  shared: "{{ MAIL_PROVIDER in group_names }}"
# nocheck: playwright-service-flag β€” self-provider
mailu:
  modes:
    compose:
      enabled: true
    swarm:
      enabled: true
  bond: 1
  # nocheck: default-placement-manager  mail edge at a known IP: MX A-record, PTR and SPF bind inbound/outbound SMTP to the stack host IP (a floating task's egress IP breaks deliverability); postfix /queue and dovecot mail+index state are NFS-hostile and ARE the app (no central-service equivalent); cert renewals land in a node-local bind via a manager-side systemd timer
  placement: manager
  enabled: true # nocheck: dynamic-flag
  shared: true
  covers:
    - email
  # nocheck: unwatched-version  Reason: Mailu ships its images under the release-series tag while its git tags are patch level (2024.06.58), so the series is the pin and moves only on a deliberate migration
  version: "2024.06"
  name: mailu
  backup:
    project_hard_restart: true
  min_storage: 20GB
  domain: "{{ lookup('email').domain }}"
  dmarc:
    rua_user: administrator
  ports:
    local:
      http: 8007
    public:
      smtp: 25
      smtps: 465
      submission: 587
      pop3: 110
      pop3s: 995
      imap: 143
      imaps: 993
      sieve: 4190
    internal:
      http: 80
      smtp: 25
      smtps: 465
      submission: 587
      pop3: 110
      pop3s: 995
      imap: 143
      imaps: 993
      sieve: 4190
    onion:
      smtp: true
      submission: true
      imap: true
      pop3: true
      # nocheck: onion-flag  ManageSieve edits server-side filters, which is administration rather than the sending and receiving the onion transport is for
      sieve: false
  proxy:
    service_key: front
  run_after:
    - web-app-matomo
    - web-app-stalwart
  lifecycle: eol
  cpus: "1.0"
  mem_reservation: 512m
  mem_limit: 2g
  pids_limit: 1024
# nocheck: shared
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” DB engine, covered by role-local integration tests
redis:
  bond: 1
  name: mailu-redis
  backup:
    disabled: true
  enabled: true # nocheck: dynamic-flag
  # Exception: central redis overlay adds VIP pressure on manager-pinned mailu; embedded redis avoids it.
  shared: "{{ ('svc-db-redis' in group_names) and (DEPLOYMENT_MODE == 'compose') }}"
  cpus: "0.2"
  mem_reservation: 256m
  mem_limit: 512m
  pids_limit: 256
# nocheck: playwright-service-flag - central DNS resolver, infrastructural (no Playwright surface)
# nocheck: dynamic-flag  enabled+shared (not the `in group_names` form) marks svc-dns-unbound `required` so the loader deploys it every compose round; reverting reintroduces the admin DNS hang.
unbound:
  bond: 1
  enabled: "{{ DEPLOYMENT_MODE == 'compose' }}"
  shared: true
# nocheck: playwright-service-flag β€” DB engine, covered by role-local integration tests
mariadb:
  bond: 1
  enabled: true # nocheck: dynamic-flag
  shared: "{{ 'svc-db-mariadb' in group_names }}"
  cpus: "0.8"
  mem_reservation: 1g
  mem_limit: 2g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
admin:
  name: mailu-admin
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.3"
  mem_reservation: 256m
  mem_limit: 2g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
imap:
  name: mailu-imap
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.5"
  mem_reservation: 512m
  mem_limit: 1.5g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
smtp:
  name: mailu-smtp
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.5"
  mem_reservation: 512m
  mem_limit: 1.5g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
antispam:
  name: mailu-antispam
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.6"
  mem_reservation: 512m
  mem_limit: 1.5g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
antivirus:
  name: mailu-antivirus
  enabled: true # nocheck: dynamic-flag
  shared: false
  image: clamav/clamav-debian
  version: 1.5.4
  cpus: "0.6"
  mem_reservation: 2g
  mem_limit: 3g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
oletools:
  name: mailu-oletools
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.2"
  mem_reservation: 256m
  mem_limit: 512m
  pids_limit: 256
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
webdav:
  name: mailu-webdav
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.2"
  mem_reservation: 256m
  mem_limit: 512m
  pids_limit: 256
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
fetchmail:
  name: mailu-fetchmail
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.2"
  mem_reservation: 256m
  mem_limit: 512m
  pids_limit: 256
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
webmail:
  name: mailu-webmail
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.3"
  mem_reservation: 256m
  mem_limit: 1g
  pids_limit: 512
# nocheck: dynamic-flag
# nocheck: playwright-service-flag β€” internal sub-component
front:
  name: mailu-front
  enabled: true # nocheck: dynamic-flag
  shared: false
  cpus: "0.3"
  mem_reservation: 256m
  mem_limit: 1g
  pids_limit: 512
# nocheck: playwright-service-flag β€” verified by web-svc-css provider spec
css:
  bond: 1
  enabled: "{{ 'web-svc-css' in group_names }}"
  shared: "{{ 'web-svc-css' in group_names }}"
prometheus:
  bond: 1
  enabled: "{{ 'web-app-prometheus' in group_names }}"
  shared: "{{ 'web-app-prometheus' in group_names }}"

# nocheck: playwright-service-flag
# nocheck: variants-coverage β€” sso-variant-tor requires the onion on in every variant, so the false polarity has no variant left to live in
tor:
  bond: 0.5
  enabled: "{{ 'svc-net-tor' in group_names }}"
  shared: true # nocheck: dynamic-flag
# nocheck: dynamic-flag
# nocheck: playwright-service-flag, dynamic-flag infrastructure backup consumer
container_backup: # nocheck: bond-baseline backup host joins outside the variant topology
  bond: 1
  enabled: "{{ 'svc-bkp-volume-2-local' in group_names }}"
  shared: true