浏览代码

Use config.json to render multiple Jinja2 templates

FreddleSpl0it 3 月之前
父节点
当前提交
dba9675a9b

+ 39 - 16
data/Dockerfiles/bootstrap/modules/BootstrapBase.py

@@ -30,30 +30,53 @@ class BootstrapBase:
     self.mysql_conn = None
     self.redis_conn = None
 
-  def render_config(self, template_name, output_path, clean_blank_lines=False):
+  def render_config(self, config_file):
     """
-    Renders a Jinja2 template and writes it to the specified output path.
+    Renders multiple Jinja2 templates based on a JSON config file.
 
-    Args:
-      template_name (str): Name of the template file.
-      output_path (str or Path): Path to write the rendered output file.
-      clean_blank_lines (bool): If True, removes empty/whitespace-only lines from rendered output.
+    Each config entry must include:
+      - template (str): the template filename
+      - output (str): absolute path to the output file
+
+    Optional:
+      - clean_blank_lines (bool): remove empty lines from output
+      - if_not_exists (bool): skip rendering if output file already exists
     """
 
-    output_path = Path(output_path)
-    output_path.parent.mkdir(parents=True, exist_ok=True)
+    from pathlib import Path
+    import json
+
+    config_path = Path(config_file)
+    if not config_path.exists():
+      print(f"Template config file not found: {config_path}")
+      return
+
+    with config_path.open("r") as f:
+      entries = json.load(f)
+
+    for entry in entries:
+      template_name = entry["template"]
+      output_path = Path(entry["output"])
+      clean_blank_lines = entry.get("clean_blank_lines", False)
+      if_not_exists = entry.get("if_not_exists", False)
+
+      if if_not_exists and output_path.exists():
+        print(f"Skipping {output_path} (already exists)")
+        continue
+
+      output_path.parent.mkdir(parents=True, exist_ok=True)
+      template = self.env.get_template(template_name)
+      rendered = template.render(self.env_vars)
 
-    template = self.env.get_template(template_name)
-    rendered = template.render(self.env_vars)
+      if clean_blank_lines:
+        rendered = "\n".join(line for line in rendered.splitlines() if line.strip())
 
-    if clean_blank_lines:
-      rendered = "\n".join(line for line in rendered.splitlines() if line.strip())
+      rendered = rendered.replace('\r\n', '\n').replace('\r', '\n')
 
-    # converts output to Unix-style line endings
-    rendered = rendered.replace('\r\n', '\n').replace('\r', '\n')
+      with output_path.open("w") as f:
+        f.write(rendered)
 
-    with open(output_path, "w") as f:
-      f.write(rendered)
+      print(f"Rendered {template_name} to {output_path}")
 
   def prepare_template_vars(self, overwrite_path, extra_vars = None):
     """

+ 1 - 1
data/Dockerfiles/bootstrap/modules/BootstrapClamd.py

@@ -47,7 +47,7 @@ class Bootstrap(BootstrapBase):
     self.set_timezone()
 
     print("Render config")
-    self.render_config("whitelist.ign2.j2", "/var/lib/clamav/whitelist.ign2", clean_blank_lines=True)
+    self.render_config("/etc/clamav/config.json")
 
     # Fix permissions
     self.set_owner("/var/lib/clamav", "clamav", "clamav", recursive=True)

+ 1 - 17
data/Dockerfiles/bootstrap/modules/BootstrapDovecot.py

@@ -55,23 +55,7 @@ class Bootstrap(BootstrapBase):
     self.set_timezone()
 
     print("Render config")
-    self.render_config("dovecot-dict-sql-quota.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-quota.conf")
-    self.render_config("dovecot-dict-sql-userdb.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-userdb.conf")
-    self.render_config("dovecot-dict-sql-sieve_before.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-sieve_before.conf")
-    self.render_config("dovecot-dict-sql-sieve_after.conf.j2", "/etc/dovecot/sql/dovecot-dict-sql-sieve_after.conf")
-    self.render_config("mail_plugins.j2", "/etc/dovecot/mail_plugins")
-    self.render_config("mail_plugins_imap.j2", "/etc/dovecot/mail_plugins_imap")
-    self.render_config("mail_plugins_lmtp.j2", "/etc/dovecot/mail_plugins_lmtp")
-    self.render_config("global_sieve_after.sieve.j2", "/var/vmail/sieve/global_sieve_after.sieve")
-    self.render_config("global_sieve_before.sieve.j2", "/var/vmail/sieve/global_sieve_before.sieve")
-    self.render_config("dovecot-master.passwd.j2", "/etc/dovecot/dovecot-master.passwd")
-    self.render_config("dovecot-master.userdb.j2", "/etc/dovecot/dovecot-master.userdb")
-    self.render_config("sieve.creds.j2", "/etc/sogo/sieve.creds")
-    self.render_config("sogo-sso.pass.j2", "/etc/phpfpm/sogo-sso.pass")
-    self.render_config("cron.creds.j2", "/etc/sogo/cron.creds")
-    self.render_config("source_env.sh.j2", "/source_env.sh")
-    self.render_config("maildir_gc.sh.j2", "/usr/local/bin/maildir_gc.sh")
-    self.render_config("dovecot.conf.j2", "/etc/dovecot/dovecot.conf")
+    self.render_config("/etc/dovecot/config.json")
 
     files = [
       "/etc/dovecot/mail_plugins",

+ 1 - 1
data/Dockerfiles/bootstrap/modules/BootstrapMysql.py

@@ -46,7 +46,7 @@ class Bootstrap(BootstrapBase):
     self.set_timezone()
 
     print("Render config")
-    self.render_config("my.cnf.j2", "/etc/mysql/conf.d/my.cnf")
+    self.render_config("/etc/mysql/conf.d/config.json")
 
   def start_temporary(self, socket):
     """

+ 1 - 5
data/Dockerfiles/bootstrap/modules/BootstrapNginx.py

@@ -41,11 +41,7 @@ class Bootstrap(BootstrapBase):
     self.set_timezone()
 
     print("Render config")
-    self.render_config("nginx.conf.j2", "/etc/nginx/nginx.conf")
-    self.render_config("sites-default.conf.j2", "/etc/nginx/includes/sites-default.conf")
-    self.render_config("server_name.active.j2", "/etc/nginx/conf.d/server_name.active")
-    self.render_config("listen_plain.active.j2", "/etc/nginx/conf.d/listen_plain.active")
-    self.render_config("listen_ssl.active.j2", "/etc/nginx/conf.d/listen_ssl.active")
+    self.render_config("/etc/nginx/conf.d/config.json")
 
   def get_valid_cert_dirs(self):
     ssl_dir = '/etc/ssl/mail/'

+ 1 - 6
data/Dockerfiles/bootstrap/modules/BootstrapPhpfpm.py

@@ -44,12 +44,7 @@ class Bootstrap(BootstrapBase):
 
 
     print("Render config")
-    self.render_config("opcache-recommended.ini.j2", "/usr/local/etc/php/conf.d/opcache-recommended.ini")
-    self.render_config("pools.conf.j2", "/usr/local/etc/php-fpm.d/z-pools.conf")
-    self.render_config("other.ini.j2", "/usr/local/etc/php/conf.d/zzz-other.ini")
-    self.render_config("upload.ini.j2", "/usr/local/etc/php/conf.d/upload.ini")
-    self.render_config("session_store.ini.j2", "/usr/local/etc/php/conf.d/session_store.ini")
-    self.render_config("0081-custom-mailcow.css.j2", "/web/css/build/0081-custom-mailcow.css")
+    self.render_config("/php-conf/config.json")
 
     self.copy_file("/usr/local/etc/php/conf.d/opcache-recommended.ini", "/php-conf/opcache-recommended.ini")
     self.copy_file("/usr/local/etc/php-fpm.d/z-pools.conf", "/php-conf/pools.conf")

+ 1 - 33
data/Dockerfiles/bootstrap/modules/BootstrapPostfix.py

@@ -40,39 +40,7 @@ class Bootstrap(BootstrapBase):
     self.set_syslog_redis()
 
     print("Render config")
-    self.render_config("aliases.j2", "/etc/aliases")
-    self.render_config("mysql_relay_ne.cf.j2", "/opt/postfix/conf/sql/mysql_relay_ne.cf")
-    self.render_config("mysql_relay_recipient_maps.cf.j2", "/opt/postfix/conf/sql/mysql_relay_recipient_maps.cf")
-    self.render_config("mysql_tls_policy_override_maps.cf.j2", "/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf")
-    self.render_config("mysql_tls_enforce_in_policy.cf.j2", "/opt/postfix/conf/sql/mysql_tls_enforce_in_policy.cf")
-    self.render_config("mysql_sender_dependent_default_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sender_dependent_default_transport_maps.cf")
-    self.render_config("mysql_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_transport_maps.cf")
-    self.render_config("mysql_virtual_resource_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_resource_maps.cf")
-    self.render_config("mysql_sasl_passwd_maps_sender_dependent.cf.j2", "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_sender_dependent.cf")
-    self.render_config("mysql_sasl_passwd_maps_transport_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_transport_maps.cf")
-    self.render_config("mysql_virtual_alias_domain_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_alias_domain_maps.cf")
-    self.render_config("mysql_virtual_alias_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_alias_maps.cf")
-    self.render_config("mysql_recipient_bcc_maps.cf.j2", "/opt/postfix/conf/sql/mysql_recipient_bcc_maps.cf")
-    self.render_config("mysql_sender_bcc_maps.cf.j2", "/opt/postfix/conf/sql/mysql_sender_bcc_maps.cf")
-    self.render_config("mysql_recipient_canonical_maps.cf.j2", "/opt/postfix/conf/sql/mysql_recipient_canonical_maps.cf")
-    self.render_config("mysql_virtual_domains_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_domains_maps.cf")
-    self.render_config("mysql_virtual_mailbox_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf")
-    self.render_config("mysql_virtual_relay_domain_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_relay_domain_maps.cf")
-    self.render_config("mysql_virtual_sender_acl.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_sender_acl.cf")
-    self.render_config("mysql_mbr_access_maps.cf.j2", "/opt/postfix/conf/sql/mysql_mbr_access_maps.cf")
-    self.render_config("mysql_virtual_spamalias_maps.cf.j2", "/opt/postfix/conf/sql/mysql_virtual_spamalias_maps.cf")
-    self.render_config("sni.map.j2", "/opt/postfix/conf/sni.map")
-    self.render_config("main.cf.j2", "/opt/postfix/conf/main.cf")
-
-    # Conditional render
-    if not Path("/opt/postfix/conf/dns_blocklists.cf").exists():
-      self.render_config("dns_blocklists.cf.j2", "/opt/postfix/conf/dns_blocklists.cf")
-    if not Path("/opt/postfix/conf/dns_reply.map").exists():
-      self.render_config("dns_reply.map.j2", "/opt/postfix/conf/dns_reply.map")
-    if not Path("/opt/postfix/conf/custom_postscreen_whitelist.cidr").exists():
-      self.render_config("custom_postscreen_whitelist.cidr.j2", "/opt/postfix/conf/custom_postscreen_whitelist.cidr")
-    if not Path("/opt/postfix/conf/custom_transport.pcre").exists():
-      self.render_config("custom_transport.pcre.j2", "/opt/postfix/conf/custom_transport.pcre")
+    self.render_config("/opt/postfix/conf/config.json")
 
     # Create SNI Config
     self.run_command(["postmap", "-F", "hash:/opt/postfix/conf/sni.map"])

+ 1 - 7
data/Dockerfiles/bootstrap/modules/BootstrapRspamd.py

@@ -80,13 +80,7 @@ class Bootstrap(BootstrapBase):
     self.set_timezone()
 
     print("Render config")
-    self.render_config("mailcow_networks.map.j2", "/etc/rspamd/custom/mailcow_networks.map")
-    self.render_config("dovecot_trusted.map.j2", "/etc/rspamd/custom/dovecot_trusted.map")
-    self.render_config("rspamd_trusted.map.j2", "/etc/rspamd/custom/rspamd_trusted.map")
-    self.render_config("external_services.conf.j2", "/etc/rspamd/local.d/external_services.conf")
-    self.render_config("redis.conf.j2", "/etc/rspamd/local.d/redis.conf")
-    self.render_config("dqs-rbl.conf.j2", "/etc/rspamd/custom/dqs-rbl.conf")
-    self.render_config("worker-controller-password.inc.j2", "/etc/rspamd/override.d/worker-controller-password.inc")
+    self.render_config("/etc/rspamd/config.json")
 
     # Fix missing default global maps, if any
     # These exists in mailcow UI and should not be removed

+ 1 - 2
data/Dockerfiles/bootstrap/modules/BootstrapSogo.py

@@ -48,8 +48,7 @@ class Bootstrap(BootstrapBase):
     self.set_syslog_redis()
 
     print("Render config")
-    self.render_config("sogod.plist.j2", "/var/lib/sogo/GNUstep/Defaults/sogod.plist")
-    self.render_config("UIxTopnavToolbar.wox.j2", "/usr/lib/GNUstep/SOGo/Templates/UIxTopnavToolbar.wox")
+    self.render_config("/etc/sogo/config.json")
 
     print("Fix permissions")
     self.set_owner("/var/lib/sogo", "sogo", "sogo", recursive=True)

+ 7 - 0
data/conf/clamav/config.json

@@ -0,0 +1,7 @@
+[
+  {
+    "template": "whitelist.ign2.j2",
+    "output": "/var/lib/clamav/whitelist.ign2",
+    "clean_blank_lines": true
+  }
+]

+ 70 - 0
data/conf/dovecot/config.json

@@ -0,0 +1,70 @@
+[
+  {
+    "template": "dovecot-dict-sql-quota.conf.j2",
+    "output":   "/etc/dovecot/sql/dovecot-dict-sql-quota.conf"
+  },
+  {
+    "template": "dovecot-dict-sql-userdb.conf.j2",
+    "output":   "/etc/dovecot/sql/dovecot-dict-sql-userdb.conf"
+  },
+  {
+    "template": "dovecot-dict-sql-sieve_before.conf.j2",
+    "output":   "/etc/dovecot/sql/dovecot-dict-sql-sieve_before.conf"
+  },
+  {
+    "template": "dovecot-dict-sql-sieve_after.conf.j2",
+    "output":   "/etc/dovecot/sql/dovecot-dict-sql-sieve_after.conf"
+  },
+  {
+    "template": "mail_plugins.j2",
+    "output":   "/etc/dovecot/mail_plugins"
+  },
+  {
+    "template": "mail_plugins_imap.j2",
+    "output":   "/etc/dovecot/mail_plugins_imap"
+  },
+  {
+    "template": "mail_plugins_lmtp.j2",
+    "output":   "/etc/dovecot/mail_plugins_lmtp"
+  },
+  {
+    "template": "global_sieve_after.sieve.j2",
+    "output":   "/var/vmail/sieve/global_sieve_after.sieve"
+  },
+  {
+    "template": "global_sieve_before.sieve.j2",
+    "output":   "/var/vmail/sieve/global_sieve_before.sieve"
+  },
+  {
+    "template": "dovecot-master.passwd.j2",
+    "output":   "/etc/dovecot/dovecot-master.passwd"
+  },
+  {
+    "template": "dovecot-master.userdb.j2",
+    "output":   "/etc/dovecot/dovecot-master.userdb"
+  },
+  {
+    "template": "sieve.creds.j2",
+    "output":   "/etc/sogo/sieve.creds"
+  },
+  {
+    "template": "sogo-sso.pass.j2",
+    "output":   "/etc/phpfpm/sogo-sso.pass"
+  },
+  {
+    "template": "cron.creds.j2",
+    "output":   "/etc/sogo/cron.creds"
+  },
+  {
+    "template": "source_env.sh.j2",
+    "output":   "/source_env.sh"
+  },
+  {
+    "template": "maildir_gc.sh.j2",
+    "output":   "/usr/local/bin/maildir_gc.sh"
+  },
+  {
+    "template": "dovecot.conf.j2",
+    "output":   "/etc/dovecot/dovecot.conf"
+  }
+]

+ 6 - 0
data/conf/mysql/config.json

@@ -0,0 +1,6 @@
+[
+  {
+    "template": "my.cnf.j2",
+    "output":   "/etc/mysql/conf.d/my.cnf"
+  }
+]

+ 22 - 0
data/conf/nginx/config.json

@@ -0,0 +1,22 @@
+[
+  {
+    "template": "nginx.conf.j2",
+    "output":   "/etc/nginx/nginx.conf"
+  },
+  {
+    "template": "sites-default.conf.j2",
+    "output":   "/etc/nginx/includes/sites-default.conf"
+  },
+  {
+    "template": "server_name.active.j2",
+    "output":   "/etc/nginx/conf.d/server_name.active"
+  },
+  {
+    "template": "listen_plain.active.j2",
+    "output":   "/etc/nginx/conf.d/listen_plain.active"
+  },
+  {
+    "template": "listen_ssl.active.j2",
+    "output":   "/etc/nginx/conf.d/listen_ssl.active"
+  }
+]

+ 26 - 0
data/conf/phpfpm/config.json

@@ -0,0 +1,26 @@
+[
+  {
+    "template": "opcache-recommended.ini.j2",
+    "output":   "/usr/local/etc/php/conf.d/opcache-recommended.ini"
+  },
+  {
+    "template": "pools.conf.j2",
+    "output":   "/usr/local/etc/php-fpm.d/z-pools.conf"
+  },
+  {
+    "template": "other.ini.j2",
+    "output":   "/usr/local/etc/php/conf.d/zzz-other.ini"
+  },
+  {
+    "template": "upload.ini.j2",
+    "output":   "/usr/local/etc/php/conf.d/upload.ini"
+  },
+  {
+    "template": "session_store.ini.j2",
+    "output":   "/usr/local/etc/php/conf.d/session_store.ini"
+  },
+  {
+    "template": "0081-custom-mailcow.css.j2",
+    "output":   "/web/css/build/0081-custom-mailcow.css"
+  }
+]

+ 110 - 0
data/conf/postfix/config.json

@@ -0,0 +1,110 @@
+[
+  {
+    "template": "aliases.j2",
+    "output":   "/etc/aliases"
+  },
+  {
+    "template": "mysql_relay_ne.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_relay_ne.cf"
+  },
+  {
+    "template": "mysql_relay_recipient_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_relay_recipient_maps.cf"
+  },
+  {
+    "template": "mysql_tls_policy_override_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf"
+  },
+  {
+    "template": "mysql_tls_enforce_in_policy.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_tls_enforce_in_policy.cf"
+  },
+  {
+    "template": "mysql_sender_dependent_default_transport_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_sender_dependent_default_transport_maps.cf"
+  },
+  {
+    "template": "mysql_transport_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_transport_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_resource_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_resource_maps.cf"
+  },
+  {
+    "template": "mysql_sasl_passwd_maps_sender_dependent.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_sender_dependent.cf"
+  },
+  {
+    "template": "mysql_sasl_passwd_maps_transport_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_sasl_passwd_maps_transport_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_alias_domain_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_alias_domain_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_alias_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_alias_maps.cf"
+  },
+  {
+    "template": "mysql_recipient_bcc_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_recipient_bcc_maps.cf"
+  },
+  {
+    "template": "mysql_sender_bcc_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_sender_bcc_maps.cf"
+  },
+  {
+    "template": "mysql_recipient_canonical_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_recipient_canonical_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_domains_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_domains_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_mailbox_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_relay_domain_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_relay_domain_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_sender_acl.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_sender_acl.cf"
+  },
+  {
+    "template": "mysql_mbr_access_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_mbr_access_maps.cf"
+  },
+  {
+    "template": "mysql_virtual_spamalias_maps.cf.j2",
+    "output":   "/opt/postfix/conf/sql/mysql_virtual_spamalias_maps.cf"
+  },
+  {
+    "template": "sni.map.j2",
+    "output":   "/opt/postfix/conf/sni.map"
+  },
+  {
+    "template": "main.cf.j2",
+    "output":   "/opt/postfix/conf/main.cf"
+  },
+  {
+    "template": "dns_blocklists.cf.j2",
+    "output":   "/opt/postfix/conf/dns_blocklists.cf"
+  },
+  {
+    "template": "dns_reply.map.j2",
+    "output":   "/opt/postfix/conf/dns_reply.map"
+  },
+  {
+    "template": "custom_postscreen_whitelist.cidr.j2",
+    "output":   "/opt/postfix/conf/custom_postscreen_whitelist.cidr"
+  },
+  {
+    "template": "custom_transport.pcre.j2",
+    "output":   "/opt/postfix/conf/custom_transport.pcre"
+  }
+]

+ 30 - 0
data/conf/rspamd/config.json

@@ -0,0 +1,30 @@
+[
+  {
+    "template": "mailcow_networks.map.j2",
+    "output":   "/etc/rspamd/custom/mailcow_networks.map"
+  },
+  {
+    "template": "dovecot_trusted.map.j2",
+    "output":   "/etc/rspamd/custom/dovecot_trusted.map"
+  },
+  {
+    "template": "rspamd_trusted.map.j2",
+    "output":   "/etc/rspamd/custom/rspamd_trusted.map"
+  },
+  {
+    "template": "external_services.conf.j2",
+    "output":   "/etc/rspamd/local.d/external_services.conf"
+  },
+  {
+    "template": "redis.conf.j2",
+    "output":   "/etc/rspamd/local.d/redis.conf"
+  },
+  {
+    "template": "dqs-rbl.conf.j2",
+    "output":   "/etc/rspamd/custom/dqs-rbl.conf"
+  },
+  {
+    "template": "worker-controller-password.inc.j2",
+    "output":   "/etc/rspamd/override.d/worker-controller-password.inc"
+  }
+]

+ 10 - 0
data/conf/sogo/config.json

@@ -0,0 +1,10 @@
+[
+  {
+    "template": "sogod.plist.j2",
+    "output":   "/var/lib/sogo/GNUstep/Defaults/sogod.plist"
+  },
+  {
+    "template": "UIxTopnavToolbar.wox.j2",
+    "output":   "/usr/lib/GNUstep/SOGo/Templates/UIxTopnavToolbar.wox"
+  }
+]

+ 1 - 0
docker-compose.yml

@@ -119,6 +119,7 @@ services:
         - ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro,Z
         - ./data/conf/rspamd/rspamd.conf.local:/etc/rspamd/rspamd.conf.local:Z
         - ./data/conf/rspamd/rspamd.conf.override:/etc/rspamd/rspamd.conf.override:Z
+        - ./data/conf/rspamd/config.json:/etc/rspamd/config.json:Z
         - mysql-socket-vol-1:/var/run/mysqld/
         - rspamd-vol-1:/var/lib/rspamd
       restart: always