diff --git a/deployment/applications/default.nix b/deployment/applications/default.nix new file mode 100644 index 00000000..ff8ebce1 --- /dev/null +++ b/deployment/applications/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./mastodon.nix + ]; +} diff --git a/deployment/applications/mastodon.nix b/deployment/applications/mastodon.nix new file mode 100644 index 00000000..f848d54c --- /dev/null +++ b/deployment/applications/mastodon.nix @@ -0,0 +1,141 @@ +{ + lib, + pkgs, + config, + ... +}: +{ + applications.mastodon = + { ... }: + { + description = '' + Mastodon: Your self-hosted, globally interconnected microblogging community + ''; + module = + # # usage: + # { + # config.fediversity.domain = lib.mkOption { + # type = lib.types.str; + # default = "fediversity.tld"; + # }; + # } + { lib, config, ... }: + { + options = import ../../../services/fediversity/sharedOptions.nix { + inherit config lib; + serviceName = "mastodon"; + serviceDocName = "Mastodon"; + }; + }; + # this is ported from `services/fediversity/mastodon/default.nix`. what of `services/vm/mastodon-vm.nix`? + implementation = + cfg: + # { + # config, + # lib, + # pkgs, + # ... + # }: + let + inherit (lib) mkIf mkMerge readFile; + inherit (pkgs) writeText; + in + lib.optionalAttrs cfg.enable { + # # not using this part as we split this out in our data model. + # imports = [ ./options.nix ]; + + config = mkMerge [ + (mkIf + (config.fediversity.garage.enable && cfg.s3AccessKeyFile != null && cfg.s3SecretKeyFile != null) + { + fediversity.garage = { + ensureBuckets = { + mastodon = { + website = true; + corsRules = { + enable = true; + allowedHeaders = [ "*" ]; + allowedMethods = [ "GET" ]; + allowedOrigins = [ "*" ]; + }; + }; + }; + + ensureKeys = { + mastodon = { + inherit (cfg) s3AccessKeyFile s3SecretKeyFile; + ensureAccess = { + mastodon = { + read = true; + write = true; + owner = true; + }; + }; + }; + }; + }; + } + ) + + (mkIf cfg.enable { + + services.mastodon.extraConfig = rec { + S3_ENABLED = "true"; + # TODO: this shouldn't be hard-coded, it should come from the garage configuration + S3_ENDPOINT = config.fediversity.garage.api.url; + S3_REGION = "garage"; + S3_BUCKET = "mastodon"; + # use . + S3_OVERRIDE_PATH_STLE = "true"; + S3_PROTOCOL = "http"; + S3_ALIAS_HOST = config.fediversity.garage.web.domainForBucket S3_BUCKET; + # SEE: the last section in https://docs.joinmastodon.org/admin/optional/object-storage/ + # TODO: can we set up ACLs with garage? + S3_PERMISSION = ""; + }; + + ## FIXME: secrets management; we should have a service that writes the + ## `.env` files based on all the secrets that we need to put there. + services.mastodon.extraEnvFiles = [ + (writeText "s3AccessKey" '' + AWS_ACCESS_KEY_ID=${readFile cfg.s3AccessKeyFile} + '') + (writeText "s3SecretKey" '' + AWS_SECRET_ACCESS_KEY=${readFile cfg.s3SecretKeyFile} + '') + ]; + + # open up access to the mastodon web interface. 80 is necessary if only for ACME + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.mastodon = { + enable = true; + + localDomain = cfg.domain; + configureNginx = true; + + # from the documentation: recommended is the amount of your CPU cores minus + # one. but it also must be a positive integer + streamingProcesses = lib.max 1 (config.fediversity.temp.cores - 1); + + # TODO: configure a mailserver so this works + smtp = { + fromAddress = "noreply@${cfg.domain}"; + createLocally = false; + }; + }; + + security.acme = { + acceptTerms = true; + preliminarySelfsigned = true; + # TODO: configure a mailserver so we can set up acme + # defaults.email = "test@example.com"; + }; + }) + ]; + }; + }; +}