Solved bug existed due to difference between mailu domain and hostname difference. also refactored during this to find the bug

This commit is contained in:
2025-08-16 14:29:07 +02:00
parent 1bed83078e
commit 0de26fa6c7
76 changed files with 543 additions and 487 deletions

View File

@@ -1,10 +1,23 @@
- name: "load docker, db and proxy for {{ application_id }}"
include_role:
name: cmp-db-docker-proxy
- name: Ensure MAILU_HOSTNAMES is a list with max 1 entry
ansible.builtin.assert:
that:
- MAILU_HOSTNAMES is iterable
- MAILU_HOSTNAMES is sequence
- MAILU_HOSTNAMES | length <= 1
fail_msg: "MAILU_HOSTNAMES must be a list with at most one entry (only one host is supported). You can set the other ones as alias."
success_msg: "MAILU_HOSTNAMES is valid."
- name: "Include the srv-proxy-6-6-tls-deploy role"
include_role:
name: srv-proxy-6-6-tls-deploy
- name: "Mailu Docker and Webserver Setup"
block:
- name: "load docker, db and proxy for {{ application_id }}"
include_role:
name: cmp-db-docker-proxy
- name: "Include the sys-svc-cert-sync-docker role"
include_role:
name: sys-svc-cert-sync-docker
vars:
domain: "{{ MAILU_HOSTNAME }}"
- name: Flush docker service handlers
meta: flush_handlers
@@ -12,10 +25,8 @@
- name: "Create Mailu accounts"
include_tasks: 02_create-mailu-user.yml
vars:
mailu_compose_dir: "{{ docker_compose.directories.instance }}"
mailu_domain: "{{ PRIMARY_DOMAIN }}"
MAILU_DOCKER_DIR: "{{ docker_compose.directories.instance }}"
mailu_api_base_url: "http://127.0.0.1:8080/api/v1"
mailu_global_api_token: "{{ applications | get_app_conf(application_id, 'credentials.api_token') }}"
mailu_action: >-
{{
(

View File

@@ -1,9 +1,9 @@
- name: "Ensure Mailu user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ mailu_domain }}'' exists"
- name: "Ensure Mailu user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}'' exists"
command: >
docker compose exec admin flask mailu {{ mailu_action }}
{{ mailu_user_name }} {{ mailu_domain }} '{{ mailu_password }}'
{{ mailu_user_name }} {{ MAILU_DOMAIN }} '{{ mailu_password }}'
args:
chdir: "{{ mailu_compose_dir }}"
chdir: "{{ MAILU_DOCKER_DIR }}"
register: mailu_user_result
failed_when: >
mailu_user_result.rc != 0 and
@@ -15,12 +15,12 @@
when: "'mail-bot' in item.value.roles or 'administrator' in item.value.roles"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: "Change password for user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ mailu_domain }}'"
- name: "Change password for user '{{ mailu_user_key }};{{ mailu_user_name }}@{{ MAILU_DOMAIN }}'"
command: >
docker compose exec admin flask mailu password
{{ mailu_user_name }} {{ mailu_domain }} '{{ mailu_password }}'
{{ mailu_user_name }} {{ MAILU_DOMAIN }} '{{ mailu_password }}'
args:
chdir: "{{ mailu_compose_dir }}"
chdir: "{{ MAILU_DOCKER_DIR }}"
when: "'mail-bot' in item.value.roles or 'administrator' in item.value.roles"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

View File

@@ -3,9 +3,9 @@
command: >-
docker compose exec -T admin \
curl -s -X GET {{ mailu_api_base_url }}/token \
-H "Authorization: Bearer {{ mailu_global_api_token }}"
-H "Authorization: Bearer {{ MAILU_API_TOKEN }}"
args:
chdir: "{{ mailu_compose_dir }}"
chdir: "{{ MAILU_DOCKER_DIR }}"
register: mailu_tokens_cli
changed_when: false
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
@@ -25,9 +25,9 @@
command: >-
docker compose exec -T admin \
curl -s -X DELETE {{ mailu_api_base_url }}/token/{{ mailu_user_existing_token.id }} \
-H "Authorization: Bearer {{ mailu_global_api_token }}"
-H "Authorization: Bearer {{ MAILU_API_TOKEN }}"
args:
chdir: "{{ mailu_compose_dir }}"
chdir: "{{ MAILU_DOCKER_DIR }}"
when:
- users[mailu_user_key].mailu_token is not defined
- mailu_user_existing_token is not none
@@ -40,7 +40,7 @@
command: >-
docker compose exec -T admin \
curl -s -X POST {{ mailu_api_base_url }}/token \
-H "Authorization: Bearer {{ mailu_global_api_token }}" \
-H "Authorization: Bearer {{ MAILU_API_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{{ {
"comment": mailu_user_key ~ " - ansible.infinito",
@@ -48,7 +48,7 @@
"ip": mailu_token_ip
} | to_json }}'
args:
chdir: "{{ mailu_compose_dir }}"
chdir: "{{ MAILU_DOCKER_DIR }}"
when: users[mailu_user_key].mailu_token is not defined
register: mailu_token_creation
changed_when: mailu_token_creation.rc == 0

View File

@@ -1,108 +1,125 @@
- name: "Load Mailu DNS variables"
include_vars: vars/mailu-dns.yml
- name: Generate DKIM public key
include_tasks: 05_generate-and-read-dkim.yml
- name: "Set A record for mail server"
# A/AAAA record for the mail host in the **Hostname Zone**
- name: "Set A record for Mailu host"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_HOSTNAME_DNS_ZONE }}"
type: A
name: "{{ domain }}"
content: "{{ mailu_dns_ip }}"
name: "{{ MAILU_HOSTNAME }}" # Fully Qualified Domain Name of the mail host
content: "{{ MAILU_IP4_PUBLIC }}"
proxied: false
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: "Set AAAA record for Mailu host"
community.general.cloudflare_dns:
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_HOSTNAME_DNS_ZONE }}"
type: AAAA
name: "{{ MAILU_HOSTNAME }}"
content: "{{ MAILU_IP6_PUBLIC }}"
proxied: false
ttl: 1
state: present
when: MAILU_IP6_PUBLIC is defined and MAILU_IP6_PUBLIC | length > 0
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# Autoconfig CNAME record in the **Mail Domain Zone**
- name: "Set CNAME record for autoconfig"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: CNAME
name: "autoconfig.{{ mailu_dns_zone }}"
value: "{{ domain }}"
name: "autoconfig.{{ MAILU_DOMAIN_DNS_ZONE }}"
value: "{{ MAILU_HOSTNAME }}" # Points to the Mailu host FQDN
proxied: false
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# MX record in the **Mail Domain Zone**
- name: "Set MX record"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: MX
name: "{{ mailu_dns_zone }}"
value: "{{ domain }}"
name: "{{ MAILU_DOMAIN }}" # Root mail domain
value: "{{ MAILU_HOSTNAME }}" # Points to the Mailu host
priority: 10
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# SRV records in the **Mail Domain Zone**
- name: "Set SRV records"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: SRV
service: "_{{ item.key }}"
proto: "_tcp"
priority: "{{ item.value.priority }}"
weight: "{{ item.value.weight }}"
port: "{{ item.value.port }}"
value: "{{ domain }}"
value: "{{ MAILU_HOSTNAME }}" # Target = Mailu host FQDN
ttl: 1
state: present
loop: "{{ mailu_dns_srv_records | dict2items }}"
name: "{{ MAILU_DOMAIN }}"
loop: "{{ MAILU_DNS_SRV_RECORDS | dict2items }}"
ignore_errors: true
#register: srv_result
#failed_when: srv_result.rc != 0 and ("An identical record already exists" not in srv_result.stdout)
#changed_when: srv_result.rc == 0 and ("An identical record already exists" not in srv_result.stdout)
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# SPF TXT record in the **Mail Domain Zone**
- name: "Set SPF TXT record"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: TXT
name: "{{ mailu_dns_zone }}"
value: "v=spf1 mx a:{{ domain }} ~all"
name: "{{ MAILU_DOMAIN }}"
value: "v=spf1 mx a:{{ MAILU_HOSTNAME }} ~all"
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# DMARC TXT record in the **Mail Domain Zone**
- name: "Set DMARC TXT record"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: TXT
name: "_dmarc.{{ mailu_dns_zone }}"
value: "v=DMARC1; p=reject; ruf=mailto:{{ mailu_dmarc_ruf }}; adkim=s; aspf=s"
name: "_dmarc.{{ MAILU_DOMAIN_DNS_ZONE }}"
value: "v=DMARC1; p=reject; ruf=mailto:{{ MAILU_DMARC_RUF }}; adkim=s; aspf=s"
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
# DKIM TXT record in the **Mail Domain Zone**
- name: "Set DKIM TXT record"
community.general.cloudflare_dns:
api_token: "{{ cloudflare_record_api_token }}"
zone: "{{ mailu_dns_zone }}"
api_token: "{{ MAILU_CLOUDFLARE_API_TOKEN }}"
zone: "{{ MAILU_DOMAIN_DNS_ZONE }}"
type: TXT
name: "dkim._domainkey.{{ mailu_dns_zone }}"
name: "dkim._domainkey.{{ MAILU_DOMAIN_DNS_ZONE }}"
value: "{{ mailu_dkim_public_key }}"
ttl: 1
state: present
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

View File

@@ -1,7 +1,7 @@
- name: Check if DKIM private key file exists in the antispam container
command: >
docker compose exec -T antispam
test -f {{ mailu_dkim_key_path }}
test -f {{ MAILU_DKIM_KEY_PATH }}
register: dkim_key_file_stat
failed_when: false
changed_when: false
@@ -11,7 +11,7 @@
- name: Generate DKIM key
command: >
docker compose exec -T antispam
rspamadm dkim_keygen -s dkim -d {{ applications | get_app_conf(application_id, 'domain', True) }} -k {{ mailu_dkim_key_path }}
rspamadm dkim_keygen -s dkim -d {{ MAILU_DOMAIN }} -k {{ MAILU_DKIM_KEY_PATH }}
register: dkim_keygen_output
when: dkim_key_file_stat.rc != 0
args:
@@ -21,7 +21,7 @@
- name: Fetch DKIM private key from antispam container
shell: >
docker compose exec -T antispam
cat {{ mailu_dkim_key_path }}
cat {{ MAILU_DKIM_KEY_PATH }}
args:
chdir: "{{ docker_compose.directories.instance }}"
register: dkim_priv_content

View File

@@ -2,29 +2,29 @@
# Core services
resolver:
image: {{docker_source}}/unbound:{{ mailu_version }}
container_name: {{mailu_name}}_resolver
image: {{ MAILU_DOCKER_FLAVOR }}/unbound:{{ MAILU_VERSION }}
container_name: {{ MAILU_CONTAINER }}_resolver
{% include 'roles/docker-container/templates/base.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
ipv4_address: {{networks.local['web-app-mailu'].dns}}
ipv4_address: {{ MAILU_DNS_RESOLVER }}
front:
container_name: {{mailu_name}}_front
image: {{docker_source}}/nginx:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_front
image: {{ MAILU_DOCKER_FLAVOR }}/nginx:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
- "{{ networks.internet.ip4 }}:25:25"
- "{{ networks.internet.ip4 }}:465:465"
- "{{ networks.internet.ip4 }}:587:587"
- "{{ networks.internet.ip4 }}:110:110"
- "{{ networks.internet.ip4 }}:995:995"
- "{{ networks.internet.ip4 }}:143:143"
- "{{ networks.internet.ip4 }}:993:993"
- "{{ networks.internet.ip4 }}:4190:4190"
- "{{ MAILU_IP4_PUBLIC }}:25:25"
- "{{ MAILU_IP4_PUBLIC }}:465:465"
- "{{ MAILU_IP4_PUBLIC }}:587:587"
- "{{ MAILU_IP4_PUBLIC }}:110:110"
- "{{ MAILU_IP4_PUBLIC }}:995:995"
- "{{ MAILU_IP4_PUBLIC }}:143:143"
- "{{ MAILU_IP4_PUBLIC }}:993:993"
- "{{ MAILU_IP4_PUBLIC }}:4190:4190"
volumes:
- "{{docker_compose.directories.volumes}}overrides/nginx:/overrides:ro"
- "{{cert_mount_directory}}:/certs:ro"
- "{{ cert_mount_directory }}:/certs:ro"
{% include 'roles/docker-container/templates/depends_on/dmbs_incl.yml.j2' %}
resolver:
condition: service_started
@@ -32,11 +32,11 @@
webmail:
radicale:
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
admin:
container_name: {{mailu_name}}_admin
image: {{docker_source}}/admin:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_admin
image: {{ MAILU_DOCKER_FLAVOR }}/admin:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "admin_data:/data"
@@ -47,12 +47,12 @@
front:
condition: service_started
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
imap:
container_name: {{mailu_name}}_imap
image: {{docker_source}}/dovecot:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_imap
image: {{ MAILU_DOCKER_FLAVOR }}/dovecot:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "dovecot_mail:/mail"
@@ -61,12 +61,12 @@
- front
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
smtp:
container_name: {{mailu_name}}_smtp
image: {{docker_source}}/postfix:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_smtp
image: {{ MAILU_DOCKER_FLAVOR }}/postfix:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "{{docker_compose.directories.volumes}}overrides:/overrides:ro"
@@ -75,24 +75,24 @@
- front
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
oletools:
container_name: {{mailu_name}}_oletools
image: {{docker_source}}/oletools:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_oletools
image: {{ MAILU_DOCKER_FLAVOR }}/oletools:{{ MAILU_VERSION }}
hostname: oletools
restart: {{ DOCKER_RESTART_POLICY }}
depends_on:
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
noinet:
antispam:
container_name: {{mailu_name}}_antispam
image: {{docker_source}}/rspamd:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_antispam
image: {{ MAILU_DOCKER_FLAVOR }}/rspamd:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "filter:/var/lib/rspamd"
@@ -104,14 +104,14 @@
- antivirus
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
noinet:
# Optional services
antivirus:
container_name: {{mailu_name}}_antivirus
container_name: {{ MAILU_CONTAINER }}_antivirus
image: clamav/clamav-debian:latest
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
@@ -119,25 +119,25 @@
depends_on:
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
webdav:
container_name: {{mailu_name}}_webdav
image: {{docker_source}}/radicale:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_webdav
image: {{ MAILU_DOCKER_FLAVOR }}/radicale:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "webdav_data:/data"
depends_on:
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
radicale:
fetchmail:
container_name: {{mailu_name}}_fetchmail
image: {{docker_source}}/fetchmail:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_fetchmail
image: {{ MAILU_DOCKER_FLAVOR }}/fetchmail:{{ MAILU_VERSION }}
volumes:
- "admin_data:/data"
{% include 'roles/docker-container/templates/base.yml.j2' %}
@@ -147,12 +147,12 @@
- imap
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
webmail:
container_name: {{mailu_name}}_webmail
image: {{docker_source}}/webmail:{{ mailu_version }}
container_name: {{ MAILU_CONTAINER }}_webmail
image: {{ MAILU_DOCKER_FLAVOR }}/webmail:{{ MAILU_VERSION }}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- "webmail_data:/data"
@@ -162,25 +162,25 @@
- front
- resolver
dns:
- {{networks.local['web-app-mailu'].dns}}
- {{ MAILU_DNS_RESOLVER }}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
webmail:
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
smtp_queue:
name: {{ mailu_smtp_queue }}
name: {{ MAILU_SMTP_QUEUE_VOLUME }}
admin_data:
name: {{ mailu_admin_data }}
name: {{ MAILU_ADMIN_DATA_VOLUME }}
webdav_data:
name: {{ mailu_webdav_data }}
name: {{ MAILU_WEBDAV_DATA }}
webmail_data:
name: {{ mailu_webmail_data }}
name: {{ MAILU_WEBMAIL_DATA }}
filter:
name: {{ mailu_filter }}
name: {{ MAILU_FILTER_VOLUME }}
dkim:
name: {{ mailu_dkim }}
name: {{ MAILU_DKIM_VOLUME }}
dovecot_mail:
name: {{ mailu_dovecot_mail }}
name: {{ MAILU_DOVECOT_MAIL_VOLUME }}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
radicale:

View File

@@ -11,16 +11,16 @@
LD_PRELOAD=/usr/lib/libhardened_malloc.so
# Set to a randomly generated 16 bytes string
SECRET_KEY={{applications | get_app_conf(application_id,'credentials.secret_key')}}
SECRET_KEY={{ MAILU_SECRET_KEY }}
# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!)
SUBNET={{networks.local['web-app-mailu'].subnet}}
SUBNET={{ MAILU_SUBNET }}
# Main mail domain
DOMAIN={{ applications | get_app_conf(application_id,'domain') }}
DOMAIN={{ MAILU_DOMAIN }}
# Hostnames for this server, separated with comas
HOSTNAMES={{ domains[application_id] | join(',') }}
HOSTNAMES={{ MAILU_HOSTNAMES | join(',') }}
# Postmaster local part (will append the main mail domain)
POSTMASTER=admin
@@ -105,7 +105,7 @@ WEB_WEBMAIL=/webmail
SITENAME=Mailservices
# Linked Website URL
WEBSITE={{ domains | get_url(application_id, WEB_PROTOCOL) }}
WEBSITE={{ MAILU_WEBSITE }}
@@ -151,34 +151,34 @@ SQLALCHEMY_DATABASE_URI=mysql+mysqlconnector://{{ database_username }}:{{ databa
API=true
WEB_API=/api
# Configures the authentication token. The minimum length is 3 characters. This token must be passed as request header to the API as authentication token. This is a mandatory setting for using the RESTful API.
API_TOKEN={{ applications | get_app_conf(application_id, 'credentials.api_token')}}
API_TOKEN={{ MAILU_API_TOKEN}}
# Activated https://mailu.io/master/configuration.html#advanced-settings
AUTH_REQUIRE_TOKENS=True
{% if applications | get_app_conf(application_id, 'features.oidc', False) %}
{% if MAILU_OIDC_ENABLED | bool %}
###################################
# OpenID Connect settings
###################################
# @see https://github.com/heviat/Mailu-OIDC/tree/master
# Enable OpenID Connect. Possible values: True, False
OIDC_ENABLED={{ applications | get_app_conf(application_id, 'features.oidc', False) | string | capitalize }}
OIDC_ENABLED={{ MAILU_OIDC_ENABLED | string | capitalize }}
# OpenID Connect provider configuration URL
OIDC_PROVIDER_INFO_URL={{ oidc.client.issuer_url }}
OIDC_PROVIDER_INFO_URL={{ OIDC.CLIENT.ISSUER_URL }}
# OpenID Connect Client ID for Mailu
OIDC_CLIENT_ID={{ oidc.client.id }}
OIDC_CLIENT_ID={{ OIDC.CLIENT.ID }}
# OpenID Connect Client secret for Mailu
OIDC_CLIENT_SECRET={{ oidc.client.secret }}
OIDC_CLIENT_SECRET={{ OIDC.CLIENT.SECRET }}
# Label text for OpenID Connect login button. Default: OpenID Connect
OIDC_BUTTON_NAME={{ oidc.button_text }}
OIDC_BUTTON_NAME={{ OIDC.BUTTON_TEXT }}
# Disable TLS certificate verification for the OIDC client. Possible values: True, False
OIDC_VERIFY_SSL=True
@@ -187,17 +187,17 @@ OIDC_VERIFY_SSL=True
OIDC_CHANGE_PASSWORD_REDIRECT_ENABLED=True
# Redirect URL for password change. Defaults to provider issuer url appended by /.well-known/change-password
OIDC_CHANGE_PASSWORD_REDIRECT_URL={{oidc.client.change_credentials}}
OIDC_CHANGE_PASSWORD_REDIRECT_URL={{ OIDC.CLIENT.CHANGE_CREDENTIALS }}
{% if applications | get_app_conf(application_id, 'oidc.email_by_username', True) | bool %}
{% if MAILU_OIDC_EMAIL_BY_USERNAME_ENABLED | bool %}
# The OIDC claim used as the username. If the selected claim contains an email address, it will be used as is. If it is not an email (e.g., sub), the email address will be constructed as <OIDC_USERNAME_CLAIM>@<OIDC_USER_DOMAIN>. Defaults to email.
OIDC_USERNAME_CLAIM={{oidc.attributes.username}}
OIDC_USERNAME_CLAIM={{ OIDC.ATTRIBUTES.USERNAME }}
# The domain used when constructing an email from a non-email username (e.g., when OIDC_USERNAME_CLAIM=sub). Ignored if OIDC_USERNAME_CLAIM is already an email. Defaults to the value of DOMAIN.
OIDC_USER_DOMAIN={{ PRIMARY_DOMAIN }}
OIDC_USER_DOMAIN={{ MAILU_DOMAIN }}
{% endif %}
# If enabled, users who authenticate successfully but do not yet have an account will have one created for them. If disabled, only existing users can log in, and authentication will fail for users without a pre-existing account. Defaults to True.
OIDC_ENABLE_USER_CREATION={{ applications | get_app_conf(application_id, 'oidc.enable_user_creation', True) | string | capitalize }}
OIDC_ENABLE_USER_CREATION={{ MAILU_OIDC_ENABLE_USER_CREATION }}
{% endif %}

View File

@@ -1,41 +0,0 @@
# vars/mailu-dns.yml
mailu_dns_zone: "{{ applications | get_app_conf(application_id, 'domain', True) }}"
mailu_dns_ip: "{{ networks.internet.ip4 }}"
cloudflare_record_api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
mailu_dmarc_ruf: "{{ applications | get_app_conf(application_id, 'users.administrator.email', True) }}"
mailu_dkim_key_file: "{{ applications | get_app_conf(application_id, 'domain', True) }}.dkim.key"
mailu_dkim_key_path: "/dkim/{{ mailu_dkim_key_file }}"
mailu_dns_srv_records:
submission:
port: 587
priority: 20
weight: 1
submissions:
port: 465
priority: 20
weight: 1
imaps:
port: 993
priority: 20
weight: 1
imap:
port: 143
priority: 20
weight: 1
pop3s:
port: 995
priority: 20
weight: 1
pop3:
port: 110
priority: 20
weight: 1
autodiscover:
port: "{{ WEB_PORT }}"
priority: 20
weight: 1

View File

@@ -1,26 +1,70 @@
# General
application_id: "web-app-mailu"
domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}"
proxy_extra_configuration: "client_max_body_size 31M;"
application_id: "web-app-mailu"
http_port: "{{ ports.localhost.http[application_id] }}"
proxy_extra_configuration: "client_max_body_size 31M;"
# Database Configuration
database_password: "{{ applications | get_app_conf(application_id, ' credentials.database_password') }}"
database_type: "mariadb"
database_password: "{{ applications | get_app_conf(application_id, 'credentials.database_password') }}"
database_type: "mariadb"
cert_mount_directory: "{{ docker_compose.directories.volumes }}certs/"
# Cert Mount
cert_mount_directory: "{{ docker_compose.directories.volumes }}certs/"
# Mailu
## Meta
MAILU_WEBSITE: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
## Domains
MAILU_DOMAIN: "{{ applications | get_app_conf(application_id, 'domain') }}"
MAILU_DOMAIN_DNS_ZONE: "{{ MAILU_DOMAIN | to_zone }}"
MAILU_HOSTNAMES: "{{ domains[application_id] }}"
MAILU_HOSTNAME: "{{ domains | get_domain(application_id) }}"
MAILU_HOSTNAME_DNS_ZONE: "{{ MAILU_HOSTNAME | to_zone }}"
## Docker
MAILU_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.mailu.version') }}"
MAILU_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.mailu.name') }}"
## Volumes
MAILU_SMTP_QUEUE_VOLUME: "mailu_smtp_queue"
MAILU_ADMIN_DATA_VOLUME: "mailu_admin_data"
MAILU_WEBDAV_DATA: "mailu_webdav_data"
MAILU_WEBMAIL_DATA: "mailu_webmail_data"
MAILU_FILTER_VOLUME: "mailu_filter"
MAILU_DKIM_VOLUME: "mailu_dkim"
MAILU_DOVECOT_MAIL_VOLUME: "mailu_dovecot_mail"
## Network
MAILU_DNS_RESOLVER: "{{ networks.local['web-app-mailu'].dns_resolver }}"
MAILU_IP4_PUBLIC: "{{ networks.internet.ip4 }}"
MAILU_IP6_PUBLIC: false #Deactivated atm. but cloudflare logic present
MAILU_SUBNET: "{{ networks.local['web-app-mailu'].subnet }}"
## Credentials
MAILU_SECRET_KEY: "{{ applications | get_app_conf(application_id,'credentials.secret_key') }}"
MAILU_CLOUDFLARE_API_TOKEN: "{{ CERTBOT_DNS_API_TOKEN }}"
MAILU_API_TOKEN: "{{ applications | get_app_conf(application_id, 'credentials.api_token') }}"
## OIDC
MAILU_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc', False) }}"
MAILU_OIDC_EMAIL_BY_USERNAME_ENABLED: "{{ applications | get_app_conf(application_id, 'oidc.email_by_username') }}"
MAILU_OIDC_ENABLE_USER_CREATION: "{{ applications | get_app_conf(application_id, 'oidc.enable_user_creation') | string | capitalize }}"
# Use dedicated source for oidc if activated
# @see https://github.com/heviat/Mailu-OIDC/tree/2024.06
docker_source: "{{ 'ghcr.io/heviat' if applications | get_app_conf(application_id, 'features.oidc', False) else 'ghcr.io/mailu' }}"
MAILU_DOCKER_FLAVOR: "{{ 'ghcr.io/heviat' if MAILU_OIDC_ENABLED | bool else 'ghcr.io/mailu' }}"
# Mailu Specific
mailu_version: "{{ applications | get_app_conf(application_id, 'docker.services.mailu.version', True) }}"
mailu_name: "{{ applications | get_app_conf(application_id, 'docker.services.mailu.name', True) }}"
mailu_smtp_queue: "mailu_smtp_queue"
mailu_admin_data: "mailu_admin_data"
mailu_webdav_data: "mailu_webdav_data"
mailu_webmail_data: "mailu_webmail_data"
mailu_filter: "mailu_filter"
mailu_dkim: "mailu_dkim"
mailu_dovecot_mail: "mailu_dovecot_mail"
MAILU_DMARC_RUF: "{{ applications | get_app_conf(application_id, 'users.administrator.email') }}"
MAILU_DKIM_KEY_FILE: "{{ MAILU_DOMAIN }}.dkim.key"
MAILU_DKIM_KEY_PATH: "/dkim/{{ MAILU_DKIM_KEY_FILE }}"
MAILU_DNS_SRV_RECORDS:
submission: { port: 587, priority: 20, weight: 1 }
submissions: { port: 465, priority: 20, weight: 1 }
imaps: { port: 993, priority: 20, weight: 1 }
imap: { port: 143, priority: 20, weight: 1 }
pop3s: { port: 995, priority: 20, weight: 1 }
pop3: { port: 110, priority: 20, weight: 1 }
autodiscover: { port: 443, priority: 20, weight: 1 }