{ config, lib, pkgs, ... }@toplevel: with lib; let cfg = config.fudo.services.chat; hostname = config.instance.hostname; domain-name = config.instance.local-domain; domain = config.fudo.domains.${domain-name}; chat-server = domain.chat-server; isChatServer = hostname == chat-server; chat-fqdn = "${cfg.host-alias}.${domain-name}"; mail-server = "mail.${domain-name}"; host-ip = "192.168.19.1"; container-ip = "192.168.19.2"; host-secrets = config.fudo.secrets.host-secrets.${hostname}; seed = config.instance.build-seed; mattermost-mail-passwd-file = pkgs.lib.passwd.stablerandom-passwd-file "mattermost-email" seed; in { options.fudo.services.chat = with types; { host-alias = mkOption { type = str; description = "CNAME to use for the chat server."; default = "chat"; }; site-name = mkOption { type = str; description = "Name of the chat site."; default = "Fudo Chat"; }; state-directory = mkOption { type = str; description = "Path at which to store chat server state. Must be persistent."; }; external-interface = mkOption { type = str; description = "Public-facing external interface, for outgoing traffic."; }; }; config = mkIf (chat-server != null) { networking.nat = mkIf isChatServer { enable = true; internalInterfaces = [ "ve-fudo-chat" ]; externalInterface = cfg.external-interface; }; fudo = { users.chat = { uid = 20001; primary-group = "fudo"; common-name = cfg.site-name; ldap-hashed-passwd = pkgs.lib.passwd.hash-ldap-passwd "mattermost-chat" mattermost-mail-passwd-file; }; zones.${domain.zone}.aliases.chat = pkgs.lib.network.host-fqdn config chat-server; }; systemd.tmpfiles.rules = mkIf isChatServer [ "d ${cfg.state-directory}/mattermost 0700 - - - -" "d ${cfg.state-directory}/postgresql 0700 - - - -" ]; services.nginx = mkIf isChatServer { enable = true; recommendedProxySettings = true; virtualHosts."${chat-fqdn}" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://${container-ip}:1234"; proxyWebsockets = true; }; }; }; containers.fudo-chat = mkIf isChatServer { ephemeral = true; privateNetwork = true; hostAddress = host-ip; localAddress = container-ip; autoStart = true; bindMounts = { "/var/lib/mattermost" = { hostPath = "${cfg.state-directory}/mattermost"; isReadOnly = false; }; "/var/lib/postgresql" = { hostPath = "${cfg.state-directory}/postgresql"; isReadOnly = false; }; }; config = { config, lib, ... }: { networking = { defaultGateway = host-ip; firewall.enable = false; }; systemd.tmpfiles.rules = [ "d /var/lib/mattermost 700 ${config.services.mattermost.user} - - -" "d /var/lib/postgresql 700 ${config.systemd.services.postgresql.serviceConfig.User} - - -" ]; services = { postgresql.dataDir = "/var/lib/postgresql"; mattermost = { enable = true; siteUrl = "https://${chat-fqdn}"; siteName = cfg.site-name; statePath = "/var/lib/mattermost"; listenAddress = "${container-ip}:1234"; localDatabaseCreate = true; extraConfig = { EmailSettings = { RequireEmailVerification = true; SMTPServer = mail-server; SMTPPort = "587"; ConnectionSecurity = "STARTTLS"; EnableSMTPAuth = true; SMTPUsername = "chat"; # TODO: Ugh SMTPPassword = readFile mattermost-mail-passwd-file; SendEmailNotifications = true; FeedbackEmail = "chat@${domain-name}"; FeedbackName = cfg.site-name; }; EnableEmailNotifications = true; }; }; }; }; }; }; }