···
+
WorkingDirectory = cfg.package;
# State directory and mode
StateDirectory = "mastodon";
StateDirectoryMode = "0750";
···
$sudo ${cfg.package}/bin/tootctl "$@"
+
sidekiqUnits = lib.attrsets.mapAttrs' (name: processCfg:
+
lib.nameValuePair "mastodon-sidekiq-${name}" (let
+
jobClassArgs = toString (builtins.map (c: "-q ${c}") processCfg.jobClasses);
+
jobClassLabel = toString ([""] ++ processCfg.jobClasses);
+
threads = toString (if processCfg.threads == null then cfg.sidekiqThreads else processCfg.threads);
+
after = [ "network.target" "mastodon-init-dirs.service" ]
+
++ lib.optional databaseActuallyCreateLocally "postgresql.service"
+
++ lib.optional cfg.automaticMigrations "mastodon-init-db.service";
+
requires = [ "mastodon-init-dirs.service" ]
+
++ lib.optional databaseActuallyCreateLocally "postgresql.service"
+
++ lib.optional cfg.automaticMigrations "mastodon-init-db.service";
+
description = "Mastodon sidekiq${jobClassLabel}";
+
wantedBy = [ "mastodon.target" ];
+
PORT = toString(cfg.sidekiqPort);
+
ExecStart = "${cfg.package}/bin/sidekiq ${jobClassArgs} -c ${threads} -r ${cfg.package}";
+
EnvironmentFile = [ "/var/lib/mastodon/.secrets_env" ] ++ cfg.extraEnvFiles;
+
WorkingDirectory = cfg.package;
+
# System Call Filtering
+
SystemCallFilter = [ ("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2" ];
+
path = with pkgs; [ file imagemagick ffmpeg ];
+
) cfg.sidekiqProcesses;
···
sidekiqThreads = lib.mkOption {
+
description = lib.mdDoc "Worker threads used by the mastodon-sidekiq-all service. If `sidekiqProcesses` is configured and any processes specify null `threads`, this value is used.";
+
sidekiqProcesses = lib.mkOption {
+
description = lib.mdDoc "How many Sidekiq processes should be used to handle background jobs, and which job classes they handle. *Read the [upstream documentation](https://docs.joinmastodon.org/admin/scaling/#sidekiq) before configuring this!*";
+
type = with lib.types; attrsOf (submodule {
+
jobClasses = lib.mkOption {
+
type = listOf (enum [ "default" "push" "pull" "mailers" "scheduler" "ingress" ]);
+
description = lib.mdDoc "If not empty, which job classes should be executed by this process. *Only one process should handle the 'scheduler' class. If left empty, this process will handle the 'scheduler' class.*";
+
threads = lib.mkOption {
+
description = lib.mdDoc "Number of threads this process should use for executing jobs. If null, the configured `sidekiqThreads` are used.";
+
jobClasses = [ "ingress" ];
+
jobClasses = [ "default" ];
+
jobClasses = [ "push" "pull" ];
vapidPublicKeyFile = lib.mkOption {
description = lib.mdDoc ''
Path to file containing the public key used for Web Push
···
+
config = lib.mkIf cfg.enable (lib.mkMerge [{
assertion = databaseActuallyCreateLocally -> (cfg.user == cfg.database.user);
···
environment.systemPackages = [ mastodonTootctl ];
+
systemd.targets.mastodon = {
+
description = "Target for all Mastodon services";
+
wantedBy = [ "multi-user.target" ];
+
after = [ "network.target" ];
systemd.services.mastodon-init-dirs = {
···
+
SyslogIdentifier = "mastodon-init-dirs";
SystemCallFilter = [ ("~" + lib.concatStringsSep " " (systemCallsList ++ [ "@resources" ])) "@chown" "pipe" "pipe2" ];
···
requires = [ "mastodon-init-dirs.service" ]
++ lib.optional databaseActuallyCreateLocally "postgresql.service"
++ lib.optional cfg.automaticMigrations "mastodon-init-db.service";
+
wantedBy = [ "mastodon.target" ];
description = "Mastodon streaming";
environment = env // (if cfg.enableUnixSocket
then { SOCKET = "/run/mastodon-streaming/streaming.socket"; }
···
requires = [ "mastodon-init-dirs.service" ]
++ lib.optional databaseActuallyCreateLocally "postgresql.service"
++ lib.optional cfg.automaticMigrations "mastodon-init-db.service";
+
wantedBy = [ "mastodon.target" ];
description = "Mastodon web";
environment = env // (if cfg.enableUnixSocket
then { SOCKET = "/run/mastodon-web/web.socket"; }
···
path = with pkgs; [ file imagemagick ffmpeg ];
systemd.services.mastodon-media-auto-remove = lib.mkIf cfg.mediaAutoRemove.enable {
description = "Mastodon media auto remove";
···
users.groups.${cfg.group}.members = lib.optional cfg.configureNginx config.services.nginx.user;
+
{ systemd.services = sidekiqUnits; }
meta.maintainers = with lib.maintainers; [ happy-river erictapen ];