Self-host your own digital island
1{ pkgs, config, lib, ... }:
2
3with lib;
4let
5 cfg = config.eilean;
6 domain = config.networking.domain;
7 subdomain = "mastodon.${domain}";
8in {
9 options.eilean.mastodon = { enable = mkEnableOption "mastodon"; };
10
11 config = mkIf cfg.mastodon.enable {
12 services.mastodon = {
13 enable = true;
14 enableUnixSocket = false;
15 webProcesses = 1;
16 webThreads = 3;
17 sidekiqThreads = 5;
18 streamingProcesses = 3;
19 smtp = {
20 #createLocally = false;
21 user = "system@${domain}";
22 port = 465;
23 host = "mail.${domain}";
24 authenticate = true;
25 passwordFile = cfg.mailserver.systemAccountPasswordFile;
26 fromAddress = "mastodon@${domain}";
27 };
28 extraConfig = {
29 # override localDomain
30 LOCAL_DOMAIN = domain;
31 WEB_DOMAIN = subdomain;
32
33 # https://peterbabic.dev/blog/setting-up-smtp-in-mastodon/
34 SMTP_SSL = "true";
35 SMTP_ENABLE_STARTTLS = "false";
36 SMTP_OPENSSL_VERIFY_MODE = "none";
37 };
38 };
39
40 users.groups.${config.services.mastodon.group}.members =
41 [ config.services.nginx.user ];
42
43 security.acme-eon.nginxCerts = lib.mkIf cfg.acme-eon [ subdomain ];
44
45 services.nginx = {
46 enable = true;
47 recommendedProxySettings = true;
48 virtualHosts = {
49 # relies on root domain being set up
50 "${domain}".locations = {
51 "/.well-known/host-meta".extraConfig = ''
52 return 301 https://${subdomain}$request_uri;
53 '';
54 "/.well-known/webfinger".extraConfig = ''
55 return 301 https://${subdomain}$request_uri;
56 '';
57 };
58 "${subdomain}" = {
59 root = "${config.services.mastodon.package}/public/";
60 forceSSL = true;
61 enableACME = lib.mkIf (!cfg.acme-eon) true;
62
63 locations."/system/".alias = "/var/lib/mastodon/public-system/";
64
65 locations."/" = { tryFiles = "$uri @proxy"; };
66
67 locations."@proxy" = {
68 proxyPass = "http://127.0.0.1:${
69 builtins.toString config.services.mastodon.webPort
70 }";
71 proxyWebsockets = true;
72 };
73 };
74 };
75 };
76
77 eilean.dns.enable = true;
78 eilean.services.dns.zones.${config.networking.domain}.records = [{
79 name = "mastodon";
80 type = "CNAME";
81 value = cfg.domainName;
82 }];
83 };
84}