summary refs log tree commit diff
path: root/nixos/modules/services/networking/pleroma.nix
blob: 9b8382392c0a7ee32ecf7b13174fbfe6fc855a0f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{ config, options, lib, pkgs, stdenv, ... }:
let
  cfg = config.services.pleroma;
in {
  options = {
    services.pleroma = with lib; {
      enable = mkEnableOption "pleroma";

      package = mkOption {
        type = types.package;
        default = pkgs.pleroma;
        defaultText = literalExpression "pkgs.pleroma";
        description = "Pleroma package to use.";
      };

      user = mkOption {
        type = types.str;
        default = "pleroma";
        description = "User account under which pleroma runs.";
      };

      group = mkOption {
        type = types.str;
        default = "pleroma";
        description = "Group account under which pleroma runs.";
      };

      stateDir = mkOption {
        type = types.str;
        default = "/var/lib/pleroma";
        readOnly = true;
        description = "Directory where the pleroma service will save the uploads and static files.";
      };

      configs = mkOption {
        type = with types; listOf str;
        description = ''
          Pleroma public configuration.

          This list gets appended from left to
          right into /etc/pleroma/config.exs. Elixir evaluates its
          configuration imperatively, meaning you can override a
          setting by appending a new str to this NixOS option list.

          <emphasis>DO NOT STORE ANY PLEROMA SECRET
          HERE</emphasis>, use
          <link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>
          instead.

          This setting is going to be stored in a file part of
          the Nix store. The Nix store being world-readable, it's not
          the right place to store any secret

          Have a look to Pleroma section in the NixOS manual for more
          informations.
          '';
      };

      secretConfigFile = mkOption {
        type = types.str;
        default = "/var/lib/pleroma/secrets.exs";
        description = ''
          Path to the file containing your secret pleroma configuration.

          <emphasis>DO NOT POINT THIS OPTION TO THE NIX
          STORE</emphasis>, the store being world-readable, it'll
          compromise all your secrets.
        '';
      };
    };
  };

  config = lib.mkIf cfg.enable {
    users = {
      users."${cfg.user}" = {
        description = "Pleroma user";
        home = cfg.stateDir;
        group = cfg.group;
        isSystemUser = true;
      };
      groups."${cfg.group}" = {};
    };

    environment.systemPackages = [ cfg.package ];

    environment.etc."/pleroma/config.exs".text = ''
      ${lib.concatMapStrings (x: "${x}") cfg.configs}

      # The lau/tzdata library is trying to download the latest
      # timezone database in the OTP priv directory by default.
      # This directory being in the store, it's read-only.
      # Setting that up to a more appropriate location.
      config :tzdata, :data_dir, "/var/lib/pleroma/elixir_tzdata_data"

      import_config "${cfg.secretConfigFile}"
    '';

    systemd.services.pleroma = {
      description = "Pleroma social network";
      after = [ "network-online.target" "postgresql.service" ];
      wantedBy = [ "multi-user.target" ];
      restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
      environment.RELEASE_COOKIE = "/var/lib/pleroma/.cookie";
      serviceConfig = {
        User = cfg.user;
        Group = cfg.group;
        Type = "exec";
        WorkingDirectory = "~";
        StateDirectory = "pleroma pleroma/static pleroma/uploads";
        StateDirectoryMode = "700";

        # Checking the conf file is there then running the database
        # migration before each service start, just in case there are
        # some pending ones.
        #
        # It's sub-optimal as we'll always run this, even if pleroma
        # has not been updated. But the no-op process is pretty fast.
        # Better be safe than sorry migration-wise.
        ExecStartPre =
          let preScript = pkgs.writers.writeBashBin "pleromaStartPre" ''
            if [ ! -f /var/lib/pleroma/.cookie ]
            then
              echo "Creating cookie file"
              dd if=/dev/urandom bs=1 count=16 | hexdump -e '16/1 "%02x"' > /var/lib/pleroma/.cookie
            fi
            ${cfg.package}/bin/pleroma_ctl migrate
          '';
          in "${preScript}/bin/pleromaStartPre";

        ExecStart = "${cfg.package}/bin/pleroma start";
        ExecStop = "${cfg.package}/bin/pleroma stop";
        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";

        # Systemd sandboxing directives.
        # Taken from the upstream contrib systemd service at
        # pleroma/installation/pleroma.service
        PrivateTmp = true;
        ProtectHome = true;
        ProtectSystem = "full";
        PrivateDevices = false;
        NoNewPrivileges = true;
        CapabilityBoundingSet = "~CAP_SYS_ADMIN";
      };
    };

  };
  meta.maintainers = with lib.maintainers; [ ninjatrappeur ];
  meta.doc = ./pleroma.xml;
}