{ config, pkgs, lib, ... }: let emailAddress = "mastodon@vhack.eu"; applyPatches = pkg: pkg.overrideAttrs (attrs: { patches = (attrs.patches or []) ++ [./patches/0001-feat-treewide-Increase-character-limit-to-5000-in-me.patch]; }); cfg = config.vhack.mastodon; in { options.vhack.mastodon = { enable = lib.mkEnableOption "a mastodon instance"; domain = lib.mkOption { type = lib.types.str; description = "The Domain mastodon should be served on"; example = "mastodon.vhack.eu"; }; enableTLD = lib.mkEnableOption "using the tld as handle, configured via webfinger (note: this requires the tld to point to the same server as domain)"; tld = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "vhack.eu"; }; }; config = lib.mkIf cfg.enable { age.secrets.mastodonMail = { file = ./mail.age; mode = "700"; owner = "mastodon"; group = "mastodon"; }; vhack.persist.directories = [ { directory = "/var/lib/mastodon"; user = "mastodon"; group = "mastodon"; mode = "0700"; } ]; vhack.postgresql.enable = true; services.mastodon = { enable = true; package = applyPatches pkgs.mastodon; # Unstable Mastodon package, used if # security updates aren't backported. #package = applyPatches pkgs-unstable.mastodon; localDomain = if cfg.enableTLD then cfg.tld else cfg.domain; smtp = { authenticate = true; createLocally = false; fromAddress = emailAddress; user = emailAddress; host = "server1.vhack.eu"; passwordFile = config.age.secrets.mastodonMail.path; }; streamingProcesses = 3; # Number of Cores - 1 extraConfig = { WEB_DOMAIN = cfg.domain; EMAIL_DOMAIN_ALLOWLIST = "vhack.eu|sils.li"; }; }; vhack.nginx.enable = true; services.nginx = { enable = true; recommendedProxySettings = true; # required for redirections to work virtualHosts = { "${cfg.domain}" = { root = "${config.services.mastodon.package}/public/"; # mastodon only supports https, but you can override this if you offload tls elsewhere. forceSSL = true; enableACME = true; locations = { "/system/".alias = "/var/lib/mastodon/public-system/"; "/".tryFiles = "$uri @proxy"; "@proxy" = { proxyPass = "http://unix:/run/mastodon-web/web.socket"; proxyWebsockets = true; }; "/api/v1/streaming/" = { proxyPass = "http://unix:/run/mastodon-streaming/streaming.socket"; proxyWebsockets = true; }; }; }; "${cfg.tld}" = if cfg.enableTLD then { locations."/.well-known/webfinger".return = "301 https://${cfg.domain}$request_uri"; } else {}; }; }; users = { users.mastodon.uid = config.vhack.constants.ids.uids.mastodon; users.redis-mastodon.uid = config.vhack.constants.ids.uids.redis-mastodon; groups.redis-mastodon.gid = config.vhack.constants.ids.gids.redis-mastodon; groups.mastodon = { gid = config.vhack.constants.ids.gids.mastodon; members = [ config.services.nginx.user ]; }; }; }; }