diff --git a/docs/services/exim-relay.md b/docs/services/exim-relay.md
new file mode 100644
index 0000000..8969f6c
--- /dev/null
+++ b/docs/services/exim-relay.md
@@ -0,0 +1,69 @@
+# Exim-relay
+
+Various services need to send out email.
+
+The default playbook configuration (`examples/vars.yml`) recommends that you enable the Exim relay SMTP mailer service (powered by [exim-relay](https://github.com/devture/exim-relay) and the [ansible-role-exim-relay](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay) Ansible role).
+
+## Configuration
+
+To enable this service, add the following configuration to your `vars.yml` file and re-run the [installation](../installing.md) process:
+
+```yaml
+########################################################################
+# #
+# exim_relay #
+# #
+########################################################################
+
+# Various services need to send out email.
+#
+# Enabling this Exim relay SMTP mailer service automatically wires
+# all other services to send email through it.
+#
+# exim-relay then gives you a centralized place for configuring email-sending.
+
+exim_relay_enabled: true
+
+exim_relay_hostname: mash.example.com
+
+exim_relay_sender_address: "someone@{{ exim_relay_hostname }}"
+
+# By default, exim-relay attempts to deliver emails directly.
+# To make it relay via an external SMTP server, see the "Relaying via an external SMTP server" section below.
+
+########################################################################
+# #
+# /exim_relay #
+# #
+########################################################################
+```
+
+Enabling this service, **automatically wires various other services to send email through it**.
+
+
+**By default, exim-relay attempts to deliver emails directly**. This may work to some extent on some servers, but deliverability may be low.
+To make the exim-relay service relay all outgoing emails via an external SMTP server, see [Relaying via an external SMTP server](#relaying-via-an-external-smtp-server)
+
+## Relaying via an external SMTP server
+
+To make the exim-relay service relay all outgoing emails via an external SMTP server, add the following to your `vars.yml` configuration:
+
+```yml
+exim_relay_relay_use: true
+exim_relay_relay_host_name: smtp.example.com
+exim_relay_relay_host_port: 465
+exim_relay_relay_auth: true
+exim_relay_relay_auth_username: ''
+exim_relay_relay_auth_password: ''
+```
+
+## Using a per-service sender address
+
+By default, all roles that this playbook wires to `exim-relay` will all be configured to send emails using a `From` address as configured in `exim_relay_sender_address`.
+
+To configure a given service to use another sender address, override the specific variables for the given service.
+
+For example, to make [Vaultwarden](vaultwarden.md) (automatically wired to send via `exim-relay` if you have it enabled) send emails from a custom address (instead of the default, `exim_relay_sender_address`), use configuration like this:
+```yml
+vaultwarden_config_smtp_from: vaultwarden@example.com
+```
diff --git a/docs/supported-services.md b/docs/supported-services.md
index 35aa295..d1a90e1 100644
--- a/docs/supported-services.md
+++ b/docs/supported-services.md
@@ -16,6 +16,7 @@
| [Docker Registry Browser](https://github.com/klausmeyer/docker-registry-browser) | Web Interface for the Docker Registry HTTP API V2 written in Ruby on Rails | [Link](services/docker-registry-browser.md) |
| [Docker Registry Purger](https://github.com/devture/docker-registry-purger) | A small tool used for purging a private Docker Registry's old tags | [Link](services/docker-registry-purger.md) |
| [Echo IP](https://github.com/mpolden/echoip) | A simple service for looking up your IP address | [Link](services/echoip.md) |
+| [exim-relay](https://github.com/devture/exim-relay) | A lightweight [Exim](https://www.exim.org/) SMTP mail relay server | [Link](services/exim-relay.md) |
| [Focalboard](https://www.focalboard.com/) | An open source, self-hosted alternative to [Trello](https://trello.com/), [Notion](https://www.notion.so/), and [Asana](https://asana.com/). | [Link](services/focalboard.md) |
| [FreshRSS](https://freshrss.org/) | RSS and Atom feed aggregator. | [Link](services/freshrss.md) |
| [Firezone](https://www.firezone.dev/) | A self-hosted VPN server (based on [WireGuard](https://www.wireguard.com/)) with a Web UI | [Link](services/firezone.md) |
diff --git a/examples/vars.yml b/examples/vars.yml
index d05b975..4677f23 100644
--- a/examples/vars.yml
+++ b/examples/vars.yml
@@ -110,6 +110,36 @@ devture_postgres_connection_password: ''
+########################################################################
+# #
+# exim_relay #
+# #
+########################################################################
+
+# Various services need to send out email.
+#
+# Enabling this Exim relay SMTP mailer service automatically wires
+# all other services to send email through it.
+#
+# exim-relay then gives you a centralized place for configuring email-sending.
+
+exim_relay_enabled: true
+
+exim_relay_hostname: mash.example.com
+
+exim_relay_sender_address: "someone@{{ exim_relay_hostname }}"
+
+# By default, exim-relay attempts to deliver emails directly.
+# To make it relay via an external SMTP server, see docs/services/exim-relay.md
+
+########################################################################
+# #
+# /exim_relay #
+# #
+########################################################################
+
+
+
########################################################################
# #
# miniflux #
diff --git a/releases.opml b/releases.opml
index 1a1760d..a59a657 100644
--- a/releases.opml
+++ b/releases.opml
@@ -15,6 +15,7 @@
+
diff --git a/templates/group_vars_mash_servers b/templates/group_vars_mash_servers
index a8fcb70..0b7dbf9 100644
--- a/templates/group_vars_mash_servers
+++ b/templates/group_vars_mash_servers
@@ -245,6 +245,11 @@ mash_playbook_devture_systemd_service_manager_services_list_auto_itemized:
{{ ({'name': (echoip_identifier + '.service'), 'priority': 2000, 'groups': ['mash', 'echoip']} if echoip_enabled else omit) }}
# /role-specific:echoip
+ # role-specific:exim_relay
+ - |-
+ {{ ({'name': (exim_relay_identifier + '.service'), 'priority': 2000, 'groups': ['mash', 'exim-relay']} if exim_relay_enabled else omit) }}
+ # /role-specific:exim_relay
+
# role-specific:firezone
- |-
{{ ({'name': (firezone_identifier + '.service'), 'priority': 2000, 'groups': ['mash', 'firezone']} if firezone_enabled else omit) }}
@@ -1482,6 +1487,29 @@ echoip_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolv
# /role-specific:echoip
+# role-specific:exim_relay
+########################################################################
+# #
+# exim_relay #
+# #
+########################################################################
+
+exim_relay_enabled: false
+
+exim_relay_identifier: "{{ mash_playbook_service_identifier_prefix }}exim-relay"
+
+exim_relay_base_path: "{{ mash_playbook_base_path }}/{{ mash_playbook_service_base_directory_name_prefix }}exim-relay"
+
+exim_relay_uid: "{{ mash_playbook_uid }}"
+exim_relay_gid: "{{ mash_playbook_gid }}"
+
+########################################################################
+# #
+# /exim_relay #
+# #
+########################################################################
+# /role-specific:exim_relay
+
# role-specific:firezone
########################################################################
@@ -1764,21 +1792,23 @@ gotosocial_base_path: "{{ mash_playbook_base_path }}/{{ mash_playbook_service_ba
gotosocial_uid: "{{ mash_playbook_uid }}"
gotosocial_gid: "{{ mash_playbook_gid }}"
-gotosocial_database_host: "{{ devture_postgres_identifier if devture_postgres_enabled else '' }}"
-gotosocial_database_port: "{{ '5432' if devture_postgres_enabled else '' }}"
-gotosocial_database_password: "{{ '%s' | format(mash_playbook_generic_secret_key) | password_hash('sha512', 'db.gotosocial', rounds=655555) | to_uuid }}"
-gotosocial_database_username: "{{ gotosocial_identifier }}"
-
gotosocial_systemd_required_services_list_auto: |
{{
([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled and gotosocial_database_host == devture_postgres_identifier else [])
}}
+gotosocial_systemd_wanted_services_list_auto: |
+ {{
+ ([(exim_relay_identifier | default('mash-exim-relay')) ~ '.service'] if (exim_relay_enabled | default(false) and gotosocial_smtp_host == exim_relay_identifier | default('mash-exim-relay')) else [])
+ }}
+
gotosocial_container_additional_networks_auto: |
{{
([mash_playbook_reverse_proxyable_services_additional_network] if mash_playbook_reverse_proxyable_services_additional_network else [])
+
([devture_postgres_container_network] if devture_postgres_enabled and gotosocial_database_host == devture_postgres_identifier and gotosocial_container_network != devture_postgres_container_network else [])
+ +
+ ([exim_relay_container_network | default('mash-exim-relay')] if (exim_relay_enabled | default(false) and gotosocial_smtp_host == exim_relay_identifier | default('mash-exim-relay') and gotosocial_container_network != exim_relay_container_network) else [])
}}
gotosocial_container_labels_traefik_enabled: "{{ mash_playbook_traefik_labels_enabled }}"
@@ -1786,6 +1816,17 @@ gotosocial_container_labels_traefik_docker_network: "{{ mash_playbook_reverse_pr
gotosocial_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}"
gotosocial_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}"
+gotosocial_database_host: "{{ devture_postgres_identifier if devture_postgres_enabled else '' }}"
+gotosocial_database_port: "{{ '5432' if devture_postgres_enabled else '' }}"
+gotosocial_database_password: "{{ '%s' | format(mash_playbook_generic_secret_key) | password_hash('sha512', 'db.gotosocial', rounds=655555) | to_uuid }}"
+gotosocial_database_username: "{{ gotosocial_identifier }}"
+
+# role-specific:exim_relay
+gotosocial_smtp_host: "{{ exim_relay_identifier if exim_relay_enabled else '' }}"
+gotosocial_smtp_port: 8025
+gotosocial_smtp_from: "{{ exim_relay_sender_address if exim_relay_enabled else '' }}"
+# /role-specific:exim_relay
+
########################################################################
# #
# /gotosocial #
@@ -3150,12 +3191,19 @@ nextcloud_systemd_required_services_list_auto: |
([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled and nextcloud_database_hostname == devture_postgres_identifier else [])
}}
+nextcloud_systemd_wanted_services_list_auto: |
+ {{
+ ([(exim_relay_identifier | default('mash-exim-relay')) ~ '.service'] if (exim_relay_enabled | default(false) and nextcloud_config_parameter_mail_smtphost == exim_relay_identifier | default('mash-exim-relay')) else [])
+ }}
+
nextcloud_container_additional_networks_auto: |
{{
(
([mash_playbook_reverse_proxyable_services_additional_network] if mash_playbook_reverse_proxyable_services_additional_network else [])
+
([devture_postgres_container_network] if devture_postgres_enabled and nextcloud_database_hostname == devture_postgres_identifier and nextcloud_container_network != devture_postgres_container_network else [])
+ +
+ ([exim_relay_container_network | default('mash-exim-relay')] if (exim_relay_enabled | default(false) and nextcloud_config_parameter_mail_smtphost == exim_relay_identifier | default('mash-exim-relay') and nextcloud_container_network != exim_relay_container_network) else [])
) | unique
}}
@@ -3169,6 +3217,15 @@ nextcloud_database_port: "{{ '5432' if devture_postgres_enabled else '' }}"
nextcloud_database_username: "nextcloud"
nextcloud_database_password: "{{ '%s' | format(mash_playbook_generic_secret_key) | password_hash('sha512', 'db.nextcloud', rounds=655555) | to_uuid }}"
+# role-specific:exim_relay
+nextcloud_config_parameter_mail_smtphost: "{{ exim_relay_identifier if exim_relay_enabled else '' }}"
+nextcloud_config_parameter_mail_smtpport: "{{ 8025 if exim_relay_enabled else '' }}"
+nextcloud_config_parameter_mail_smtpsecure: ''
+nextcloud_config_parameter_mail_smtpauth: false
+nextcloud_config_parameter_mail_from_address: "{{ (exim_relay_sender_address | split('@'))[0] if exim_relay_enabled else '' }}"
+nextcloud_config_parameter_mail_domain: "{{ (exim_relay_sender_address | split('@'))[1] if exim_relay_enabled else '' }}"
+# /role-specific:exim_relay
+
########################################################################
# #
# /nextcloud #
@@ -4067,11 +4124,18 @@ vaultwarden_systemd_required_systemd_services_list_auto: |
([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled and vaultwarden_database_hostname == devture_postgres_identifier else [])
}}
+vaultwarden_systemd_wanted_systemd_services_list_auto: |
+ {{
+ ([(exim_relay_identifier | default('mash-exim-relay')) ~ '.service'] if (exim_relay_enabled | default(false) and vaultwarden_config_smtp_host == exim_relay_identifier | default('mash-exim-relay')) else [])
+ }}
+
vaultwarden_container_additional_networks_auto: |
{{
([mash_playbook_reverse_proxyable_services_additional_network] if mash_playbook_reverse_proxyable_services_additional_network else [])
+
([devture_postgres_container_network] if devture_postgres_enabled and vaultwarden_database_hostname == devture_postgres_identifier and vaultwarden_container_network != devture_postgres_container_network else [])
+ +
+ ([exim_relay_container_network | default('mash-exim-relay')] if (exim_relay_enabled | default(false) and vaultwarden_config_smtp_host == exim_relay_identifier | default('mash-exim-relay') and vaultwarden_container_network != exim_relay_container_network) else [])
}}
vaultwarden_container_labels_traefik_enabled: "{{ mash_playbook_traefik_labels_enabled }}"
@@ -4084,6 +4148,13 @@ vaultwarden_database_port: "{{ '5432' if devture_postgres_enabled else '' }}"
vaultwarden_database_username: "vaultwarden"
vaultwarden_database_password: "{{ '%s' | format(mash_playbook_generic_secret_key) | password_hash('sha512', 'db.vaultwarden', rounds=655555) | to_uuid }}"
+# role-specific:exim_relay
+vaultwarden_config_smtp_from: "{{ exim_relay_sender_address if exim_relay_enabled else '' }}"
+vaultwarden_config_smtp_host: "{{ exim_relay_identifier if exim_relay_enabled else '' }}"
+vaultwarden_config_smtp_port: "{{ 8025 if exim_relay_enabled else '587' }}"
+vaultwarden_config_smtp_security: "{{ 'off' if exim_relay_enabled else 'starttls' }}"
+# /role-specific:exim_relay
+
########################################################################
# #
# /vaultwarden #
diff --git a/templates/requirements.yml b/templates/requirements.yml
index fe9f0a7..d662543 100644
--- a/templates/requirements.yml
+++ b/templates/requirements.yml
@@ -68,6 +68,10 @@
version: v0.0.0-0
name: echoip
activation_prefix: echoip_
+- src: git+https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay.git
+ version: v4.97-r0-0-1
+ name: exim_relay
+ activation_prefix: exim_relay_
- src: git+https://gitlab.com/etke.cc/roles/fail2ban.git
version: 09886730e8d3c061f22d1da4a542899063f97f0a
name: fail2ban
diff --git a/templates/setup.yml b/templates/setup.yml
index 7b6b482..e1016ff 100644
--- a/templates/setup.yml
+++ b/templates/setup.yml
@@ -136,6 +136,10 @@
- role: galaxy/echoip
# /role-specific:echoip
+ # role-specific:exim_relay
+ - role: galaxy/exim_relay
+ # /role-specific:exim_relay
+
# role-specific:firezone
- role: galaxy/firezone
# /role-specific:firezone