Personal-use NixOS configuration
0
fork

Configure Feed

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

Initial `index` implementation

encode42 1e65c9e9 7ada4e50

+2323 -40
+59 -40
flake.lock
··· 36 36 "type": "github" 37 37 } 38 38 }, 39 + "emby-flake": { 40 + "inputs": { 41 + "nixpkgs": "nixpkgs" 42 + }, 43 + "locked": { 44 + "lastModified": 1756077204, 45 + "narHash": "sha256-HPq6oCTriMhgtujE19/79lVG+ruddao4UjB9UgsEQP0=", 46 + "owner": "tofu-salad", 47 + "repo": "emby-server-flake", 48 + "rev": "94da69b906d6a28a8142ad43f7775f75a4bb25d6", 49 + "type": "github" 50 + }, 51 + "original": { 52 + "owner": "tofu-salad", 53 + "repo": "emby-server-flake", 54 + "type": "github" 55 + } 56 + }, 39 57 "firefox-addons": { 40 58 "inputs": { 41 59 "nixpkgs": [ ··· 44 62 }, 45 63 "locked": { 46 64 "dir": "pkgs/firefox-addons", 47 - "lastModified": 1756267413, 48 - "narHash": "sha256-6U8w5ekYCkSl+abrWoZbMRIJh38pjO2zCQsLxhh9ea4=", 65 + "lastModified": 1757131407, 66 + "narHash": "sha256-AlCnmivsXeZAiDz0b0n/HsYx6ccowNATAilNxLMFgeM=", 49 67 "owner": "rycee", 50 68 "repo": "nur-expressions", 51 - "rev": "cfca2aacacfd57476bd4137033e1b181ed239dff", 69 + "rev": "102a040fa2e745daf670819aac53d1f6f73635af", 52 70 "type": "gitlab" 53 71 }, 54 72 "original": { ··· 210 228 ] 211 229 }, 212 230 "locked": { 213 - "lastModified": 1756245065, 214 - "narHash": "sha256-aAZNbGcWrVRZgWgkQbkabSGcDVRDMgON4BipMy69gvI=", 231 + "lastModified": 1756679287, 232 + "narHash": "sha256-Xd1vOeY9ccDf5VtVK12yM0FS6qqvfUop8UQlxEB+gTQ=", 215 233 "owner": "nix-community", 216 234 "repo": "home-manager", 217 - "rev": "54b2879ce622d44415e727905925e21b8f833a98", 235 + "rev": "07fc025fe10487dd80f2ec694f1cd790e752d0e8", 218 236 "type": "github" 219 237 }, 220 238 "original": { ··· 295 313 "xwayland-satellite-unstable": "xwayland-satellite-unstable" 296 314 }, 297 315 "locked": { 298 - "lastModified": 1756264663, 299 - "narHash": "sha256-CgWMOS7RqNLgR+p6mTiQ0mi5vqXJqe+4lLAbjN49DsE=", 316 + "lastModified": 1757071535, 317 + "narHash": "sha256-I3ppQKxd2oxQfwMCW04TSWnIwp5an5kTMY+tx0W8jaA=", 300 318 "owner": "sodiboo", 301 319 "repo": "niri-flake", 302 - "rev": "d1fcac50c77d374240fe49042d0e19a34b0597da", 320 + "rev": "efa08fc58d7da5be64cfebc52b7dc44bf8d19ba9", 303 321 "type": "github" 304 322 }, 305 323 "original": { ··· 311 329 "niri-stable": { 312 330 "flake": false, 313 331 "locked": { 314 - "lastModified": 1748151941, 315 - "narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=", 332 + "lastModified": 1756556321, 333 + "narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=", 316 334 "owner": "YaLTeR", 317 335 "repo": "niri", 318 - "rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7", 336 + "rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294", 319 337 "type": "github" 320 338 }, 321 339 "original": { 322 340 "owner": "YaLTeR", 323 - "ref": "v25.05.1", 341 + "ref": "v25.08", 324 342 "repo": "niri", 325 343 "type": "github" 326 344 } ··· 328 346 "niri-unstable": { 329 347 "flake": false, 330 348 "locked": { 331 - "lastModified": 1756240937, 332 - "narHash": "sha256-KdC5owCAE+U4f5cyTsgL0mFKL4Bz2VhuFqFjlxPAEUA=", 349 + "lastModified": 1756926064, 350 + "narHash": "sha256-5/1vyFRLvJWxhBgpPaV2orC0pjSgIny6JM6+joLyZok=", 333 351 "owner": "YaLTeR", 334 352 "repo": "niri", 335 - "rev": "7cbb6288c3ea3009daf6cc95d5d12d47a33d8fed", 353 + "rev": "c69464c1288789020d9a086f86c970a7dc49b8c7", 336 354 "type": "github" 337 355 }, 338 356 "original": { ··· 350 368 "systems": "systems_2" 351 369 }, 352 370 "locked": { 353 - "lastModified": 1756137620, 354 - "narHash": "sha256-TmvHQCBNA5dSaFkO0jH8iFCpRdXhSLrEaT3uwZ159BI=", 371 + "lastModified": 1756535359, 372 + "narHash": "sha256-XNhW99b7aG+HpT2pIokbU68k911Ok/qUKCaWAB2UUfY=", 355 373 "owner": "theCapypara", 356 374 "repo": "nix-jetbrains-plugins", 357 - "rev": "70c59381b2c303a3ef8bc7a51298846c7017b2a2", 375 + "rev": "ef476a789cadeac91dec6e7965d873c0d9905ba6", 358 376 "type": "github" 359 377 }, 360 378 "original": { ··· 372 390 ] 373 391 }, 374 392 "locked": { 375 - "lastModified": 1756257722, 376 - "narHash": "sha256-VqQpU4H6gTSFvhz1CsvmrdYH4JOefSKuxp9xVDUF8gc=", 393 + "lastModified": 1757121435, 394 + "narHash": "sha256-PmhZWQh/RBlqCfIJPRePD++nAXkByixlnUNwtIFTFNA=", 377 395 "owner": "kaylorben", 378 396 "repo": "nixcord", 379 - "rev": "7fedaf5f9c2506b2b810c92732ba8103e451944c", 397 + "rev": "0d467edfdb65341a5dff9d3e0419cd3ddc3c0c58", 380 398 "type": "github" 381 399 }, 382 400 "original": { ··· 387 405 }, 388 406 "nixos-hardware": { 389 407 "locked": { 390 - "lastModified": 1756245047, 391 - "narHash": "sha256-9bHzrVbjAudbO8q4vYFBWlEkDam31fsz0J7GB8k4AsI=", 408 + "lastModified": 1757103352, 409 + "narHash": "sha256-PtT7ix43ss8PONJ1VJw3f6t2yAoGH+q462Sn8lrmWmk=", 392 410 "owner": "NixOS", 393 411 "repo": "nixos-hardware", 394 - "rev": "a65b650d6981e23edd1afa1f01eb942f19cdcbb7", 412 + "rev": "11b2a10c7be726321bb854403fdeec391e798bf0", 395 413 "type": "github" 396 414 }, 397 415 "original": { ··· 450 468 }, 451 469 "nixpkgs-stable_2": { 452 470 "locked": { 453 - "lastModified": 1755922037, 454 - "narHash": "sha256-wY1+2JPH0ZZC4BQefoZw/k+3+DowFyfOxv17CN/idKs=", 471 + "lastModified": 1757020766, 472 + "narHash": "sha256-PLoSjHRa2bUbi1x9HoXgTx2AiuzNXs54c8omhadyvp0=", 455 473 "owner": "NixOS", 456 474 "repo": "nixpkgs", 457 - "rev": "b1b3291469652d5a2edb0becc4ef0246fff97a7c", 475 + "rev": "fe83bbdde2ccdc2cb9573aa846abe8363f79a97a", 458 476 "type": "github" 459 477 }, 460 478 "original": { ··· 466 484 }, 467 485 "nixpkgs-unstable": { 468 486 "locked": { 469 - "lastModified": 1756125398, 470 - "narHash": "sha256-XexyKZpf46cMiO5Vbj+dWSAXOnr285GHsMch8FBoHbc=", 487 + "lastModified": 1756787288, 488 + "narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=", 471 489 "owner": "NixOS", 472 490 "repo": "nixpkgs", 473 - "rev": "3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5", 491 + "rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1", 474 492 "type": "github" 475 493 }, 476 494 "original": { ··· 482 500 }, 483 501 "nixpkgs_2": { 484 502 "locked": { 485 - "lastModified": 1756125398, 486 - "narHash": "sha256-XexyKZpf46cMiO5Vbj+dWSAXOnr285GHsMch8FBoHbc=", 503 + "lastModified": 1756787288, 504 + "narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=", 487 505 "owner": "NixOS", 488 506 "repo": "nixpkgs", 489 - "rev": "3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5", 507 + "rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1", 490 508 "type": "github" 491 509 }, 492 510 "original": { ··· 498 516 }, 499 517 "nixpkgs_3": { 500 518 "locked": { 501 - "lastModified": 1755922037, 502 - "narHash": "sha256-wY1+2JPH0ZZC4BQefoZw/k+3+DowFyfOxv17CN/idKs=", 519 + "lastModified": 1757020766, 520 + "narHash": "sha256-PLoSjHRa2bUbi1x9HoXgTx2AiuzNXs54c8omhadyvp0=", 503 521 "owner": "NixOS", 504 522 "repo": "nixpkgs", 505 - "rev": "b1b3291469652d5a2edb0becc4ef0246fff97a7c", 523 + "rev": "fe83bbdde2ccdc2cb9573aa846abe8363f79a97a", 506 524 "type": "github" 507 525 }, 508 526 "original": { ··· 542 560 "root": { 543 561 "inputs": { 544 562 "disko": "disko", 563 + "emby-flake": "emby-flake", 545 564 "firefox-addons": "firefox-addons", 546 565 "home-manager": "home-manager", 547 566 "lanzaboote": "lanzaboote", ··· 625 644 "xwayland-satellite-unstable": { 626 645 "flake": false, 627 646 "locked": { 628 - "lastModified": 1756260173, 629 - "narHash": "sha256-wcf04fl5ncbOqAK7OCWIgILERIbMfL/eeM3UThqgErI=", 647 + "lastModified": 1756869116, 648 + "narHash": "sha256-SGcqX3amLH4xiA+dwF2Fu2mt1O8zHc60v0+NEZGDJhw=", 630 649 "owner": "Supreeeme", 631 650 "repo": "xwayland-satellite", 632 - "rev": "af33f7eb124b51ff6d9cdf9b428643e2246c8cbb", 651 + "rev": "41e865c8d35468c67b991ef5a245a98b3e44108c", 633 652 "type": "github" 634 653 }, 635 654 "original": {
+5
flake.nix
··· 56 56 57 57 inputs.nixpkgs.follows = "nixpkgs-unstable"; 58 58 }; 59 + 60 + # Server packages 61 + emby-flake = { 62 + url = "github:tofu-salad/emby-server-flake"; 63 + }; 59 64 }; 60 65 61 66 outputs = args: import ./outputs.nix args;
+11
hosts/index/config/databases/mysql.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + { 4 + imports = [ 5 + (flakeRoot + /packages/server/databases/mysql.nix) 6 + ]; 7 + 8 + services.mysql = { 9 + dataDir = "/mnt/apps/mariadb"; 10 + }; 11 + }
+11
hosts/index/config/databases/postgresql.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + { 4 + imports = [ 5 + (flakeRoot + /packages/server/databases/postgresql.nix) 6 + ]; 7 + 8 + services.postgresql = { 9 + dataDir = "/mnt/apps/postgres/data"; 10 + }; 11 + }
+45
hosts/index/config/groupware/maddy.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + domain = "encrypted.group"; 5 + 6 + maddyModule = import (flakeRoot + /packages/server/groupware/maddy.nix) { 7 + inherit domain; 8 + 9 + email = "postmaster@${domain}"; 10 + }; 11 + 12 + autoconfigModule = import (flakeRoot + /packages/server/groupware/autoconfig.nix) { 13 + inherit domain; 14 + 15 + hosts = [ 16 + { 17 + name = "autoconfig.${domain}"; 18 + ssl = "cloudflare"; 19 + } 20 + ]; 21 + }; 22 + in 23 + { 24 + imports = [ 25 + maddyModule 26 + autoconfigModule 27 + ]; 28 + 29 + services.maddy = { 30 + hostname = domain; 31 + 32 + localDomains = [ 33 + "erora.live" 34 + "encode42.dev" 35 + ]; 36 + 37 + secrets = [ 38 + "/mnt/apps/maddy/secrets/cloudflare_token.env" 39 + ]; 40 + }; 41 + 42 + services.rspamd-trainer.secrets = [ 43 + "/mnt/apps/rspamd/.rspamd-trainer.env" 44 + ]; 45 + }
+25
hosts/index/config/media/audiobookshelf.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + audiobookshelfModule = import (flakeRoot + /packages/server/media/audiobookshelf.nix) { 5 + hosts = [ 6 + { 7 + name = "audiobookshelf.lan"; 8 + ssl = "internal"; 9 + } 10 + { 11 + name = "read.encrypted.group"; 12 + ssl = "cloudflare"; 13 + } 14 + ]; 15 + }; 16 + in 17 + { 18 + imports = [ 19 + audiobookshelfModule 20 + ]; 21 + 22 + services.audiobookshelf = { 23 + dataDir = "/mnt/apps/audiobookshelf"; 24 + }; 25 + }
+23
hosts/index/config/media/emby.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + { 4 + imports = [ 5 + (flakeRoot + /packages/server/media/emby.nix) 6 + { 7 + hosts = [ 8 + { 9 + name = "emby.lan"; 10 + ssl = "internal"; 11 + } 12 + { 13 + name = "watch.encrypted.group"; 14 + ssl = "cloudflare"; 15 + } 16 + ]; 17 + } 18 + ]; 19 + 20 + services.emby = { 21 + dataDir = "/mnt/apps/emby"; 22 + }; 23 + }
+30
hosts/index/config/media/navidrome.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + navidromeModule = import (flakeRoot + /packages/server/media/navidrome.nix) { 5 + hosts = [ 6 + { 7 + name = "navidrome.lan"; 8 + ssl = "internal"; 9 + } 10 + { 11 + name = "listen.encrypted.group"; 12 + ssl = "cloudflare"; 13 + } 14 + ]; 15 + }; 16 + in 17 + { 18 + imports = [ 19 + navidromeModule 20 + ]; 21 + 22 + services.navidrome = { 23 + settings = { 24 + DataFolder = "/mnt/apps/navidrome"; 25 + MusicFolder = "/mnt/data/media/Music"; # TODO 26 + }; 27 + 28 + environmentFile = "/mnt/apps/navidrome/navidrome.env"; 29 + }; 30 + }
+24
hosts/index/config/torrenting/rtorrent.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + floodModule = import (flakeRoot + /packages/server/torrenting/flood.nix) { 5 + hosts = [ 6 + { 7 + name = "rtorrent.lan"; 8 + ssl = "internal"; 9 + } 10 + ]; 11 + }; 12 + in 13 + { 14 + imports = [ 15 + (flakeRoot + /packages/server/torrenting/rtorrent.nix) 16 + 17 + floodModule 18 + ]; 19 + 20 + services.rtorrent = { 21 + dataDir = "/mnt/apps/rtorrent"; 22 + downloadDir = "/mnt/data/rtorrent/downloads"; 23 + }; 24 + }
+36
hosts/index/config/torrenting/soulseek.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + soulseekModule = import (flakeRoot + /packages/server/torrenting/soulseek.nix) { 5 + hosts = [ 6 + { 7 + name = "soulseek.lan"; 8 + ssl = "internal"; 9 + } 10 + ]; 11 + }; 12 + in 13 + { 14 + imports = [ 15 + soulseekModule 16 + ]; 17 + 18 + services.slskd = { 19 + settings = { 20 + instance_name = "index"; 21 + 22 + directories = { 23 + incomplete = "/mnt/data/soulseek/incomplete"; 24 + downloads = "/mnt/data/soulseek/downloads"; 25 + }; 26 + 27 + shares = { 28 + directories = [ 29 + "[Music]/mnt/data/media/Music" # TODO 30 + ]; 31 + }; 32 + }; 33 + 34 + environmentFile = "/mnt/apps/soulseek/soulseek.env"; 35 + }; 36 + }
+16
hosts/index/config/web/caddy.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + caddyModule = import (flakeRoot + /packages/server/caddy) { 5 + email = "postmaster@encrypted.group"; 6 + }; 7 + in 8 + { 9 + imports = [ 10 + caddyModule 11 + ]; 12 + 13 + services.caddy = { 14 + environmentFile = "/mnt/apps/caddy/caddy.env"; 15 + }; 16 + }
+63
hosts/index/config/web/forgejo.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + host = "git.encrypted.group"; 5 + 6 + forgejoModule = import (flakeRoot + /packages/server/web/forgejo.nix) { 7 + hosts = [ 8 + { 9 + name = "forgejo.lan"; 10 + ssl = "internal"; 11 + } 12 + { 13 + name = host; 14 + ssl = "cloudflare"; 15 + } 16 + ]; 17 + }; 18 + in 19 + { 20 + imports = [ 21 + forgejoModule 22 + ]; 23 + 24 + services.forgejo = { 25 + stateDir = "/mnt/apps/forgejo"; 26 + 27 + repositoryRoot = "/mnt/data/forgejo/repos"; 28 + lfs.contentDir = "/mnt/data/forgejo/lfs"; 29 + 30 + settings = { 31 + DEFAULT = { 32 + APP_NAME = "encrypted group forge"; 33 + }; 34 + 35 + service = { 36 + NO_REPLY_ADDRESS = "noreply.${host}"; 37 + }; 38 + 39 + mailer = { 40 + FROM = "git@encrypted.group"; 41 + SMTP_PORT = 465; 42 + }; 43 + 44 + server = { 45 + DOMAIN = "${host}"; 46 + ROOT_URL = "https://${host}"; 47 + }; 48 + }; 49 + 50 + secrets = { 51 + service = { 52 + CF_TURNSTILE_SITEKEY = "/mnt/apps/forgejo/secrets/turnstile_sitekey.env"; 53 + CF_TURNSTILE_SECRET = "/mnt/apps/forgejo/secrets/turnstile_secret.env"; 54 + }; 55 + 56 + mailer = { 57 + SMTP_ADDR = "/mnt/apps/forgejo/secrets/smtp_address.env"; 58 + USER = "/mnt/apps/forgejo/secrets/smtp_user.env"; 59 + PASSWD = "/mnt/apps/forgejo/secrets/smtp_password.env"; 60 + }; 61 + }; 62 + }; 63 + }
+23
hosts/index/config/web/miniflux.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + minifluxModule = import (flakeRoot + /packages/server/web/miniflux.nix) { 5 + hosts = [ 6 + { 7 + name = "miniflux.lan"; 8 + ssl = "internal"; 9 + } 10 + { 11 + name = "feed.encrypted.group"; 12 + ssl = "cloudflare"; 13 + } 14 + ]; 15 + }; 16 + in 17 + { 18 + imports = [ 19 + minifluxModule 20 + ]; 21 + 22 + services.miniflux.adminCredentialsFile = "/mnt/apps/miniflux/.miniflux.env"; 23 + }
+37
hosts/index/config/web/searx.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + host = "search.encrypted.group"; 5 + 6 + searxModule = import (flakeRoot + /packages/server/web/searx.nix) { 7 + hosts = [ 8 + { 9 + name = "searx.lan"; 10 + ssl = "internal"; 11 + } 12 + { 13 + name = host; 14 + ssl = "cloudflare"; 15 + } 16 + ]; 17 + }; 18 + in 19 + { 20 + imports = [ 21 + searxModule 22 + ]; 23 + 24 + services.searx = { 25 + environmentFile = "/mnt/apps/searx/searx.env"; 26 + 27 + settings = { 28 + general = { 29 + instance_name = "encrypted group search"; 30 + }; 31 + 32 + server = { 33 + base_url = "https://${host}"; 34 + }; 35 + }; 36 + }; 37 + }
+37
hosts/index/config/web/vaultwarden.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + host = "vault.encrypted.group"; 5 + 6 + vaultwardenModule = import (flakeRoot + /packages/server/web/vaultwarden.nix) { 7 + hosts = [ 8 + { 9 + name = "vaultwarden.lan"; 10 + ssl = "internal"; 11 + } 12 + { 13 + name = host; 14 + ssl = "cloudflare"; 15 + } 16 + ]; 17 + }; 18 + in 19 + { 20 + imports = [ 21 + vaultwardenModule 22 + ]; 23 + 24 + services.vaultwarden = { 25 + config = { 26 + DOMAIN = "https://${host}"; 27 + INVITATION_ORG_NAME = "encrypted group vault"; 28 + 29 + DATA_FOLDER = "/mnt/apps/vaultwarden"; 30 + 31 + ATTACHMENTS_FOLDER = "/mnt/data/vaultwarden/attachments"; 32 + SENDS_FOLDER = "/mnt/data/vaultwarden/sends"; 33 + }; 34 + 35 + environmentFile = "/mnt/apps/vaultwarden/vaultwarden.env"; # TODO: Make sure to swap out 36 + }; 37 + }
+21
hosts/index/config/web/wakapi.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + let 4 + wakapiModule = import (flakeRoot + /packages/server/web/wakapi.nix) { 5 + hosts = [ 6 + { 7 + name = "wakapi.lan"; 8 + ssl = "internal"; 9 + } 10 + ]; 11 + }; 12 + in 13 + { 14 + imports = [ 15 + wakapiModule 16 + ]; 17 + 18 + services.wakapi = { 19 + passwordSaltFile = "/mnt/apps/wakapi/wakapi.env"; 20 + }; 21 + }
+49
hosts/index/config/zfs.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + { 4 + imports = [ 5 + (flakeRoot + /modules/server/zfs.nix) 6 + ]; 7 + 8 + networking.hostId = "c864ff4e"; 9 + 10 + boot.zfs.extraPools = [ 11 + "apps" 12 + "data" 13 + ]; 14 + 15 + services.sanoid = { 16 + datasets = { 17 + # User data 18 + "data/pydio" = { 19 + useTemplate = [ "hourly" ]; 20 + }; 21 + 22 + "data/immich" = { 23 + useTemplate = [ "hourly" ]; 24 + }; 25 + 26 + "data/vaultwarden" = { 27 + useTemplate = [ "hourly" ]; 28 + }; 29 + 30 + # App data 31 + "apps/pydio" = { 32 + useTemplate = [ "daily" ]; 33 + }; 34 + 35 + "apps/vaultwarden" = { 36 + useTemplate = [ "daily" ]; 37 + }; 38 + 39 + # Databases 40 + "apps/postgresql" = { 41 + useTemplate = [ "vital" ]; 42 + }; 43 + 44 + "apps/mariadb" = { 45 + useTemplate = [ "vital" ]; 46 + }; 47 + }; 48 + }; 49 + }
+54
hosts/index/default.nix
··· 1 + { 2 + flakeRoot, 3 + nixos-hardware, 4 + pkgs, 5 + ... 6 + }: 7 + 8 + { 9 + imports = [ 10 + nixos-hardware.nixosModules.common-pc-ssd 11 + ./hardware-configuration.nix 12 + (flakeRoot + /hardware/cpu/amd.nix) 13 + (flakeRoot + /hardware/gpu/amd.nix) 14 + 15 + (flakeRoot + /modules/common) 16 + (flakeRoot + /modules/common/boot/systemd-boot.nix) 17 + 18 + #(flakeRoot + /modules/server/nfs.nix) 19 + (flakeRoot + /modules/server/openssh.nix) 20 + 21 + ./config/zfs.nix 22 + 23 + #./config/databases/mysql.nix 24 + #./config/databases/postgresql.nix 25 + 26 + #./config/groupware/maddy.nix 27 + 28 + #./config/media/audiobookshelf.nix 29 + #./config/media/emby.nix 30 + #./config/media/navidrome.nix 31 + 32 + #./config/torrenting/rtorrent.nix 33 + #./config/torrenting/soulseek.nix 34 + 35 + #./config/web/caddy.nix 36 + #./config/web/forgejo.nix 37 + #./config/web/miniflux.nix 38 + #./config/web/searx.nix 39 + #./config/web/vaultwarden.nix 40 + #./config/web/wakapi.nix 41 + 42 + ./users 43 + ]; 44 + 45 + # TODO: 46 + # - cells 47 + # - omnipoly 48 + 49 + boot.kernelPackages = pkgs.linuxPackages_hardened; 50 + 51 + time.timeZone = "US/Eastern"; 52 + 53 + system.stateVersion = "24.11"; 54 + }
+58
hosts/index/hardware-configuration.nix
··· 1 + # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 + # and may be overwritten by future invocations. Please make changes 3 + # to /etc/nixos/configuration.nix instead. 4 + { 5 + config, 6 + lib, 7 + pkgs, 8 + modulesPath, 9 + ... 10 + }: 11 + 12 + { 13 + imports = [ 14 + (modulesPath + "/installer/scan/not-detected.nix") 15 + ]; 16 + 17 + boot.initrd.availableKernelModules = [ 18 + "nvme" 19 + "mpt3sas" 20 + "xhci_pci" 21 + "ahci" 22 + "usbhid" 23 + "usb_storage" 24 + "sd_mod" 25 + "sr_mod" 26 + ]; 27 + boot.initrd.kernelModules = [ ]; 28 + boot.kernelModules = [ "kvm-amd" ]; 29 + boot.extraModulePackages = [ ]; 30 + 31 + fileSystems."/" = { 32 + device = "/dev/disk/by-uuid/5dbd27ba-b737-4452-bdf6-702941c023a0"; 33 + fsType = "xfs"; 34 + }; 35 + 36 + fileSystems."/boot" = { 37 + device = "/dev/disk/by-uuid/1857-DC29"; 38 + fsType = "vfat"; 39 + options = [ 40 + "fmask=0077" 41 + "dmask=0077" 42 + ]; 43 + }; 44 + 45 + swapDevices = [ ]; 46 + 47 + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 48 + # (the default) this is the recommended approach. When using systemd-networkd it's 49 + # still possible to use this option, but it's recommended to use it in conjunction 50 + # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. 51 + networking.useDHCP = lib.mkDefault true; 52 + # networking.interfaces.enp7s0.useDHCP = lib.mkDefault true; 53 + # networking.interfaces.enp9s0.useDHCP = lib.mkDefault true; 54 + # networking.interfaces.wlo1.useDHCP = lib.mkDefault true; 55 + 56 + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 57 + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 58 + }
+20
hosts/index/homes/encode42.nix
··· 1 + { 2 + flakeRoot, 3 + pkgs, 4 + pkgs-unstable, 5 + ... 6 + }: 7 + 8 + { 9 + imports = [ 10 + (flakeRoot + /homes/encode42/common) 11 + 12 + (flakeRoot + /homes/encode42/common/github.nix) 13 + (flakeRoot + /homes/encode42/common/direnv.nix) 14 + ]; 15 + 16 + home.packages = with pkgs; [ 17 + cyanrip 18 + pkgs-unstable.makemkv 19 + ]; 20 + }
+9
hosts/index/users/default.nix
··· 1 + { flakeRoot, ... }: 2 + 3 + { 4 + imports = [ 5 + (flakeRoot + /modules/desktop/home-manager.nix) 6 + 7 + ./encode42.nix 8 + ]; 9 + }
+26
hosts/index/users/encode42.nix
··· 1 + { 2 + lib, 3 + flakeRoot, 4 + pkgs, 5 + ... 6 + }: 7 + 8 + { 9 + imports = [ 10 + (flakeRoot + /users/encode42/common) 11 + ]; 12 + 13 + home-manager.users.encode42 = { 14 + imports = [ 15 + ../homes/encode42.nix 16 + ]; 17 + 18 + home.stateVersion = "24.11"; 19 + }; 20 + 21 + users.users.encode42.extraGroups = [ 22 + "wheel" 23 + "cdrom" 24 + "optical" 25 + ]; 26 + }
+2
lib/default.nix
··· 4 4 customJetbrainsPackage = import ./customJetbrainsPackage.nix { 5 5 inherit nix-jetbrains-plugins pkgs; 6 6 }; 7 + 8 + mkProxies = import ./mkProxies.nix; 7 9 }
+21
lib/mkProxies.nix
··· 1 + hosts: proxy: 2 + 3 + let 4 + caddyModulesPath = ../packages/server/caddy/modules; 5 + 6 + compressionModules = import (caddyModulesPath + /compression.nix); 7 + sslModules = import (caddyModulesPath + /ssl.nix); 8 + in 9 + builtins.listToAttrs ( 10 + map (host: { 11 + name = host.name; 12 + value = { 13 + extraConfig = '' 14 + ${compressionModules.basic} 15 + ${sslModules.${host.ssl}} 16 + 17 + ${proxy} 18 + ''; 19 + }; 20 + }) hosts 21 + )
+1
lib/mkSystem.nix
··· 60 60 home-manager = inputs.home-manager; 61 61 firefox-addons = inputs.firefox-addons; 62 62 nixcord = inputs.nixcord; 63 + emby-flake = inputs.emby-flake; 63 64 }; 64 65 }
+24
modules/server/nfs.nix
··· 1 + let 2 + ports = [ 3 + 111 4 + 2049 5 + 4000 6 + 4001 7 + 4002 8 + 20048 9 + ]; 10 + in 11 + { 12 + services.nfs.server = { 13 + enable = true; 14 + 15 + statdPort = 4000; 16 + lockdPort = 4001; 17 + mountdPort = 4002; 18 + }; 19 + 20 + networking.firewall = { 21 + allowedTCPPorts = ports; 22 + allowedUDPPorts = ports; 23 + }; 24 + }
+14
modules/server/openssh.nix
··· 1 + { 2 + services.openssh = { 3 + enable = true; 4 + 5 + startWhenNeeded = true; 6 + 7 + settings = { 8 + PasswordAuthentication = false; 9 + KbdInteractiveAuthentication = false; 10 + 11 + PermitRootLogin = "no"; 12 + }; 13 + }; 14 + }
+43
modules/server/zfs.nix
··· 1 + { config, pkgs, ... }: 2 + 3 + { 4 + boot.supportedFilesystems = [ "zfs" ]; 5 + boot.zfs.forceImportRoot = false; 6 + 7 + boot.zfs.devNodes = "/dev/disk/by-partuuid"; 8 + 9 + services.zfs.autoScrub.enable = true; 10 + 11 + services.sanoid = { 12 + enable = true; 13 + 14 + templates = { 15 + vital = { 16 + autosnap = true; 17 + autoprune = true; 18 + 19 + yearly = 3; 20 + monthly = 12; 21 + daily = 62; 22 + hourly = 120; 23 + }; 24 + 25 + hourly = { 26 + autosnap = true; 27 + autoprune = true; 28 + 29 + monthly = 3; 30 + daily = 7; 31 + hourly = 24; 32 + }; 33 + 34 + daily = { 35 + autosnap = true; 36 + autoprune = true; 37 + 38 + monthly = 6; 39 + daily = 31; 40 + }; 41 + }; 42 + }; 43 + }
+9
outputs.nix
··· 27 27 hostName = "prospect"; 28 28 system = "x86_64-linux"; 29 29 }; 30 + 31 + index = mkSystem { 32 + hostName = "index"; 33 + system = "x86_64-linux"; 34 + 35 + extraModules = [ 36 + inputs.emby-flake.nixosModules.default 37 + ]; 38 + }; 30 39 }; 31 40 }
+30
packages/server/caddy/default.nix
··· 1 + { email }: 2 + 3 + { pkgs, ... }: 4 + 5 + { 6 + services.caddy = { 7 + enable = true; 8 + 9 + inherit email; 10 + 11 + globalConfig = '' 12 + servers { 13 + trusted_proxies cloudflare { 14 + interval 12h 15 + timeout 15s 16 + } 17 + } 18 + ''; 19 + 20 + package = pkgs.caddy.withPlugins { 21 + plugins = [ 22 + "github.com/caddy-dns/cloudflare@v0.2.1" 23 + "github.com/WeidiDeng/caddy-cloudflare-ip@v0.0.0-20231130002422-f53b62aa13cb" 24 + "github.com/BadAimWeeb/caddy-uwsgi-transport@v0.0.0-20240317192154-74a1008b9763" 25 + ]; 26 + 27 + hash = "sha256-THbBk1z14F6LhsI8feUgZxCPIFehLXlNkpxidl0soYc="; 28 + }; 29 + }; 30 + }
+5
packages/server/caddy/modules/compression.nix
··· 1 + { 2 + basic = '' 3 + encode zstd gzip 4 + ''; 5 + }
+14
packages/server/caddy/modules/ssl.nix
··· 1 + { 2 + internal = '' 3 + tls internal 4 + ''; 5 + 6 + cloudflare = '' 7 + tls = { 8 + dns cloudflare {env.CF_API_TOKEN} 9 + 10 + resolvers 1.1.1.1 11 + propagation_delay 60s 12 + } 13 + ''; 14 + }
+9
packages/server/databases/mysql.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + services.mysql = { 5 + enable = true; 6 + 7 + package = pkgs.mariadb_114; 8 + }; 9 + }
+20
packages/server/databases/postgresql.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + services.postgresql = { 5 + enable = true; 6 + 7 + enableJIT = true; 8 + 9 + settings = { 10 + random_page_cost = 1.2; 11 + 12 + jit_above_cost = 500000; 13 + 14 + autovacuum_vacuum_cost_limit = 2000; 15 + autovacuum_vacuum_scale_factor = 0.01; 16 + }; 17 + 18 + package = pkgs.postgresql_17; 19 + }; 20 + }
+7
packages/server/databases/redis.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + services.redis = { 5 + package = pkgs.valkey; 6 + }; 7 + }
+28
packages/server/groupware/autoconfig.nix
··· 1 + { 2 + hosts ? [ ], 3 + domain, 4 + }: 5 + 6 + { flakeLib, ... }: 7 + 8 + { 9 + services.go-autoconfig = { 10 + enable = true; 11 + 12 + settings = { 13 + domain = "autoconfig.${domain}"; 14 + 15 + smtp = { 16 + server = "mx.${domain}"; 17 + }; 18 + 19 + imap = { 20 + server = "mx.${domain}"; 21 + }; 22 + }; 23 + }; 24 + 25 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 26 + reverse_proxy :1323 27 + ''; 28 + }
+45
packages/server/groupware/collabora.nix
··· 1 + { config, ... }: 2 + 3 + # Socket support: https://github.com/CollaboraOnline/online/issues/7156 4 + 5 + { 6 + imports = [ 7 + ../language/languagetool.nix 8 + ]; 9 + 10 + services.collabora-online = { 11 + enable = true; 12 + 13 + languagetool = { 14 + enabled = true; 15 + 16 + base_url = "http://127.0.0.1:${config.services.languagetool.port}/v2"; 17 + }; 18 + 19 + fonts_missing = { 20 + handling = "report"; 21 + }; 22 + 23 + per_document = { 24 + idlesave_duration_secs = 15; 25 + autosave_duration_secs = 60; 26 + always_save_on_exit = true; 27 + 28 + redlining_as_comments = true; 29 + 30 + max_concurrency = 6; 31 + }; 32 + 33 + admin_console = { 34 + enable = false; 35 + }; 36 + 37 + ssl = { 38 + enable = false; 39 + }; 40 + 41 + wasm = { 42 + enable = true; 43 + }; 44 + }; 45 + }
+210
packages/server/groupware/maddy.nix
··· 1 + { domain, email }: 2 + 3 + { config, ... }: 4 + 5 + let 6 + subdomain = "mx.${domain}"; 7 + in 8 + { 9 + imports = [ 10 + ../databases/postgresql.nix 11 + ./rspamd.nix 12 + ]; 13 + 14 + services.postgresql = { 15 + ensureUsers = [ 16 + { 17 + name = "maddy"; 18 + ensureDBOwnership = true; 19 + } 20 + ]; 21 + 22 + ensureDatabases = [ "maddy" ]; 23 + }; 24 + 25 + services.rspamd = { 26 + locals."dkim_signing.conf".text = '' 27 + selector = "default"; 28 + domain = "${subdomain}"; 29 + path = "/var/lib/maddy/dkim_keys/$domain_$selector.key"; 30 + ''; 31 + }; 32 + 33 + systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "maddy" ]; 34 + 35 + services.maddy = { 36 + enable = true; 37 + 38 + primaryDomain = subdomain; 39 + 40 + localDomains = [ 41 + "$(hostname)" 42 + ]; 43 + 44 + tls = { 45 + loader = "acme"; 46 + extraConfig = '' 47 + email ${email} 48 + agreed 49 + 50 + hostname ${subdomain} 51 + challenge dns-01 52 + 53 + dns cloudflare { 54 + api_token {env:CF_API_TOKEN} 55 + } 56 + ''; 57 + }; 58 + 59 + config = '' 60 + auth.pass_table local_authdb { 61 + table sql_table { 62 + driver postgres 63 + dsn "host=/run/postgresql dbname=maddy user=maddy" 64 + table_name passwords 65 + } 66 + } 67 + 68 + storage.imapsql local_mailboxes { 69 + driver postgres 70 + dsn "host=/run/postgresql dbname=maddy user=maddy" 71 + } 72 + 73 + table.chain local_rewrites { 74 + optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3" 75 + 76 + optional_step static { 77 + entry postmaster postmaster@$(primary_domain) 78 + } 79 + 80 + optional_step file /etc/maddy/aliases 81 + } 82 + 83 + msgpipeline local_routing { 84 + check { 85 + rspamd { 86 + api_path unix:/run/rspamd/rspamd.sock 87 + } 88 + } 89 + 90 + destination postmaster $(local_domains) { 91 + modify { 92 + replace_rcpt &local_rewrites 93 + } 94 + 95 + deliver_to &local_mailboxes 96 + } 97 + 98 + default_destination { 99 + reject 550 5.1.1 "User doesn't exist" 100 + } 101 + } 102 + 103 + smtp tcp://0.0.0.0:25 { 104 + limits { 105 + all rate 25 1s 106 + all concurrency 10 107 + } 108 + 109 + dmarc yes 110 + max_message_size 25M 111 + check { 112 + require_mx_record 113 + dkim 114 + spf 115 + } 116 + 117 + source $(local_domains) { 118 + reject 501 5.1.8 "Use Submission for outgoing SMTP" 119 + } 120 + 121 + default_source { 122 + destination postmaster $(local_domains) { 123 + deliver_to &local_routing 124 + } 125 + 126 + default_destination { 127 + reject 550 5.1.1 "User doesn't exist" 128 + } 129 + } 130 + } 131 + 132 + submission tls://0.0.0.0:465 tcp://0.0.0.0:587 { 133 + limits { 134 + all rate 25 1s 135 + } 136 + 137 + auth &local_authdb 138 + 139 + source $(local_domains) { 140 + check { 141 + authorize_sender { 142 + prepare_email &local_rewrites 143 + user_to_email identity 144 + } 145 + } 146 + 147 + destination postmaster $(local_domains) { 148 + deliver_to &local_routing 149 + } 150 + 151 + default_destination { 152 + modify { 153 + dkim $(primary_domain) $(local_domains) default 154 + } 155 + 156 + deliver_to &remote_queue 157 + } 158 + } 159 + 160 + default_source { 161 + reject 501 5.1.8 "Non-local sender domain" 162 + } 163 + } 164 + 165 + imap tls://0.0.0.0:993 tcp://0.0.0.0:143 { 166 + auth &local_authdb 167 + storage &local_mailboxes 168 + } 169 + 170 + target.remote outbound_delivery { 171 + limits { 172 + destination rate 25 1s 173 + destination concurrency 10 174 + } 175 + 176 + mx_auth { 177 + dane 178 + mtasts { 179 + cache ram 180 + } 181 + local_policy { 182 + min_tls_level encrypted 183 + min_mx_level none 184 + } 185 + } 186 + } 187 + 188 + target.queue remote_queue { 189 + target &outbound_delivery 190 + 191 + autogenerated_msg_domain $(primary_domain) 192 + 193 + bounce { 194 + destination postmaster $(local_domains) { 195 + deliver_to &local_routing 196 + } 197 + 198 + default_destination { 199 + reject 550 5.0.0 "Refusing to send DSNs to non-local addresses" 200 + } 201 + } 202 + } 203 + ''; 204 + }; 205 + 206 + networking.firewall.allowedTCPPorts = [ 207 + 465 208 + 993 209 + ]; 210 + }
+28
packages/server/groupware/radicale.nix
··· 1 + { 2 + hosts ? [ ] 3 + }: 4 + 5 + { 6 + services.radicale = { 7 + enable = true; 8 + 9 + settings = { 10 + auth = { 11 + type = "imap"; 12 + 13 + # imap_host = "localhost"; 14 + # imap_security = "tls"; 15 + 16 + cache_logins = true; 17 + }; 18 + 19 + web = { 20 + type = "none"; 21 + }; 22 + }; 23 + }; 24 + 25 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 26 + reverse_proxy :5232 27 + ''; 28 + }
+30
packages/server/groupware/rspamd.nix
··· 1 + { config, ... }: 2 + 3 + { 4 + imports = [ 5 + ../databases/redis.nix 6 + ]; 7 + 8 + services.redis.servers.rspamd = { 9 + enable = true; 10 + 11 + port = 0; 12 + 13 + user = config.services.rspamd.user; 14 + }; 15 + 16 + services.rspamd = { 17 + enable = true; 18 + 19 + locals = { 20 + "redis.conf".text = '' 21 + servers = "${config.services.redis.servers.rspamd.unixSocket}"; 22 + ''; 23 + 24 + "classifier-bayes.conf".text = '' 25 + backend = "redis"; 26 + autolearn = true; 27 + ''; 28 + }; 29 + }; 30 + }
+18
packages/server/language/languagetool.nix
··· 1 + { config, pkgs, ... }: 2 + 3 + { 4 + services.languagetool = { 5 + enable = true; 6 + 7 + # TODO: 1, 2, 3grams and fasttext 8 + 9 + settings = { 10 + maxTextLength = 380; 11 + 12 + pipelineCaching = true; 13 + pipelinePrewarming = true; 14 + }; 15 + 16 + jrePackage = pkgs.temurin-jre-bin; 17 + }; 18 + }
+29
packages/server/language/libretranslate.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + systemd.services.libretranslate = { 5 + description = "LibreTranslate service"; 6 + after = [ "network.target" ]; 7 + wantedBy = [ "multi-user.target" ]; 8 + 9 + environment = { 10 + HOME = "/var/lib/libretranslate"; 11 + 12 + LT_DISABLE_FILES_TRANSLATION = "true"; 13 + LT_CHAR_LIMIT = "380"; 14 + 15 + LT_THREADS = "8"; 16 + }; 17 + 18 + serviceConfig = { 19 + ExecStart = "${pkgs.libretranslate}/bin/libretranslate"; 20 + DynamicUser = true; 21 + WorkingDirectory = "/var/lib/libretranslate"; 22 + StateDirectory = "libretranslate"; 23 + }; 24 + }; 25 + 26 + environment.systemPackages = with pkgs; [ 27 + libretranslate 28 + ]; 29 + }
+17
packages/server/media/audiobookshelf.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { config, flakeLib, ... }: 6 + 7 + { 8 + services.audiobookshelf = { 9 + enable = true; 10 + 11 + host = "unix//run/audiobookshelf/audiobookshelf.sock"; 12 + }; 13 + 14 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 15 + reverse_proxy ${config.services.audiobookshelf.host} 16 + ''; 17 + }
+9
packages/server/media/emby.nix
··· 1 + { emby-flake, ... }: 2 + 3 + { 4 + services.emby = { 5 + enable = true; 6 + 7 + package = emby-flake.packages.x86_64-linux.default; 8 + }; 9 + }
+67
packages/server/media/navidrome.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { flakeLib, pkgs-unstable, ... }: 6 + 7 + let 8 + socket = "/run/navidrome/navidrome.sock"; 9 + in 10 + { 11 + services.navidrome = { 12 + enable = true; 13 + 14 + settings = { 15 + Address = "unix:${socket}"; 16 + 17 + DefaultTheme = "Spotify-ish"; 18 + DefaultUIVolume = 25; 19 + 20 + EnableCoverAnimation = false; 21 + EnableGravatar = false; 22 + EnableStarRating = false; 23 + MaxSidebarPlaylists = 15; 24 + 25 + EnableSharing = true; 26 + EnableDownloads = true; 27 + DefaultShareExpiration = "72h"; 28 + 29 + Deezer.Enabled = false; 30 + #LastFM.Enabled = false; 31 + ListenBrainz.Enabled = false; # TODO: Self-host Maloja 32 + AlbumPlayCountMode = "normalized"; 33 + 34 + EnableInsightsCollector = false; 35 + 36 + Tags.genre.Split = [ 37 + "; " 38 + ", " 39 + " / " 40 + "/" 41 + "\\" 42 + ]; 43 + 44 + Scanner.ArtistJoiner = ", "; 45 + Scanner.WatcherWait = "1m"; 46 + Scanner.ScanOnStartup = false; 47 + 48 + LyricsPriority = ".lrc, embedded"; 49 + ArtistArtPriority = "artist.*"; 50 + CoverArtPriority = "cover.*, embedded"; 51 + EnableMediaFileCoverArt = true; 52 + 53 + AutoImportPlaylists = false; 54 + 55 + Subsonic.ArtistParticipations = true; 56 + 57 + ImageCacheSize = "2GB"; 58 + TranscodingCacheSize = "8GB"; 59 + }; 60 + 61 + package = pkgs-unstable.navidrome; # TODO: Switch back to stable once BFR is ready 62 + }; 63 + 64 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 65 + reverse_proxy unix/${socket} 66 + ''; 67 + }
+38
packages/server/torrenting/flood.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { 6 + config, 7 + lib, 8 + flakeLib, 9 + pkgs, 10 + utils ? pkgs.utils, 11 + ... 12 + }: 13 + 14 + let 15 + socket = "/run/flood/flood.sock"; 16 + in 17 + { 18 + services.flood = { 19 + enable = true; 20 + 21 + extraArgs = [ 22 + "--rtsocket=${config.services.rtorrent.rpcSocket}" 23 + ]; 24 + }; 25 + 26 + systemd.services.flood.serviceConfig.ExecStart = lib.mkForce (utils.escapeSystemdExecArgs ( 27 + [ 28 + (lib.getExe pkgs.flood) 29 + "--port ${socket}" 30 + "--rundir=/var/lib/flood" 31 + ] 32 + ++ config.services.flood.extraArgs 33 + )); 34 + 35 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 36 + reverse_proxy unix/${socket} 37 + ''; 38 + }
+36
packages/server/torrenting/rtorrent.nix
··· 1 + { 2 + services.rtorrent = { 3 + enable = true; 4 + 5 + configText = '' 6 + dht.mode.set = auto 7 + dht.port.set = "6881" 8 + 9 + protocol.pex.set = yes 10 + 11 + network.port_range.set = "6881-6889" 12 + 13 + trackers.use_udp.set = yes 14 + 15 + throttle.max_downloads.set = 100 16 + throttle.max_uploads.global.set = 300 17 + 18 + trackers.numwant.set = 100 19 + throttle.min_peers.normal.set = 1 20 + throttle.max_peers.normal.set = 100 21 + throttle.min_peers.seed.set = 1 22 + throttle.max_peers.seed.set = 100 23 + 24 + pieces.memory.max.set = 4000M 25 + pieces.preload.type.set = 2 26 + pieces.preload.min_rate.set = 50000 27 + 28 + #ratio.enable= # TODO: seeding ratio for sonarr/etc. 29 + #ratio.min.set=100 30 + #ratio.max.set=300 31 + #system.method.set = group.seeding.ratio.command, d.close= 32 + 33 + schedule2 = throttle_slow, 10:00:00, 24:00:00, ((throttle.global_up.max_rate.set_kb, 4000)) 34 + ''; 35 + }; 36 + }
+101
packages/server/torrenting/soulseek.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { config, flakeLib, ... }: 6 + 7 + { 8 + services.slskd = { 9 + enable = true; 10 + 11 + domain = null; 12 + 13 + settings = { 14 + global = { 15 + upload = { 16 + slots = 75; 17 + speed_limit = 122070; 18 + }; 19 + }; 20 + 21 + groups.default = { 22 + upload = { 23 + slots = 50; 24 + speed_limit = 12207; 25 + }; 26 + 27 + limits.queued = { 28 + files = 300; 29 + megabytes = 5000; 30 + }; 31 + 32 + limits.daily = { 33 + files = 2147483647; 34 + megabytes = 2147483647; 35 + }; 36 + 37 + limits.weekly = { 38 + files = 2000; 39 + megabytes = 30000; 40 + }; 41 + }; 42 + 43 + groups.leechers = { 44 + thresholds = { 45 + files = 25; 46 + directories = 3; 47 + }; 48 + 49 + upload = { 50 + slots = 3; 51 + speed_limit = 976; 52 + }; 53 + 54 + limits.queued = { 55 + files = 30; 56 + megabytes = 1000; 57 + }; 58 + 59 + limits.daily = { 60 + files = 30; 61 + megabytes = 1000; 62 + }; 63 + 64 + limits.weekly = { 65 + files = 150; 66 + megabytes = 5000; 67 + }; 68 + }; 69 + 70 + shares = { 71 + filters = [ 72 + ".md$" 73 + ".log$" 74 + ".pydio$" 75 + ]; 76 + 77 + cache = { 78 + storage_mode = "memory"; 79 + workers = 8; 80 + retention = 10080; 81 + }; 82 + }; 83 + 84 + filters.search.request = [ 85 + "^.{1,2}$" 86 + "^(\.?pdf|\.?docx|\.?xlsx)$" 87 + ]; 88 + 89 + retention = { 90 + search = 10080; 91 + }; 92 + }; 93 + }; 94 + 95 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 96 + reverse_proxy :${toString config.services.slskd.settings.web.port} { 97 + header_up Upgrade "websocket" 98 + header_up Connection "Upgrade" 99 + } 100 + ''; 101 + }
+103
packages/server/web/forgejo.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { 6 + config, 7 + lib, 8 + flakeLib, 9 + ... 10 + }: 11 + 12 + { 13 + imports = [ 14 + ../databases/postgresql.nix 15 + ../databases/redis.nix 16 + ]; 17 + 18 + services.redis.servers.forgejo = { 19 + enable = true; 20 + user = "forgejo"; 21 + }; 22 + 23 + services.forgejo = { 24 + enable = true; 25 + 26 + lfs = { 27 + enable = true; 28 + }; 29 + 30 + database = { 31 + type = "postgres"; 32 + 33 + socket = "/run/postgresql/"; 34 + 35 + createDatabase = true; 36 + }; 37 + 38 + settings = { 39 + service = { 40 + ENABLE_CAPTCHA = true; 41 + CAPTCHA_TYPE = "cfturnstile"; 42 + 43 + DISABLE_REGISTRATION = true; 44 + 45 + REGISTER_EMAIL_CONFIRM = true; 46 + ENABLE_NOTIFY_MAIL = true; 47 + 48 + DEFAULT_KEEP_EMAIL_PRIVATE = true; 49 + }; 50 + 51 + "repository.signing" = { 52 + DEFAULT_TRUST_MODEL = "committer"; 53 + }; 54 + 55 + #camo = { 56 + # ENABLED = true; 57 + #}; 58 + 59 + session = { 60 + PROVIDER = "redis"; 61 + PROVIDER_CONFIG = "redis+socket://${config.services.redis.servers.forgejo.unixSocket}"; 62 + 63 + COOKIE_SECURE = true; 64 + }; 65 + 66 + queue = { 67 + TYPE = "redis"; 68 + CONN_STR = "redis+socket://${config.services.redis.servers.forgejo.unixSocket}"; 69 + }; 70 + 71 + cache = { 72 + ADAPTER = "redis"; 73 + HOST = "redis+socket://${config.services.redis.servers.forgejo.unixSocket}"; 74 + }; 75 + 76 + mailer = { 77 + ENABLED = true; 78 + }; 79 + 80 + server = { 81 + DISABLE_SSH = true; 82 + 83 + PROTOCOL = "fcgi+unix"; 84 + }; 85 + 86 + "cron.update_checker" = { 87 + enabled = false; 88 + }; 89 + }; 90 + }; 91 + 92 + systemd.services.forgejo.serviceConfig = { 93 + Type = lib.mkForce "exec"; 94 + 95 + PrivateDevices = lib.mkForce false; 96 + }; 97 + 98 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 99 + reverse_proxy unix/${config.services.forgejo.settings.server.HTTP_ADDR} { 100 + transport fastcgi 101 + } 102 + ''; 103 + }
+38
packages/server/web/miniflux.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { 6 + config, 7 + lib, 8 + flakeLib, 9 + ... 10 + }: 11 + 12 + { 13 + services.miniflux = { 14 + enable = true; 15 + 16 + config = { 17 + FILTER_ENTRY_MAX_AGE_DAYS = 7; 18 + 19 + FETCH_BILIBILI_WATCH_TIME = 1; 20 + FETCH_NEBULA_WATCH_TIME = 1; 21 + FETCH_ODYSEE_WATCH_TIME = 1; 22 + FETCH_YOUTUBE_WATCH_TIME = 1; 23 + 24 + MEDIA_PROXY_MODE = "all"; 25 + 26 + CLEANUP_ARCHIVE_READ_DAYS = -1; 27 + CLEANUP_ARCHIVE_UNREAD_DAYS = -1; 28 + 29 + LISTEN_ADDR = "/run/miniflux/miniflux.sock"; 30 + }; 31 + }; 32 + 33 + systemd.services.miniflux.serviceConfig.RuntimeDirectoryMode = lib.mkForce "0755"; 34 + 35 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 36 + reverse_proxy unix/${config.services.miniflux.config.LISTEN_ADDR} 37 + ''; 38 + }
+511
packages/server/web/searx.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { 6 + config, 7 + lib, 8 + flakeLib, 9 + ... 10 + }: 11 + 12 + { 13 + services.searx = { 14 + enable = true; 15 + 16 + redisCreateLocally = true; 17 + 18 + runInUwsgi = true; 19 + uwsgiConfig = { 20 + socket = "/run/searx/searx.sock"; 21 + http = ":8888"; 22 + chmod-socket = "660"; 23 + }; 24 + 25 + settings = { 26 + general = { 27 + donation_url = false; 28 + contact_url = false; 29 + enable_metrics = false; 30 + }; 31 + 32 + ui = { 33 + center_alignment = true; 34 + infinite_scroll = true; 35 + 36 + cache_url = "https://archive.today/"; 37 + 38 + static_use_hash = true; 39 + query_in_title = false; 40 + }; 41 + 42 + search = { 43 + autocomplete = "duckduckgo"; 44 + favicon_resolver = "allesedv"; 45 + 46 + formats = [ 47 + "html" 48 + "json" 49 + ]; 50 + }; 51 + 52 + server = { 53 + public_instance = true; 54 + limiter = true; 55 + 56 + image_proxy = true; 57 + 58 + method = "GET"; 59 + 60 + bind_address = "127.0.0.1"; 61 + }; 62 + 63 + limiterSettings = { 64 + real_ip = { 65 + x_for = 1; 66 + }; 67 + 68 + botdetection = { 69 + ip_limit = { 70 + filter_link_local = true; 71 + link_token = false; 72 + }; 73 + }; 74 + }; 75 + 76 + engines = lib.mapAttrsToList (name: value: { inherit name; } // value) { 77 + # GENERAL 78 + # translate 79 + "dictzone".disabled = true; 80 + "libretranslate".disabled = true; 81 + "lingva".disabled = true; 82 + "mozhi".disabled = true; 83 + "mymemory translated".disabled = true; 84 + 85 + # web 86 + "bing".disabled = true; 87 + "brave".disabled = false; 88 + "duckduckgo".disabled = false; 89 + "google".disabled = true; 90 + "mojeek".disabled = true; 91 + "presearch".disabled = true; 92 + "presearch videos".disabled = true; 93 + "qwant".disabled = true; 94 + "startpage".disabled = true; 95 + "wiby".disabled = true; 96 + "yahoo".disabled = true; 97 + "seznam (CZ)".disabled = true; 98 + "goo (JA)".disabled = true; 99 + "naver (KO)".disabled = true; 100 + 101 + # wikimedia 102 + "wikibooks".disabled = true; 103 + "wikiquote".disabled = true; 104 + "wikisource".disabled = true; 105 + "wikispecies".disabled = true; 106 + "wikiversity".disabled = true; 107 + "wikivoyage".disabled = true; 108 + 109 + # custom 110 + "modrinth" = { 111 + disabled = true; 112 + categories = [ "general" ]; 113 + shortcut = "mr"; 114 + 115 + engine = "json_engine"; 116 + 117 + search_url = "https://api.modrinth.com/v2/search?query={query}&offset={pageno}&limit=1&index=relevance&facets=%5B%5B%22downloads%20%3E=%20500%22%5D%5D"; 118 + paging = true; 119 + page_size = 1; 120 + first_page_num = 0; 121 + 122 + results_query = "hits"; 123 + title_query = "title"; 124 + content_query = "description"; 125 + thumbnail_query = "featured_gallery"; 126 + url_query = "project_id"; 127 + url_prefix = "https://modrinth.com/project/"; 128 + 129 + weight = 1; 130 + }; 131 + 132 + # without further subgrouping 133 + "ask".disabled = true; 134 + "cloudflareai".disabled = true; 135 + "crowdview".disabled = true; 136 + "curlie".disabled = true; 137 + "currency".disabled = false; 138 + "ddg definitions".disabled = true; 139 + "encyclosearch".disabled = true; 140 + "mwmbl".disabled = true; 141 + "right dao".disabled = true; 142 + "searchmysite".disabled = true; 143 + "stract".disabled = true; 144 + "tineye".disabled = false; 145 + "wikidata".disabled = true; 146 + "wikipedia" = { 147 + disabled = false; 148 + 149 + weight = 2; 150 + }; 151 + "wolframalpha".disabled = true; 152 + "yacy".disabled = true; 153 + "yep".disabled = true; 154 + "bpb (DE)".disabled = true; 155 + "tagesschau (DE)".disabled = true; 156 + "wikimini (FR)".disabled = true; 157 + 158 + # IMAGES 159 + # web 160 + "bing images".disabled = true; 161 + "brave.images".disabled = true; 162 + "duckduckgo images".disabled = true; 163 + "google images".disabled = false; 164 + "mojeek images".disabled = true; 165 + "presearch images".disabled = true; 166 + "qwant images".disabled = true; 167 + 168 + # without further subgrouping 169 + "1x".disabled = true; 170 + "adobe stock".disabled = true; 171 + "artic".disabled = true; 172 + "deviantart" = { 173 + disabled = false; 174 + 175 + weight = 0.2; 176 + }; 177 + "findthatmeme".disabled = true; 178 + "flickr".disabled = true; 179 + "frinkiac".disabled = true; 180 + "imgur" = { 181 + disabled = false; 182 + 183 + weight = 0.2; 184 + }; 185 + "library of congress".disabled = true; 186 + "material icons".disabled = true; 187 + "openverse" = { 188 + disabled = false; 189 + 190 + weight = 0.5; 191 + }; 192 + "pinterest".disabled = true; 193 + "svgrepo".disabled = true; 194 + "unsplash" = { 195 + disabled = false; 196 + 197 + weight = 0.5; 198 + }; 199 + "wallhaven".disabled = true; 200 + "wikicommons.images" = { 201 + disabled = false; 202 + 203 + weight = 2; 204 + }; 205 + "yacy images".disabled = true; 206 + "yep images".disabled = true; 207 + "seekr images (EN)".disabled = true; 208 + 209 + # VIDEOS 210 + # web 211 + "bing videos".disabled = false; 212 + "brave.videos".disabled = true; 213 + "duckduckgo videos".disabled = true; 214 + "google videos".disabled = true; 215 + "qwant videos".disabled = true; 216 + 217 + # without further subgrouping 218 + "adobe stock video".disabled = true; 219 + "bilibili" = { 220 + disabled = false; 221 + 222 + weight = 0.2; 223 + }; 224 + "dailymotion".disabled = true; 225 + "google play movies".disabled = true; 226 + "invidious".disabled = true; 227 + "livespace".disabled = true; 228 + "media.ccc.de".disabled = true; 229 + "odysee".disabled = false; 230 + "peertube".disabled = true; 231 + "piped".disabled = true; 232 + "rumble".disabled = true; 233 + "sepiasearch".disabled = false; 234 + "vimeo" = { 235 + disabled = false; 236 + 237 + weight = 0.5; 238 + }; 239 + "wikicommons.videos" = { 240 + disabled = false; 241 + 242 + weight = 2; 243 + }; 244 + "youtube".disabled = false; 245 + "mediathekviewweb (DE)".disabled = true; 246 + "seekr videos (EN)".disabled = true; 247 + "ina (FR)".disabled = true; 248 + 249 + # NEWS 250 + # web 251 + "duckduckgo news".disabled = true; 252 + "mojeek news".disabled = false; 253 + 254 + # wikimedia 255 + "wikinews" = { 256 + disabled = false; 257 + 258 + weight = 2; 259 + }; 260 + 261 + # without further subgrouping 262 + "bing news".disabled = true; 263 + "brave.news".disabled = true; 264 + "google news".disabled = true; 265 + "qwant news".disabled = true; 266 + "yahoo news".disabled = true; 267 + "yep news".disabled = true; 268 + "seekr news (EN)".disabled = true; 269 + 270 + # MAP 271 + "apple maps".disabled = true; 272 + "openstreetmap".disabled = false; 273 + "photon".disabled = true; 274 + 275 + # MUSIC 276 + # lyrics 277 + "genius".disabled = false; 278 + 279 + # radio 280 + "radio browser".disabled = false; 281 + 282 + # without further subgrouping 283 + "adobe stock audio".disabled = true; 284 + "bandcamp" = { 285 + disabled = false; 286 + 287 + weight = 2; 288 + }; 289 + "deezer".disabled = true; 290 + "mixcloud".disabled = true; 291 + "piped.music".disabled = true; 292 + "soundcloud" = { 293 + disabled = false; 294 + 295 + weight = 0.5; 296 + }; 297 + "wikicommons.audio" = { 298 + disabled = false; 299 + 300 + weight = 0.2; 301 + }; 302 + 303 + # IT 304 + # packages 305 + "alpine linux packages".disabled = true; 306 + "crates.io" = { 307 + disabled = false; 308 + 309 + weight = 0.6; 310 + }; 311 + "docker hub".disabled = true; 312 + "hex".disabled = true; 313 + "hoogle".disabled = true; 314 + "lib.rs".disabled = true; 315 + "metacpan".disabled = true; 316 + "npm" = { 317 + disabled = false; 318 + 319 + weight = 0.6; 320 + }; 321 + "packagist".disabled = true; 322 + "pkg.go.dev" = { 323 + disabled = false; 324 + 325 + weight = 0.6; 326 + }; 327 + "pub.dev" = { 328 + disabled = false; 329 + 330 + weight = 0.5; 331 + }; 332 + "pypi" = { 333 + disabled = false; 334 + 335 + weight = 0.5; 336 + }; 337 + "rubygems".disabled = true; 338 + "voidlinux".disabled = true; 339 + 340 + # q&a 341 + "askubuntu".disabled = true; 342 + "caddy.community".disabled = false; 343 + "discuss.python".disabled = true; 344 + "pi-hole.community".disabled = true; 345 + "stackoverflow".disabled = false; 346 + "superuser".disabled = false; 347 + 348 + # repos 349 + "bitbucket" = { 350 + disabled = false; 351 + 352 + weight = 0.7; 353 + }; 354 + "codeberg" = { 355 + disabled = false; 356 + 357 + weight = 0.8; 358 + }; 359 + "gitea.com" = { 360 + disabled = false; 361 + 362 + weight = 0.8; 363 + }; 364 + "github" = { 365 + disabled = false; 366 + 367 + weight = 0.8; 368 + }; 369 + "gitlab" = { 370 + disabled = false; 371 + 372 + weight = 0.7; 373 + }; 374 + "sourcehut" = { 375 + disabled = false; 376 + 377 + weight = 0.7; 378 + }; 379 + 380 + # software wikis 381 + "arch linux wiki".disabled = false; 382 + "free software directory".disabled = true; 383 + "gentoo".disabled = true; 384 + 385 + # without further subgrouping 386 + "anaconda".disabled = true; 387 + "cpprefrence".disabled = true; 388 + "habrahabr".disabled = true; 389 + "hackernews".disabled = false; 390 + "lobste.rs".disabled = false; 391 + "mankier" = { 392 + disabled = false; 393 + 394 + weight = 2; 395 + }; 396 + "mdn" = { 397 + disabled = false; 398 + 399 + weight = 2; 400 + }; 401 + "searchcode".disabled = true; 402 + 403 + # SCIENCE 404 + # scientific publications 405 + "arxiv".disabled = true; 406 + "crossref".disabled = true; 407 + "google scholar".disabled = false; 408 + "pubmed".disabled = false; 409 + "semanticscholar".disabled = true; 410 + 411 + # without further subgrouping 412 + "openairedatasets".disabled = true; 413 + "openairepublications".disabled = true; 414 + "pdbe".disabled = true; 415 + 416 + # FILES 417 + # apps 418 + "apk mirror".disabled = true; 419 + "apple app store".disabled = false; 420 + "fdroid".disabled = false; 421 + "google play apps" = { 422 + disabled = false; 423 + 424 + weight = 0.8; 425 + }; 426 + 427 + # without further subgrouping 428 + "1337x".disabled = true; 429 + "annas archive".disabled = true; 430 + "bt4g".disabled = true; 431 + "btdigg".disabled = true; 432 + "kickass".disabled = true; 433 + "library genesis".disabled = true; 434 + "nyaa".disabled = true; 435 + "openrepos".disabled = true; 436 + "piratebay".disabled = true; 437 + "solidtorrents".disabled = true; 438 + "tokyotoshokan".disabled = true; 439 + "wikicommons.files".disabled = false; 440 + "z-library".disabled = true; 441 + 442 + # SOCIAL MEDIA 443 + "9gag".disabled = true; 444 + "lemmy comments".disabled = false; 445 + "lemmy communities".disabled = true; 446 + "lemmy posts".disabled = false; 447 + "lemmy users".disabled = true; 448 + "mastodon hashtags".disabled = false; 449 + "mastodon users".disabled = true; 450 + "reddit" = { 451 + disabled = false; 452 + 453 + weight = 1.2; 454 + }; 455 + "tootfinder".disabled = false; 456 + 457 + # OTHER 458 + # dictionaries 459 + "etymonline".disabled = true; 460 + "wiktionary".disabled = true; 461 + "wordnik".disabled = true; 462 + "duden (DE)".disabled = true; 463 + "woxikon.de synonyme (DE)".disabled = true; 464 + "jisho (JA)".disabled = true; 465 + "sjp.pwn (PL)".disabled = true; 466 + 467 + # movies 468 + "imdb".disabled = true; 469 + "rottentomatoes".disabled = true; 470 + "tmdb".disabled = true; 471 + "moviepilot (DE)".disabled = true; 472 + 473 + # shopping 474 + "geizhals (DE)".disabled = true; 475 + 476 + # weather 477 + "duckduckgo weather".disabled = true; 478 + "openmeteo".disabled = true; 479 + "wttr.in".diasbled = true; 480 + 481 + # without further subgrouping 482 + "emojipedia".disabled = true; 483 + "erowid".disabled = true; 484 + "fyyd".disabled = true; 485 + "goodreads".disabled = true; 486 + "openlibrary".disabled = true; 487 + "podcastindex".disabled = true; 488 + "yummly".disabled = true; 489 + "chefkoch (DE)".disabled = true; 490 + "destatis (DE)".disabled = true; 491 + }; 492 + 493 + enabled_plugins = [ 494 + "Unit converter plugin" 495 + "Self Information" 496 + "Hash plugin" 497 + "Open Access DOI rewrite" 498 + "Tracker URL remover" 499 + ]; 500 + }; 501 + }; 502 + 503 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 504 + reverse_proxy unix/${config.services.searx.uwsgiConfig.socket} { 505 + transport uwsgi 506 + 507 + header_up X-Forwarded-For {http.request.header.CF-Connecting-IP} 508 + header_up X-Real-IP {http.request.header.CF-Connecting-IP} 509 + } 510 + ''; 511 + }
+68
packages/server/web/vaultwarden.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { flakeLib, pkgs-unstable, ... }: 6 + 7 + let 8 + socket = "/run/vaultwarden/vaultwarden.sock"; 9 + in 10 + { 11 + imports = [ 12 + ../databases/postgresql.nix 13 + ]; 14 + 15 + services.postgresql = { 16 + ensureUsers = [ 17 + { 18 + name = "vaultwarden"; 19 + ensureDBOwnership = true; 20 + } 21 + ]; 22 + 23 + ensureDatabases = [ "vaultwarden" ]; 24 + }; 25 + 26 + services.vaultwarden = { 27 + enable = true; 28 + 29 + dbBackend = "postgresql"; 30 + 31 + config = { 32 + ICON_SERVICE = "internal"; 33 + ICON_REDIRECT_CODE = 301; 34 + 35 + SIGNUPS_VERIFY = true; 36 + REQUIRE_DEVICE_EMAIL = true; 37 + SMTP_EMBED_IMAGES = false; 38 + 39 + EMERGENCY_ACCESS_ALLOWED = false; 40 + PASSWORD_HINTS_ALLOWED = false; 41 + AUTHENTICATOR_DISABLE_TIME_DRIFT = true; 42 + 43 + INVITATIONS_ALLOWED = true; 44 + SIGNUPS_ALLOWED = false; 45 + 46 + TRASH_AUTO_DELETE_DAYS = 7; 47 + 48 + USER_ATTACHMENT_LIMIT = 51200; 49 + 50 + # TODO: look into websockets 51 + # TODO: look into push 52 + # TODO: HaveIBeenPwned API Key 53 + 54 + EXPERIMENTAL_CLIENT_FEATURE_FLAGS = "fido2-vault-credentials,simple-login-self-host-alias"; 55 + 56 + EXTENDED_LOGGING = false; 57 + 58 + ROCKET_ADDRESS = "unix:${socket}"; 59 + DATABASE_URL = "postgresql:///vaultwarden?host=/run/postgresql"; 60 + }; 61 + 62 + package = pkgs-unstable.vaultwarden; # TODO: just use stable? 63 + }; 64 + 65 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 66 + reverse_proxy unix/${socket} 67 + ''; 68 + }
+66
packages/server/web/wakapi.nix
··· 1 + { 2 + hosts ? [ ], 3 + }: 4 + 5 + { config, flakeLib, ... }: 6 + 7 + { 8 + imports = [ 9 + ../databases/postgresql.nix 10 + ]; 11 + 12 + services.wakapi = { 13 + enable = true; 14 + 15 + settings = { 16 + app = { 17 + leaderboard_enabled = false; 18 + 19 + inactive_days = 31; 20 + max_inactive_months = -1; 21 + }; 22 + 23 + mail = { 24 + smtp = { 25 + port = 465; 26 + tls = true; 27 + }; 28 + }; 29 + 30 + server = { 31 + listen_ipv4 = "-"; 32 + listen_ipv6 = "-"; 33 + listen_socket = "/run/wakapi/wakapi.sock"; 34 + }; 35 + 36 + db = { 37 + user = "wakapi"; 38 + name = "wakapi"; 39 + 40 + dialect = config.services.wakapi.database.dialect; 41 + 42 + socket = "/run/postgres"; #config.services.postgresql.settings.socket; # TODO: This causes infinite recursion 43 + }; 44 + 45 + security = { 46 + allow_signup = false; 47 + invite_codes = false; 48 + signup_captcha = true; 49 + 50 + disable_frontpage = true; 51 + 52 + insecure_cookies = false; 53 + }; 54 + }; 55 + 56 + database = { 57 + dialect = "postgres"; 58 + 59 + createLocally = true; 60 + }; 61 + }; 62 + 63 + services.caddy.virtualHosts = flakeLib.mkProxies hosts '' 64 + reverse_proxy unix/${config.services.wakapi.settings.server.listen_socket} 65 + ''; 66 + }