Our Personal Data Server from scratch!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 247 lines 7.2 kB view raw
1self: { 2 lib, 3 pkgs, 4 config, 5 ... 6}: let 7 cfg = config.services.tranquil-pds; 8 9 inherit (lib) types mkOption; 10 11 settingsFormat = pkgs.formats.toml { }; 12in { 13 _class = "nixos"; 14 15 options.services.tranquil-pds = { 16 enable = lib.mkEnableOption "tranquil-pds AT Protocol personal data server"; 17 18 package = mkOption { 19 type = types.package; 20 default = self.packages.${pkgs.stdenv.hostPlatform.system}.tranquil-pds; 21 defaultText = lib.literalExpression "self.packages.\${pkgs.stdenv.hostPlatform.system}.tranquil-pds"; 22 description = "The tranquil-pds package to use"; 23 }; 24 25 user = mkOption { 26 type = types.str; 27 default = "tranquil-pds"; 28 description = "User under which tranquil-pds runs"; 29 }; 30 31 group = mkOption { 32 type = types.str; 33 default = "tranquil-pds"; 34 description = "Group under which tranquil-pds runs"; 35 }; 36 37 dataDir = mkOption { 38 type = types.str; 39 default = "/var/lib/tranquil-pds"; 40 description = "Working directory for tranquil-pds. Also expected to be used for data (blobs)"; 41 }; 42 43 environmentFiles = mkOption { 44 type = types.listOf types.path; 45 default = [ ]; 46 description = '' 47 File to load environment variables from. Loaded variables override 48 values set in {option}`environment`. 49 50 Use it to set values of `JWT_SECRET`, `DPOP_SECRET` and `MASTER_KEY`. 51 52 Generate these with: 53 ``` 54 openssl rand -base64 48 55 ``` 56 ''; 57 }; 58 59 database.createLocally = mkOption { 60 type = types.bool; 61 default = false; 62 description = '' 63 Create the postgres database and user on the local host. 64 ''; 65 }; 66 67 settings = mkOption { 68 type = types.submodule { 69 freeformType = settingsFormat.type; 70 71 options = { 72 server = { 73 host = mkOption { 74 type = types.str; 75 default = "127.0.0.1"; 76 description = "Host for tranquil-pds to listen on"; 77 }; 78 79 port = mkOption { 80 type = types.int; 81 default = 3000; 82 description = "Port for tranquil-pds to listen on"; 83 }; 84 85 hostname = mkOption { 86 type = types.str; 87 default = ""; 88 example = "pds.example.com"; 89 description = "The public-facing hostname of the PDS"; 90 }; 91 92 max_blob_size = mkOption { 93 type = types.int; 94 default = 10737418240; # 10 GiB 95 description = "Maximum allowed blob size in bytes."; 96 }; 97 }; 98 99 frontend = { 100 enabled = lib.mkEnableOption "serving the frontend from the backend. Disable to serve the frontend manually" 101 // { default = true; }; 102 103 dir = mkOption { 104 type = types.nullOr types.package; 105 default = self.packages.${pkgs.stdenv.hostPlatform.system}.tranquil-frontend; 106 defaultText = lib.literalExpression "self.packages.\${pkgs.stdenv.hostPlatform.system}.tranquil-frontend"; 107 description = "Frontend package to be served by the backend"; 108 }; 109 }; 110 111 storage = { 112 path = mkOption { 113 type = types.path; 114 default = "/var/lib/tranquil-pds/blobs"; 115 description = "Directory for storing blobs"; 116 }; 117 }; 118 119 email = { 120 sendmail_path = mkOption { 121 type = types.path; 122 default = lib.getExe pkgs.system-sendmail; 123 description = "Path to the sendmail executable to use for sending emails."; 124 }; 125 }; 126 }; 127 }; 128 129 description = '' 130 Configuration options to set for the service. Secrets should be 131 specified using {option}`environmentFile`. 132 133 Refer to <https://tangled.org/tranquil.farm/tranquil-pds/blob/main/example.toml> 134 for available configuration options. 135 ''; 136 }; 137 }; 138 139 config = lib.mkIf cfg.enable ( 140 lib.mkMerge [ 141 (lib.mkIf cfg.database.createLocally { 142 services.postgresql = { 143 enable = true; 144 ensureDatabases = [ cfg.user ]; 145 ensureUsers = [ 146 { 147 name = cfg.user; 148 ensureDBOwnership = true; 149 } 150 ]; 151 }; 152 153 services.tranquil-pds.settings.database.url = 154 lib.mkDefault "postgresql:///${cfg.user}?host=/run/postgresql"; 155 156 systemd.services.tranquil-pds = { 157 requires = [ "postgresql.service" ]; 158 after = [ "postgresql.service" ]; 159 }; 160 }) 161 162 { 163 users.users.${cfg.user} = { 164 isSystemUser = true; 165 inherit (cfg) group; 166 home = cfg.dataDir; 167 }; 168 169 users.groups.${cfg.group} = { }; 170 171 systemd.tmpfiles.settings."tranquil-pds" = 172 lib.genAttrs 173 [ 174 cfg.dataDir 175 cfg.settings.storage.path 176 ] 177 (_: { 178 d = { 179 mode = "0750"; 180 inherit (cfg) user group; 181 }; 182 }); 183 184 environment.etc = { 185 "tranquil-pds/config.toml".source = settingsFormat.generate "tranquil-pds.toml" cfg.settings; 186 }; 187 188 systemd.services.tranquil-pds = { 189 description = "Tranquil PDS - AT Protocol Personal Data Server"; 190 after = [ "network-online.target" ]; 191 wants = [ "network-online.target" ]; 192 wantedBy = [ "multi-user.target" ]; 193 194 serviceConfig = { 195 User = cfg.user; 196 Group = cfg.group; 197 UMask = "0077"; 198 ExecStart = lib.getExe cfg.package; 199 Restart = "on-failure"; 200 RestartSec = 5; 201 202 WorkingDirectory = cfg.dataDir; 203 StateDirectory = "tranquil-pds"; 204 ReadWritePaths = [ 205 cfg.settings.storage.path 206 ]; 207 208 EnvironmentFile = cfg.environmentFiles; 209 210 CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; 211 ProtectProc = "invisible"; 212 ProcSubset = "pid"; 213 NoNewPrivileges = true; 214 ProtectSystem = "strict"; 215 ProtectHome = true; 216 PrivateTmp = true; 217 PrivateDevices = true; 218 PrivateUsers = true; 219 ProtectHostname = true; 220 ProtectClock = true; 221 ProtectKernelTunables = true; 222 ProtectKernelModules = true; 223 ProtectKernelLogs = true; 224 ProtectControlGroups = true; 225 RestrictAddressFamilies = [ 226 "AF_INET" 227 "AF_INET6" 228 "AF_UNIX" 229 ]; 230 RestrictNamespaces = true; 231 LockPersonality = true; 232 MemoryDenyWriteExecute = true; 233 RestrictRealtime = true; 234 RestrictSUIDSGID = true; 235 RemoveIPC = true; 236 PrivateMounts = true; 237 SystemCallFilter = [ 238 "@system-service" 239 "~@privileged @resources" 240 ]; 241 SystemCallArchitectures = "native"; 242 }; 243 }; 244 } 245 ] 246 ); 247}