1{ config, options, lib, pkgs, stdenv, ... }:
2let
3 cfg = config.services.pleroma;
4in {
5 options = {
6 services.pleroma = with lib; {
7 enable = mkEnableOption "pleroma";
8
9 package = mkOption {
10 type = types.package;
11 default = pkgs.pleroma-otp;
12 description = "Pleroma package to use.";
13 };
14
15 user = mkOption {
16 type = types.str;
17 default = "pleroma";
18 description = "User account under which pleroma runs.";
19 };
20
21 group = mkOption {
22 type = types.str;
23 default = "pleroma";
24 description = "Group account under which pleroma runs.";
25 };
26
27 stateDir = mkOption {
28 type = types.str;
29 default = "/var/lib/pleroma";
30 readOnly = true;
31 description = "Directory where the pleroma service will save the uploads and static files.";
32 };
33
34 configs = mkOption {
35 type = with types; listOf str;
36 description = ''
37 Pleroma public configuration.
38
39 This list gets appended from left to
40 right into /etc/pleroma/config.exs. Elixir evaluates its
41 configuration imperatively, meaning you can override a
42 setting by appending a new str to this NixOS option list.
43
44 <emphasis>DO NOT STORE ANY PLEROMA SECRET
45 HERE</emphasis>, use
46 <link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>
47 instead.
48
49 This setting is going to be stored in a file part of
50 the Nix store. The Nix store being world-readable, it's not
51 the right place to store any secret
52
53 Have a look to Pleroma section in the NixOS manual for more
54 informations.
55 '';
56 };
57
58 secretConfigFile = mkOption {
59 type = types.str;
60 default = "/var/lib/pleroma/secrets.exs";
61 description = ''
62 Path to the file containing your secret pleroma configuration.
63
64 <emphasis>DO NOT POINT THIS OPTION TO THE NIX
65 STORE</emphasis>, the store being world-readable, it'll
66 compromise all your secrets.
67 '';
68 };
69 };
70 };
71
72 config = lib.mkIf cfg.enable {
73 users = {
74 users."${cfg.user}" = {
75 description = "Pleroma user";
76 home = cfg.stateDir;
77 extraGroups = [ cfg.group ];
78 isSystemUser = true;
79 };
80 groups."${cfg.group}" = {};
81 };
82
83 environment.systemPackages = [ cfg.package ];
84
85 environment.etc."/pleroma/config.exs".text = ''
86 ${lib.concatMapStrings (x: "${x}") cfg.configs}
87
88 # The lau/tzdata library is trying to download the latest
89 # timezone database in the OTP priv directory by default.
90 # This directory being in the store, it's read-only.
91 # Setting that up to a more appropriate location.
92 config :tzdata, :data_dir, "/var/lib/pleroma/elixir_tzdata_data"
93
94 import_config "${cfg.secretConfigFile}"
95 '';
96
97 systemd.services.pleroma = {
98 description = "Pleroma social network";
99 after = [ "network-online.target" "postgresql.service" ];
100 wantedBy = [ "multi-user.target" ];
101 restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
102 serviceConfig = {
103 User = cfg.user;
104 Group = cfg.group;
105 Type = "exec";
106 WorkingDirectory = "~";
107 StateDirectory = "pleroma pleroma/static pleroma/uploads";
108 StateDirectoryMode = "700";
109
110 # Checking the conf file is there then running the database
111 # migration before each service start, just in case there are
112 # some pending ones.
113 #
114 # It's sub-optimal as we'll always run this, even if pleroma
115 # has not been updated. But the no-op process is pretty fast.
116 # Better be safe than sorry migration-wise.
117 ExecStartPre =
118 let preScript = pkgs.writers.writeBashBin "pleromaStartPre"
119 "${cfg.package}/bin/pleroma_ctl migrate";
120 in "${preScript}/bin/pleromaStartPre";
121
122 ExecStart = "${cfg.package}/bin/pleroma start";
123 ExecStop = "${cfg.package}/bin/pleroma stop";
124 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
125
126 # Systemd sandboxing directives.
127 # Taken from the upstream contrib systemd service at
128 # pleroma/installation/pleroma.service
129 PrivateTmp = true;
130 ProtectHome = true;
131 ProtectSystem = "full";
132 PrivateDevices = false;
133 NoNewPrivileges = true;
134 CapabilityBoundingSet = "~CAP_SYS_ADMIN";
135 };
136 };
137
138 };
139 meta.maintainers = with lib.maintainers; [ ninjatrappeur ];
140 meta.doc = ./pleroma.xml;
141}