263 lines
8.4 KiB
Nix
263 lines
8.4 KiB
Nix
{ pkgs, lib, config, ... }:
|
|
|
|
with lib;
|
|
let
|
|
cfg = config.fudo.chat;
|
|
mattermost-config-target = "/run/chat/mattermost/mattermost-config.json";
|
|
|
|
in {
|
|
options.fudo.chat = with types; {
|
|
enable = mkEnableOption "Enable chat server";
|
|
|
|
hostname = mkOption {
|
|
type = str;
|
|
description = "Hostname at which this chat server is accessible.";
|
|
example = "chat.mydomain.com";
|
|
};
|
|
|
|
site-name = mkOption {
|
|
type = str;
|
|
description = "The name of this chat server.";
|
|
example = "My Fancy Chat Site";
|
|
};
|
|
|
|
smtp = {
|
|
server = mkOption {
|
|
type = str;
|
|
description = "SMTP server to use for sending notification emails.";
|
|
example = "mail.my-site.com";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = str;
|
|
description = "Username with which to connect to the SMTP server.";
|
|
};
|
|
|
|
password-file = mkOption {
|
|
type = str;
|
|
description =
|
|
"Path to a file containing the password to use while connecting to the SMTP server.";
|
|
};
|
|
};
|
|
|
|
state-directory = mkOption {
|
|
type = str;
|
|
description = "Path at which to store server state data.";
|
|
default = "/var/lib/mattermost";
|
|
};
|
|
|
|
database = mkOption {
|
|
type = (submodule {
|
|
options = {
|
|
name = mkOption {
|
|
type = str;
|
|
description = "Database name.";
|
|
};
|
|
|
|
hostname = mkOption {
|
|
type = str;
|
|
description = "Database host.";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = str;
|
|
description = "Database user.";
|
|
};
|
|
|
|
password-file = mkOption {
|
|
type = str;
|
|
description = "Path to file containing database password.";
|
|
};
|
|
};
|
|
});
|
|
description = "Database configuration.";
|
|
example = {
|
|
name = "my_database";
|
|
hostname = "my.database.com";
|
|
user = "db_user";
|
|
password-file = /path/to/some/file.pw;
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable (let
|
|
pkg = pkgs.mattermost;
|
|
default-config = builtins.fromJSON (readFile "${pkg}/config/config.json");
|
|
modified-config = recursiveUpdate default-config {
|
|
ServiceSettings.SiteURL = "https://${cfg.hostname}";
|
|
ServiceSettings.ListenAddress = "127.0.0.1:8065";
|
|
TeamSettings.SiteName = cfg.site-name;
|
|
EmailSettings = {
|
|
RequireEmailVerification = true;
|
|
SMTPServer = cfg.smtp.server;
|
|
SMTPPort = 587;
|
|
EnableSMTPAuth = true;
|
|
SMTPUsername = cfg.smtp.user;
|
|
SMTPPassword = "__SMTP_PASSWD__";
|
|
SendEmailNotifications = true;
|
|
ConnectionSecurity = "STARTTLS";
|
|
FeedbackEmail = "chat@fudo.org";
|
|
FeedbackName = "Admin";
|
|
};
|
|
EnableEmailInvitations = true;
|
|
SqlSettings.DriverName = "postgres";
|
|
SqlSettings.DataSource = "postgres://${
|
|
cfg.database.user
|
|
}:__DATABASE_PASSWORD__@${
|
|
cfg.database.hostname
|
|
}:5432/${
|
|
cfg.database.name
|
|
}";
|
|
};
|
|
mattermost-config-file-template =
|
|
pkgs.writeText "mattermost-config.json.template" (builtins.toJSON modified-config);
|
|
mattermost-user = "mattermost";
|
|
mattermost-group = "mattermost";
|
|
|
|
generate-mattermost-config = target: template: smtp-passwd-file: db-passwd-file:
|
|
pkgs.writeScript "mattermost-config-generator.sh" ''
|
|
SMTP_PASSWD=$( cat ${smtp-passwd-file} )
|
|
DATABASE_PASSWORD=$( cat ${db-passwd-file} )
|
|
sed -e 's/__SMTP_PASSWD__/"$SMTP_PASSWD"/' -e 's/__DATABASE_PASSWORD__/"$DATABASE_PASSWORD"/' ${template} > ${target}
|
|
'';
|
|
|
|
in {
|
|
users = {
|
|
users = {
|
|
${mattermost-user} = {
|
|
isSystemUser = true;
|
|
group = mattermost-group;
|
|
};
|
|
};
|
|
|
|
groups = { ${mattermost-group} = { members = [ mattermost-user ]; }; };
|
|
};
|
|
|
|
fudo.system.services.mattermost = {
|
|
description = "Mattermost Chat Server";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network.target" ];
|
|
|
|
preStart = ''
|
|
${generate-mattermost-config
|
|
mattermost-config-target
|
|
mattermost-config-file-template
|
|
cfg.smtp.password-file
|
|
cfg.database.password-file}
|
|
cp ${cfg.smtp.password-file} ${cfg.state-directory}/config/config.json
|
|
cp -uRL ${pkg}/client ${cfg.state-directory}
|
|
chown ${mattermost-user}:${mattermost-group} ${cfg.state-directory}/client
|
|
chmod 0750 ${cfg.state-directory}/client
|
|
'';
|
|
execStart = "${pkg}/bin/mattermost";
|
|
workingDirectory = cfg.state-directory;
|
|
user = mattermost-user;
|
|
group = mattermost-group;
|
|
};
|
|
|
|
systemd = {
|
|
|
|
tmpfiles.rules = [
|
|
"d ${cfg.state-directory} 0750 ${mattermost-user} ${mattermost-group} - -"
|
|
"d ${cfg.state-directory}/config 0750 ${mattermost-user} ${mattermost-group} - -"
|
|
"L ${cfg.state-directory}/bin - - - - ${pkg}/bin"
|
|
"L ${cfg.state-directory}/fonts - - - - ${pkg}/fonts"
|
|
"L ${cfg.state-directory}/i18n - - - - ${pkg}/i18n"
|
|
"L ${cfg.state-directory}/templates - - - - ${pkg}/templates"
|
|
];
|
|
|
|
# services.mattermost = {
|
|
# description = "Mattermost Chat Server";
|
|
# wantedBy = [ "multi-user.target" ];
|
|
# after = [ "network.target" ];
|
|
|
|
# preStart = ''
|
|
# ${generate-mattermost-config
|
|
# mattermost-config-target
|
|
# mattermost-config-file-template
|
|
# cfg.smtp.password-file
|
|
# cfg.database.password-file}
|
|
# cp ${cfg.smtp.password-file} ${cfg.state-directory}/config/config.json
|
|
# cp -uRL ${pkg}/client ${cfg.state-directory}
|
|
# chown ${mattermost-user}:${mattermost-group} ${cfg.state-directory}/client
|
|
# chmod 0750 ${cfg.state-directory}/client
|
|
# '';
|
|
|
|
# serviceConfig = {
|
|
# PermissionsStartOnly = true;
|
|
# ExecStart = "${pkg}/bin/mattermost";
|
|
# WorkingDirectory = cfg.state-directory;
|
|
# Restart = "always";
|
|
# RestartSec = "10";
|
|
# LimitNOFILE = "49152";
|
|
# User = mattermost-user;
|
|
# Group = mattermost-group;
|
|
# };
|
|
# };
|
|
};
|
|
|
|
services.nginx = {
|
|
enable = true;
|
|
|
|
appendHttpConfig = ''
|
|
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
|
|
'';
|
|
|
|
virtualHosts = {
|
|
"${cfg.hostname}" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8065";
|
|
|
|
extraConfig = ''
|
|
client_max_body_size 50M;
|
|
proxy_set_header Connection "";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Frame-Options SAMEORIGIN;
|
|
proxy_buffers 256 16k;
|
|
proxy_buffer_size 16k;
|
|
proxy_read_timeout 600s;
|
|
proxy_cache mattermost_cache;
|
|
proxy_cache_revalidate on;
|
|
proxy_cache_min_uses 2;
|
|
proxy_cache_use_stale timeout;
|
|
proxy_cache_lock on;
|
|
proxy_http_version 1.1;
|
|
'';
|
|
};
|
|
|
|
locations."~ /api/v[0-9]+/(users/)?websocket$" = {
|
|
proxyPass = "http://127.0.0.1:8065";
|
|
|
|
extraConfig = ''
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
client_max_body_size 50M;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Frame-Options SAMEORIGIN;
|
|
proxy_buffers 256 16k;
|
|
proxy_buffer_size 16k;
|
|
client_body_timeout 60;
|
|
send_timeout 300;
|
|
lingering_timeout 5;
|
|
proxy_connect_timeout 90;
|
|
proxy_send_timeout 300;
|
|
proxy_read_timeout 90s;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
};
|
|
});
|
|
}
|