Our Personal Data Server from scratch! tranquil.farm
oauth atproto pds rust postgresql objectstorage fun

refactor(nix): toml conf

authored by isabelroses.com and committed by nel.pet 40900348 e6b46987

+63 -73
+63 -73
module.nix
··· 10 10 11 11 inherit (lib) types mkOption; 12 12 13 - backendUrl = "http://127.0.0.1:${toString cfg.settings.SERVER_PORT}"; 13 + settingsFormat = pkgs.formats.toml { }; 14 + 15 + backendUrl = "http://127.0.0.1:${toString cfg.settings.server.port}"; 14 16 15 17 useACME = cfg.nginx.enableACME && cfg.nginx.useACMEHost == null; 16 18 hasSSL = useACME || cfg.nginx.useACMEHost != null; ··· 100 102 101 103 settings = mkOption { 102 104 type = types.submodule { 103 - freeformType = types.attrsOf ( 104 - types.nullOr ( 105 - types.oneOf [ 106 - types.str 107 - types.path 108 - types.int 109 - ] 110 - ) 111 - ); 105 + freeformType = settingsFormat.type; 112 106 113 107 options = { 114 - SERVER_HOST = mkOption { 115 - type = types.str; 116 - default = "127.0.0.1"; 117 - description = "Host for tranquil-pds to listen on"; 118 - }; 119 - 120 - SERVER_PORT = mkOption { 121 - type = types.int; 122 - default = 3000; 123 - description = "Port for tranquil-pds to listen on"; 124 - }; 125 - 126 - PDS_HOSTNAME = mkOption { 127 - type = types.nullOr types.str; 128 - default = null; 129 - example = "pds.example.com"; 130 - description = "The public-facing hostname of the PDS"; 131 - }; 108 + server = { 109 + host = mkOption { 110 + type = types.str; 111 + default = "127.0.0.1"; 112 + description = "Host for tranquil-pds to listen on"; 113 + }; 132 114 133 - BLOB_STORAGE_PATH = mkOption { 134 - type = types.path; 135 - default = "/var/lib/tranquil-pds/blobs"; 136 - description = "Directory for storing blobs"; 137 - }; 115 + port = mkOption { 116 + type = types.int; 117 + default = 3000; 118 + description = "Port for tranquil-pds to listen on"; 119 + }; 138 120 139 - BACKUP_STORAGE_PATH = mkOption { 140 - type = types.path; 141 - default = "/var/lib/tranquil-pds/backups"; 142 - description = "Directory for storing backups"; 143 - }; 121 + hostname = mkOption { 122 + type = types.str; 123 + default = ""; 124 + example = "pds.example.com"; 125 + description = "The public-facing hostname of the PDS"; 126 + }; 144 127 145 - MAIL_FROM_ADDRESS = mkOption { 146 - type = types.nullOr types.str; 147 - default = null; 148 - description = "Email address to use in the From header when sending emails."; 128 + max_blob_size = mkOption { 129 + type = types.int; 130 + default = 10737418240; # 10 GiB 131 + description = "Maximum allowed blob size in bytes."; 132 + }; 149 133 }; 150 134 151 - SENDMAIL_PATH = mkOption { 152 - type = types.path; 153 - default = lib.getExe pkgs.system-sendmail; 154 - description = "Path to the sendmail executable to use for sending emails."; 135 + storage = { 136 + path = mkOption { 137 + type = types.path; 138 + default = "/var/lib/tranquil-pds/blobs"; 139 + description = "Directory for storing blobs"; 140 + }; 155 141 }; 156 142 157 - SIGNAL_SENDER_NUMBER = mkOption { 158 - type = types.nullOr types.str; 159 - default = null; 160 - description = "Phone number (in international format) to use for sending Signal notifications."; 143 + backup = { 144 + path = mkOption { 145 + type = types.path; 146 + default = "/var/lib/tranquil-pds/backups"; 147 + description = "Directory for storing backups"; 148 + }; 161 149 }; 162 150 163 - SIGNAL_CLI_PATH = mkOption { 164 - type = types.path; 165 - default = lib.getExe pkgs.signal-cli; 166 - description = "Path to the signal-cli executable to use for sending Signal notifications."; 151 + email = { 152 + sendmail_path = mkOption { 153 + type = types.path; 154 + default = lib.getExe pkgs.system-sendmail; 155 + description = "Path to the sendmail executable to use for sending emails."; 156 + }; 167 157 }; 168 158 169 - MAX_BLOB_SIZE = mkOption { 170 - type = types.int; 171 - default = 10737418240; # 10 GiB 172 - description = "Maximum allowed blob size in bytes."; 159 + signal = { 160 + cli_path = mkOption { 161 + type = types.path; 162 + default = lib.getExe pkgs.signal-cli; 163 + description = "Path to the signal-cli executable to use for sending Signal notifications."; 164 + }; 173 165 }; 174 166 }; 175 167 }; ··· 198 190 ]; 199 191 }; 200 192 201 - services.tranquil-pds.settings.DATABASE_URL = lib.mkDefault "postgresql:///${cfg.user}?host=/run/postgresql"; 193 + services.tranquil-pds.settings.database.url = 194 + lib.mkDefault "postgresql:///${cfg.user}?host=/run/postgresql"; 202 195 203 196 systemd.services.tranquil-pds = { 204 197 requires = [ "postgresql.service" ]; ··· 210 203 services.nginx = { 211 204 enable = true; 212 205 213 - virtualHosts.${cfg.settings.PDS_HOSTNAME} = { 214 - serverAliases = [ "*.${cfg.settings.PDS_HOSTNAME}" ]; 206 + virtualHosts.${cfg.settings.server.hostname} = { 207 + serverAliases = [ "*.${cfg.settings.server.hostname}" ]; 215 208 forceSSL = hasSSL; 216 209 enableACME = useACME; 217 210 useACMEHost = cfg.nginx.useACMEHost; 218 211 219 212 root = lib.mkIf (cfg.frontend.package != null) cfg.frontend.package; 220 213 221 - extraConfig = "client_max_body_size ${toString cfg.settings.MAX_BLOB_SIZE};"; 214 + extraConfig = "client_max_body_size ${toString cfg.settings.server.max_blob_size};"; 222 215 223 216 locations = lib.mkMerge [ 224 217 { ··· 321 314 lib.genAttrs 322 315 [ 323 316 cfg.dataDir 324 - cfg.settings.BLOB_STORAGE_PATH 325 - cfg.settings.BACKUP_STORAGE_PATH 317 + cfg.settings.storage.path 318 + cfg.settings.backup.path 326 319 ] 327 320 (_: { 328 321 d = { ··· 330 323 inherit (cfg) user group; 331 324 }; 332 325 }); 326 + 327 + environment.etc = { 328 + "tranquil-pds/config.toml".source = settingsFormat.generate "tranquil-pds.toml" cfg.settings; 329 + }; 333 330 334 331 systemd.services.tranquil-pds = { 335 332 description = "Tranquil PDS - AT Protocol Personal Data Server"; ··· 348 345 StateDirectory = "tranquil-pds"; 349 346 350 347 EnvironmentFile = cfg.environmentFiles; 351 - Environment = lib.mapAttrsToList (k: v: "${k}=${if builtins.isInt v then toString v else v}") ( 352 - lib.filterAttrs (k: v: 353 - if k == "SENDMAIL_PATH" then cfg.settings.MAIL_FROM_ADDRESS != null 354 - else if k == "SIGNAL_CLI_PATH" then cfg.settings.SIGNAL_SENDER_NUMBER != null 355 - else v != null 356 - ) cfg.settings 357 - ); 358 348 359 349 NoNewPrivileges = true; 360 350 ProtectSystem = "strict"; ··· 377 367 RemoveIPC = true; 378 368 379 369 ReadWritePaths = [ 380 - cfg.settings.BLOB_STORAGE_PATH 381 - cfg.settings.BACKUP_STORAGE_PATH 370 + cfg.settings.storage.path 371 + cfg.settings.backup.path 382 372 ]; 383 373 }; 384 374 };