Compare commits

...
653 Commits
Author SHA1 Message Date
blake b7d27d8ea1 syncthing bullshit 2026-09-24 15:06:10 -05:00
blake 52641b8b10 change tailscale to cli via nix 2026-09-24 13:06:15 -05:00
blake 256a9684fe change tailscale to gui via nix 2026-09-24 12:58:10 -05:00
blake 6f74b4aff3 change tailscale to gui via nix 2026-09-24 12:56:14 -05:00
blake ae9a50f11e change tailscale to gui via nix 2026-09-24 12:55:38 -05:00
blake 8c9ff95e68 update hash update 2026-09-17 15:40:35 -05:00
blake b21b81caf4 updates for jellyfin 12.0 2026-09-17 15:36:06 -05:00
blake 17631704b1 switch jellyfin to unstable for 12.0 2026-09-17 15:29:34 -05:00
blake cf29da55dc add wger, prolly wont set all this up tho, its a lot 2026-09-17 12:13:11 -05:00
blake 4d512e6f6c enable status 2026-09-10 13:30:21 -05:00
blake 3dbcfe9ff1 allow the query port 2026-09-10 13:23:15 -05:00
blake d196fed0d8 add prepare for monitoring 2026-09-10 13:19:36 -05:00
blake 491721aed3 open valheim route 2026-09-10 13:08:06 -05:00
blake faceb9d0ca open valheim ports 2026-09-10 12:57:50 -05:00
blake 8832a4495b valheim ddns 2026-09-10 12:47:38 -05:00
blake 3e268f4b22 add forwards for valheim 2026-09-10 12:46:43 -05:00
blake c9d30a962c fix motd 2026-09-10 12:40:59 -05:00
blake 7176ce59d2 fix motd 2026-09-10 12:39:41 -05:00
blake 47c160200f add fix option path 2026-09-10 12:38:14 -05:00
blake 5e6d4b6344 add import 2026-09-10 12:36:09 -05:00
blake 409d84b530 add valheim to lumiose 2026-09-10 12:35:20 -05:00
blake 60e745a3d9 config valheim 2026-09-10 12:34:47 -05:00
blake c9dc8a0def init valheim 2026-09-10 12:22:13 -05:00
blake 071b6f0e66 add acrobat pro 2026-09-02 11:48:52 -05:00
blake 0d48663d81 dumb shit 2026-09-01 03:05:46 -05:00
blake c56e020dec navidrome change plugins folder 2026-09-01 02:40:53 -05:00
blake 5af6c6242b navidrome change plugins folder 2026-09-01 02:39:23 -05:00
blake 08c829a708 navidrome change plugins folder 2026-09-01 02:38:13 -05:00
blake 939fb8d96b navidrome change plugins folder 2026-09-01 02:34:16 -05:00
blake 6b43e1e1d6 navidrome change plugins folder 2026-09-01 02:26:47 -05:00
blake 8915ff714f navidrome change plugins folder, give up 2026-09-01 02:11:27 -05:00
blake ec9ba4f0e5 navidrome change plugins folder 2026-09-01 02:10:01 -05:00
blake b481fd9c6b navidrome change plugins folder 2026-09-01 02:09:21 -05:00
blake dbf21fa3e9 navidrome change plugins folder 2026-09-01 02:07:39 -05:00
blake 5c928aac70 add yt-dlp nixos 2026-09-01 01:06:37 -05:00
blake 074fec8677 fix alias 2026-08-31 22:55:27 -05:00
blake 503b850943 fix alias 2026-08-31 22:53:40 -05:00
blake eff0c765c0 fix alias 2026-08-31 22:52:30 -05:00
blake b5deb4334f fix alias add ffmpeg 2026-08-31 22:45:35 -05:00
blake 785bdc4b32 fix alias add ffmpeg 2026-08-31 22:42:04 -05:00
blake a483ea764e add yt-dlp zsh alias 2026-08-31 22:35:05 -05:00
blake f232163920 add yt-dlp zsh alias 2026-08-31 22:23:42 -05:00
blake aec377046e add yt-dlp 2026-08-31 22:16:19 -05:00
blake d22c274a52 add picard 2026-08-31 21:53:51 -05:00
blake b4ab71c8cd fix stupidity 2026-08-31 19:04:13 -05:00
blake 7dde6470a4 fix ls on macos and other nav, passwdless lf 2026-08-31 19:01:49 -05:00
blake 11ab7440fa add lidarr to mediastack import 2026-08-31 14:38:21 -05:00
blake 72107e2339 add lidar 2026-08-31 14:36:30 -05:00
blake b21eeb5b66 take down uptime-kuma public 2026-08-31 12:31:22 -05:00
blake 4b9a6bf8cc disable runescape 2026-08-31 12:00:52 -05:00
blake 7113725038 vaultwarden ssh 2026-08-31 08:48:25 -05:00
blake d9885a92d5 trying to figure out ipv6 2026-08-26 16:48:03 -05:00
blake 1138e567e6 tailscale and brew fiddling 2026-08-26 14:52:39 -05:00
blake e66dfa5d61 updates 2026/8/26 2026-08-26 13:41:12 -05:00
blake 03c1d94677 add flo 2026-08-25 23:19:30 -05:00
blake d7c8c9e6fe peazip 2026-08-25 23:17:27 -05:00
blake 4a887023b9 peazip 2026-08-25 23:16:51 -05:00
blake 4debf084fe config nextdns 2026-08-25 23:15:59 -05:00
blake b885fc14ab move timemachine back to archives 2026-08-25 17:08:29 -05:00
blake 53b2a66d8e update ddns 2026-08-25 15:01:13 -05:00
blake 38fd7ec62e add more to glance 2026-08-25 14:34:44 -05:00
blake 01906fc345 add more to glance 2026-08-25 14:32:53 -05:00
blake f45b902e58 reorganize glance 2026-08-25 13:24:35 -05:00
blake 9fa860c86c config nextdns 2026-08-25 12:56:52 -05:00
blake d9864bbebf config nextdns 2026-08-25 12:49:08 -05:00
blake 7d23d676bf add nextdns for darwin 2026-08-25 12:42:51 -05:00
blake 08fa7027d8 reorganize proxys 2026-08-25 12:29:35 -05:00
blake 3e97b5cd67 configuring navidrome 2026-08-25 10:55:58 -05:00
blake 92a71ec2ba change glance order 2026-08-25 10:43:56 -05:00
blake 9f626a0f8e add navidrome 2026-08-25 10:33:04 -05:00
blake d6c5d3ded4 add navidrome 2026-08-25 10:32:08 -05:00
blake cc76377b37 enable ssh for root 2026-08-23 14:49:55 -05:00
blake 2ada0e3e3a add trusted keys for root 2026-08-23 14:42:45 -05:00
blake 7f74cd42b4 add script 2026-08-23 13:22:46 -05:00
blake 843f85e23e add script 2026-08-23 13:21:14 -05:00
blake 54f224a598 update glance for service move 2026-08-23 12:46:19 -05:00
blake e4ebae88fe update glance for service move 2026-08-23 12:44:30 -05:00
blake 688c96ae9a update glance for service move 2026-08-23 12:43:27 -05:00
blake 9396da0b8d fin git and vaultwarden move 2026-08-23 12:32:45 -05:00
blake 4016df88a5 stop forwarding 2026-08-23 12:27:34 -05:00
blake c0b661f83c fix new git ssh 2026-08-23 12:25:04 -05:00
blake a6b7d7f318 just a whole bunch of backup changes & move pass and git to vps 2026-08-23 12:12:44 -05:00
blake 9e475209e5 rsync over ssh for homelab 2026-08-23 11:31:53 -05:00
blake 556adde3a3 add option to backup to lumiose too 2026-08-23 11:28:27 -05:00
blake 0cc81e1126 add option to backup to lumiose too 2026-08-23 11:27:59 -05:00
blake 0f0857dd7c ssh updates 2026-08-23 11:19:48 -05:00
blake 6873fe64cb ssh updates 2026-08-23 11:18:36 -05:00
blake 603fbdc9ba ssh updates 2026-08-23 11:17:24 -05:00
blake 18bfb424f5 kde config 2026-08-23 11:13:17 -05:00
blake 64e56a615e fix module name 2026-08-23 10:59:41 -05:00
blake 671f157b8d add more borg options for dbs and offsite 2026-08-23 10:42:48 -05:00
blake 9736a86d9e add more borg options for dbs and offsite 2026-08-23 10:42:16 -05:00
blake e958a81b04 cleanup and fix borg on vaniville 2026-08-23 10:35:15 -05:00
blake 88819be7e7 enable option for homelab 2026-08-23 09:03:50 -05:00
blake 288724e86c move archives user 2026-08-23 09:01:09 -05:00
blake 583c997a62 kde 2026-08-23 08:57:51 -05:00
blake c2599ae219 move archives user 2026-08-23 08:57:14 -05:00
blake b2d33de709 move archives user 2026-08-23 08:54:56 -05:00
blake e21b3e7814 kde config 2026-08-23 08:47:45 -05:00
blake ec24d8c518 kde 2026-08-23 08:36:51 -05:00
blake 5466f8eb44 enable backups test 2026-08-23 08:27:12 -05:00
blake b5b544b83f enable backups test 2026-08-23 08:26:08 -05:00
blake 966780e7c4 updates 2026-08-23 08:25:38 -05:00
blake 24d104ad60 2026-8-3 updates 2026-08-23 07:33:36 -05:00
blake 4a79e6e3a1 smb settings for nvr 2026-08-12 01:24:12 -05:00
blake a1cbc554d8 smb settings for nvr 2026-08-12 01:16:18 -05:00
blake cc4f628ea6 smb settings for nvr 2026-08-12 01:15:57 -05:00
blake 2fc89120a8 add archives user 2026-08-12 01:07:56 -05:00
blake 11d6dde229 add change nvr settings 2026-08-12 00:50:09 -05:00
blake af2fc02d97 add nvr smb share 2026-08-07 17:49:44 -05:00
blake 3382f30b9d add zygarde to ssh 2026-08-07 04:25:27 -05:00
blake 3252c941aa enable expramental event entities for thirdreality buttons 2026-08-07 03:44:33 -05:00
blake 5447afbf61 change interface 2026-08-07 01:27:21 -05:00
blake a5f624b6b7 updates 2026-08-01 09:50:26 -05:00
blake af3a35cdec finish up kiwix 2026-07-30 12:36:53 -05:00
blake 4e0c40e83b remove homebox being in media group 2026-07-30 12:21:27 -05:00
blake 6ab43ae093 init nomad 2026-07-30 12:21:03 -05:00
blake 2e3b829118 fin homebox 2026-07-29 16:37:32 -05:00
blake ed0f761f7b homebox fix description 2026-07-29 16:25:03 -05:00
blake 888946cbc2 add homebox 2026-07-29 16:23:52 -05:00
blake 9fd96c57d6 add homebox 2026-07-29 16:23:37 -05:00
blake 8d4fcda2ce clean up testing 2026-07-28 10:25:05 -05:00
blake ff4759a368 testing new ssl with sonarr 2026-07-28 09:46:58 -05:00
blake 7f1db3ec3a setup caddy for ssl via dns with cloudflare 2026-07-28 09:44:28 -05:00
blake e5b8d6eb94 setup caddy for ssl via dns with cloudflare 2026-07-28 09:38:58 -05:00
blake 67527c2ef9 setup caddy for ssl via dns with cloudflare 2026-07-28 09:38:19 -05:00
blake 9659dcf9ef setup caddy for ssl via dns with cloudflare 2026-07-28 09:36:33 -05:00
blake 79a04d45a4 update mc server monitoring name 2026-07-27 12:50:42 -05:00
blake 887b8f3953 fix title for caddy page 2026-07-27 12:05:05 -05:00
blake e36095c1d7 properly implement a toggle for the keys subdomain 2026-07-27 12:01:37 -05:00
blake f36d67b29a adjust hosts for keys 2026-07-27 12:00:37 -05:00
blake 58c7919936 properly implement a toggle for the keys subdomain 2026-07-27 11:57:24 -05:00
blake 34254ffd93 add sops for modded mc 2026-07-23 13:08:29 -05:00
blake 649de1ce1a add sops for modded mc 2026-07-23 13:05:17 -05:00
blake 3db2962b85 add sops for modded mc 2026-07-23 12:58:45 -05:00
blake a27d6b11c0 add offsite backup support to modded mc 2026-07-23 12:57:03 -05:00
blake bd37a7bbd4 update lifeboat link in glance 2026-07-23 12:22:04 -05:00
blake 7f0e96b058 updates 2026-07-23 11:36:34 -05:00
blake 776e68e1e6 server modded swap 2026-07-23 10:45:14 -05:00
blake 1ded87909f fix tailscale routing shit 2026-07-23 10:41:20 -05:00
blake 479a8b2e03 update cen-it-07 syncthing id 2026-07-22 12:45:59 -05:00
blake 1e206de4c0 rectangle to brew 2026-07-15 16:01:21 -05:00
blake df71394956 update lifeboat ip 2026-07-15 09:05:02 -05:00
blake 4c89bf0f72 updates 2026-07-14 17:20:38 -05:00
blake dd3c2f817f spelling mistake 2026-07-09 22:37:00 -05:00
blake 89ee4bdfd4 tailscale accept routes 2026-07-09 22:19:31 -05:00
blake 5746e0144f fix caddy 2026-07-02 10:22:54 -05:00
blake 7297aaa8fb apps or some shit 2026-07-02 00:16:07 -05:00
blake adec4a5c2e add snowbelle back to subnets baby 2026-07-01 23:26:21 -05:00
blake 41211b41bb fix firewall 2026-07-01 23:25:24 -05:00
blake b18c04df36 fix port 2026-07-01 23:17:50 -05:00
blake 32a5121936 update craftoria port add voicechat 2026-07-01 23:16:28 -05:00
blake 5b9d15b2ce update craftoria port add voicechat 2026-07-01 23:15:17 -05:00
blake adcdfd604c update craftoria port 2026-07-01 23:09:14 -05:00
blake a23a211d89 fix port 2026-07-01 23:06:21 -05:00
blake 78e0b6723b finish craftoria 2026-07-01 23:01:17 -05:00
blake 84ba07b035 finish craftoria 2026-07-01 23:00:47 -05:00
blake 59ac5e92d9 sort out the jar situation 2026-07-01 22:52:44 -05:00
blake 7505abb756 craftoria 2026-07-01 22:36:25 -05:00
blake 6dca018d13 craftoria 2026-07-01 22:35:38 -05:00
blake a52b181b27 craftoria 2026-07-01 22:33:32 -05:00
blake 36cf6156e1 craftoria 2026-07-01 22:32:59 -05:00
blake ae0c4a9df2 modded i guess 2026-07-01 22:30:51 -05:00
blake 9e3955a0f9 test adding gimp back, add thudnerbird 2026-06-30 09:19:04 -05:00
blake 32efe6cb40 test adding gimp back, add thudnerbird 2026-06-30 09:18:19 -05:00
blake 0ab66f480b add back unifi 2026-06-29 08:04:07 -05:00
blake e8d3dbfc74 relabel ports 2026-06-29 08:03:20 -05:00
blake 6343f90947 add open port for homekit 2026-06-28 21:50:03 -05:00
blake 1ac6fc6e66 update glance check url for shauna 2026-06-28 21:40:14 -05:00
blake 0ecbead350 reduce keepalive interval 2026-06-24 15:51:22 -05:00
blake b5fe99371f disable backups 2026-06-24 15:48:12 -05:00
blake b24a3df88c update keepalive urls 2026-06-24 15:43:17 -05:00
blake 82cb5a742c add unas to subnet router 2026-06-24 10:49:20 -05:00
blake 77067724ce set static on vpn 2026-06-23 20:55:11 -05:00
blake 182e5abbbf try and spoof mac addr on vpn 2026-06-23 20:37:52 -05:00
blake 8abbd70e3d add keepass 2026-06-23 09:01:04 -05:00
blake 39eb846407 update glance links 2026-06-22 16:44:35 -05:00
blake d47a7580ed update vaultwarden reverse proxy 2026-06-22 16:35:30 -05:00
blake e93f8cd4ee vaultwarden updates 2026-06-22 16:19:38 -05:00
blake dd3bd26b60 vaultwarden updates 2026-06-22 16:15:46 -05:00
blake 9a204bce60 vaultwarden updates 2026-06-22 16:14:18 -05:00
blake 36a6ec23b3 vaultwarden updates 2026-06-22 15:54:23 -05:00
blake 279340f744 update ssh alias, add gateway to advertise for now 2026-06-22 10:52:14 -05:00
blake b4201cfeb4 zfs aliases 2026-06-21 02:58:30 -05:00
blake f444756575 disable test msg 2026-06-20 20:46:35 -05:00
blake 6f3999c1f9 move msmtp to dedicated file 2026-06-20 20:44:09 -05:00
blake 351613d392 move msmtp to dedicated file 2026-06-20 20:43:16 -05:00
blake ffaf77793f move msmtp to dedicated file 2026-06-20 20:42:28 -05:00
blake 4d3ef01876 mudkip to piplup rename 2026-06-20 20:35:14 -05:00
blake 779a6c4f41 zfs autosnapshots 2026-06-20 20:34:41 -05:00
blake ab2f0a6e6a holocron backups 2026-06-20 15:15:08 -05:00
blake a8811af514 make rsync work 2026-06-20 14:36:20 -05:00
blake c175baefbf add offsite backup support to borg 2026-06-20 14:08:16 -05:00
blake 168f95d219 add offsite backup support to borg 2026-06-20 14:07:47 -05:00
blake e91ab96980 change lifeboat password 2026-06-20 14:06:47 -05:00
blake 357a5b9c09 add offsite backup support to borg 2026-06-20 14:05:10 -05:00
blake 2fe99b250f open homekit ports 2026-06-19 15:14:16 -05:00
blake 5216b65607 update syncthing domain 2026-06-18 00:53:01 -05:00
blake 2c87bff5cd troubleshoot weird routing issues 2026-06-18 00:52:24 -05:00
blake bbb70a66ed troubleshoot weird routing issues 2026-06-18 00:52:24 -05:00
blake 2241045cbb update host ip 2026-06-18 00:41:42 -05:00
blake 9d3f5bfaae clean up old domain 2026-06-18 00:25:03 -05:00
blake 5b5a6bcd1c add holocron.blue homelab config 2026-06-17 23:05:08 -05:00
blake e2ef9cbad1 add holocron.blue homelab config 2026-06-17 23:02:12 -05:00
blake 5b31c91d28 switch to holocron.blue ssh/git 2026-06-17 22:54:01 -05:00
blake 37f263e984 switch to holocron.blue 2026-06-17 22:47:37 -05:00
blake 1b4dee14ed switch to holocron.blue 2026-06-17 22:47:20 -05:00
blake 233e1a4773 add holocron.blue to ddns 2026-06-17 22:40:32 -05:00
blake a743bbbc30 add holocron.blue to ddns 2026-06-17 22:36:56 -05:00
blake 3d74ff5556 networking bs 2026-06-17 22:35:21 -05:00
blake 6b16a885e3 redo networking properly, god speed me 2026-06-17 18:54:11 -05:00
blake 14f5e3e2dc batterytool-kit is archived, switching to built in limiter 2026-06-16 10:56:40 -05:00
blake 4ccb658ca8 batterytool-kit is archived, switching to built in limiter 2026-06-16 10:55:51 -05:00
blake 74bc8e7f3f add yacreader 2026-06-16 10:44:32 -05:00
blake 0e55f4e2f0 lay groundwork for radicale: 2026-06-14 20:45:57 -05:00
blake 6b0744330b motd make gameservers inclusion more conditional 2026-06-14 13:48:44 -05:00
blake a97b7fb2c3 update tailscale motd 2026-06-14 11:01:46 -05:00
blake 4b537c7fe8 add everything to motd 2026-06-14 10:58:53 -05:00
blake 2c7e21f64d more cleanup 2026-06-14 09:29:50 -05:00
blake 23c7358939 update mc modded for new motd 2026-06-14 09:14:42 -05:00
blake c1ae91491a move condiditon to motd script 2026-06-14 09:12:20 -05:00
blake 982d208b13 motd more conditional 2026-06-14 09:06:59 -05:00
blake f07bbbef01 conditional motd in the motd config 2026-06-14 09:02:57 -05:00
blake 7c18ecebab conditional motd in the motd config 2026-06-14 09:01:58 -05:00
blake 5890c3e461 file cleanup, conditional motd 2026-06-14 08:42:12 -05:00
blake 41df12b164 file cleanup, conditional motd 2026-06-14 08:38:34 -05:00
blake 18c19b2823 file cleanup, conditional motd 2026-06-14 08:37:23 -05:00
blake 66d17dfde1 file cleanup, conditional motd 2026-06-14 08:36:27 -05:00
blake 5bb3d44c8c file cleanup, conditional motd 2026-06-14 08:36:07 -05:00
blake 11d3fcd8ec file cleanup, conditional motd 2026-06-14 08:35:44 -05:00
blake fcb8961c69 test automatical inculstion in motd 2026-06-14 07:56:34 -05:00
blake 85a97ddb47 rename old holocron files 2026-06-14 07:47:03 -05:00
blake c11c04394c add vaniville to lumiose ssh conf 2026-06-14 00:15:13 -05:00
blake ff5cb7a865 make this build 2026-06-13 23:39:04 -05:00
blake fcd957443a make yveltal work after all these damn changes 2026-06-13 22:55:05 -05:00
blake 1606dd97d4 updates 2026-06-13 19:13:42 -05:00
blake 7c58261db8 fix ssh warning 2026-06-13 19:12:32 -05:00
blake f7fecbe8ad add then disable lan vlan connection 2026-06-13 19:06:28 -05:00
blake 310b332178 disable cobblemon 2026-06-13 14:34:45 -05:00
blake 087365d239 fin holocron zfs on snowbelle 2026-06-13 14:31:32 -05:00
blake a34c177b69 formatting 2026-06-13 14:29:16 -05:00
blake 0edc17ecde shut down cobblemon 2026-06-13 13:57:38 -05:00
blake 05fcf51fbd disable mc servers on snowbelle 2026-06-13 13:55:08 -05:00
blake 76fbf8ff9c disable mc servers on snowbelle 2026-06-13 13:54:32 -05:00
blake 5354a9ad0d move mc servers to lumiose 2026-06-13 13:53:31 -05:00
blake 45b1ded302 change mc server networking to lumiose 2026-06-13 13:53:22 -05:00
blake fa15da2778 test time machine service addition 2026-06-13 03:22:25 -05:00
blake 09fd696b1d test time machine service addition 2026-06-13 03:16:18 -05:00
blake 406b923226 disable ai 2026-06-13 00:37:25 -05:00
blake 9aef75b7ba enable syncthing 2026-06-12 23:55:57 -05:00
blake 53598b5997 disable homelab on snowbelle 2026-06-12 23:54:30 -05:00
blake 1c5c21612a enable dns and update ip address 2026-06-12 23:54:04 -05:00
blake 01e420aa8d enable dns and update ip address 2026-06-12 23:54:04 -05:00
blake a422358acd source dedicated server shenangans 2026-06-12 23:54:04 -05:00
blake d5f619ce4d add srcds 2026-06-12 23:54:04 -05:00
blake 981a7b0c4a add cs2 server 2026-06-12 23:54:04 -05:00
blake 6509775612 add cs2 server 2026-06-12 23:54:04 -05:00
blake f82f08098c disable homelab on snowbelle 2026-06-12 22:05:29 -05:00
blake 9265c4f4b1 disable homelab on snowbelle 2026-06-12 22:04:54 -05:00
blake f94dbf9d0d disable homelab on snowbelle 2026-06-12 22:04:29 -05:00
blake 437bf5939f disable homelab on snowbelle 2026-06-12 22:03:56 -05:00
blake d426607907 add cs2 server 2026-06-12 21:54:17 -05:00
blake 67392b4a45 add cs2 server 2026-06-12 21:53:58 -05:00
blake c37ff5dd4c add cs2 server 2026-06-12 21:53:24 -05:00
blake 3283cac3e8 fix immich and syncthing 2026-06-12 21:30:20 -05:00
blake e0e298b63f prep syncthing 2026-06-12 21:00:42 -05:00
blake 1953f417dd update immich config 2026-06-12 20:50:56 -05:00
blake bd8c18b76b update ssh config for git 2026-06-12 20:42:16 -05:00
blake c02b5a997a update ssh config for git 2026-06-12 20:35:57 -05:00
blake 4ef203bcc4 update forwarding ip 2026-06-12 20:28:34 -05:00
blake c908cb3d00 add vpn interface to qbit 2026-06-12 18:51:06 -05:00
blake d7362dee01 add vpn interface to qbit 2026-06-12 18:50:44 -05:00
blake 028c06cad3 add vpn vlan 2026-06-12 18:21:33 -05:00
blake c1dce7bab1 update var names 2026-06-12 17:17:28 -05:00
blake e225cde934 reinit lumiose 2026-06-12 17:13:00 -05:00
blake 105550e5f1 reenable ollama and webui 2026-06-03 16:18:25 -05:00
blake 164a67b968 disable AI stuff: 2026-06-03 16:15:25 -05:00
blake f960c8226c reenable ollama and webui 2026-06-03 16:07:04 -05:00
blake cb3ea8d9aa reenable ollama and webui 2026-06-03 16:06:34 -05:00
blake 3de20a07f8 reenable ollama and webui 2026-06-03 16:06:01 -05:00
blake a1c365128f reenable ollama and webui 2026-06-03 16:05:38 -05:00
blake 2fc0cb525d hass caddy config 2026-06-02 17:08:55 -05:00
blake 898a752414 update hass caddy 2026-06-02 17:08:02 -05:00
blake e319a94240 add zen browser 2026-06-02 10:05:36 -05:00
blake ec5f561b98 add unifi network app to config 2026-06-02 08:56:59 -05:00
blake 1195c8a65c make hass work again 2026-05-30 19:19:09 -05:00
blake 88740fe1e1 updates for lumiose 2026-05-30 12:18:03 -05:00
blake f12641e063 make yveltal work after all these damn changes 2026-05-30 12:06:47 -05:00
blake 8f3000cde0 update syncthing url 2026-05-30 10:15:36 -05:00
blake a030e09887 update ssh key shit 2026-05-30 10:14:06 -05:00
blake 46dcb607d8 26.05 2026-05-30 09:47:50 -05:00
blake c84484257c disable AI, prep for new release 2026-05-30 09:14:08 -05:00
blake f2b1c99a85 disable AI, prep for new release 2026-05-30 09:13:30 -05:00
blake f814db20fe disable AI shit, finish immich sync service 2026-05-28 15:33:54 -05:00
blake 84a775a0cb add rysnc immich library sync service 2026-05-28 12:23:18 -05:00
blake b15a146bee add rysnc immich library sync service 2026-05-28 12:20:32 -05:00
blake 4a1d300112 add rysnc immich library sync service 2026-05-28 12:18:52 -05:00
blake 1d000537aa add rysnc immich library sync service 2026-05-28 12:16:54 -05:00
blake 1af229350d enable app expose gesture 2026-05-14 10:03:20 -05:00
blake 9a628121ae formatting 2026-05-14 09:36:30 -05:00
blake 16c9b425c1 update bebe url 2026-05-13 17:22:02 -05:00
blake e7323bd7d6 test if prev commit worked by disabling the explicit setting of dns 2026-05-13 17:04:07 -05:00
blake a5a01250c1 make dnsmasq ignore resolv and temp disable fallback dns 2026-05-13 17:02:44 -05:00
blake 83c83e6bc8 dns swapover 2026-05-12 23:22:03 -05:00
blake 37796783ad test fqdn 2026-05-11 13:11:48 -05:00
blake f24687c060 add is linux, reformatting 2026-05-11 09:12:54 -05:00
blake f9af5f71fe make yveltal work after all these damn changes 2026-05-08 16:58:42 -05:00
blake 98e8ccd17c add fine tune 2026-05-06 08:36:02 -05:00
blake 22bdee4af6 typo 2026-05-05 09:35:38 -05:00
blake bb33a9470a have tailscale use up variable 2026-05-05 09:35:07 -05:00
blake 36a022ef0a fix format 2026-05-04 16:16:02 -05:00
blake d7a55abee2 restructure and cleanup 2026-05-04 15:32:16 -05:00
blake 7d0fb6ab9b add kde 2026-05-04 14:27:51 -05:00
blake a587da82d5 add macos specific setting to smb shares 2026-05-04 11:12:05 -05:00
blake 4f7950922d change order for glance 2026-05-04 09:29:30 -05:00
blake 1335254681 temp remove searxng 2026-05-03 13:21:31 -05:00
blake 24eccf83e2 restructure homelab nixfiles 2026-05-03 12:36:43 -05:00
blake e34a41ee7d add searnxg 2026-05-03 12:15:07 -05:00
blake f97d97a570 formatting & test cuda support 2026-05-03 12:03:57 -05:00
blake 4d552be249 remove all grammars and fix pkgs with new setup 2026-05-03 10:44:55 -05:00
blake 3c5f6cedeb remove all grammars and fix pkgs with new setup 2026-05-03 10:43:12 -05:00
blake b91a72f6c8 formatted 2026-05-03 10:36:44 -05:00
blake 4f117ac83f fix indents 2026-05-03 10:10:41 -05:00
blake 0d73aa3087 indent and format changes 2026-05-03 09:24:24 -05:00
blake 27555fe856 replace unstable stuff with overlay 2026-05-03 09:19:47 -05:00
blake 402a9cb771 add AI stack 2026-05-03 08:44:20 -05:00
blake fd7e99c6f1 add AI stack 2026-05-03 08:31:38 -05:00
blake bdd11a2e31 add open-webui 2026-05-03 08:30:41 -05:00
blake 8588d7a90d add ollama 2026-05-03 08:28:11 -05:00
blake 3937764ab1 add ollama 2026-05-03 08:27:44 -05:00
blake 6e3e135a95 add ai and update glance search urls 2026-05-03 08:18:27 -05:00
blake cada87bb75 fix keys 2026-05-02 23:36:17 -05:00
blake 934544883a just make this a proxy for the udrs dns 2026-05-02 23:29:06 -05:00
blake 5ad154ec37 add private to backup path 2026-05-02 23:15:33 -05:00
blake 2ed9cb285d remove homelab.bak 2026-05-02 18:00:19 -05:00
blake 5b4ee10875 update keepalive urls 2026-05-02 17:58:03 -05:00
blake ed4a898f83 add mediastack layer 2026-05-02 17:52:39 -05:00
blake 7302648b57 test restructure 2026-05-02 17:43:53 -05:00
blake 6fdc826b2a add restart to dnsmasq 2026-05-02 16:55:03 -05:00
blake 31683a89ed add restart to dnsmasq 2026-05-02 16:53:07 -05:00
blake aef547aefc open iperf3 port 2026-05-02 16:28:30 -05:00
blake c86fe27ea7 reverse proxy fin 2026-05-02 13:22:01 -05:00
blake 6dc36a7295 take abs off public net 2026-05-02 13:21:19 -05:00
blake 17a4e2f138 reverse proxying from vaniville 2026-05-02 12:36:21 -05:00
blake 7fddefba21 updates 2026-05-02 12:36:00 -05:00
blake 9dd2015202 tailscale on lumiose 2026-05-02 11:21:15 -05:00
blake faf9343022 update keep alives 2026-05-02 03:04:01 -05:00
blake 6059b4ef57 tails shit 2026-05-02 02:43:36 -05:00
blake 02e9dacab5 fix it all 2026-05-02 02:39:32 -05:00
blake 3ec8db578d uptime kuma public 2026-05-02 02:23:46 -05:00
blake a24f033d12 caddy secret fix 2026-05-02 02:18:25 -05:00
blake 8e0d283df0 add caddy 2026-05-02 02:16:41 -05:00
blake 5cc23aa500 update ddns for uptime 2026-05-02 02:16:01 -05:00
blake d78601bf02 cleanup 2026-05-02 01:42:12 -05:00
blake b87423350b enable homelab on lumisoe 2026-05-02 01:19:53 -05:00
blake b7002121ea touch up 2026-05-02 01:09:51 -05:00
blake 21cef8c106 add caddy root crt to sops 2026-05-02 01:08:01 -05:00
blake d2bbf6b287 rsycn passwdless 2026-05-02 01:03:01 -05:00
blake 5aaa24798d sshshit 2026-05-02 00:55:22 -05:00
blake 3c7c2b7599 sshshit 2026-05-02 00:54:06 -05:00
blake 646e263591 sshshit 2026-05-02 00:50:36 -05:00
blake 4a0c476599 sshshit 2026-05-02 00:49:31 -05:00
blake 958fd9519d add snowbelle ssh key 2026-05-02 00:47:05 -05:00
blake 9ca91b0445 add snowbelle ssh key 2026-05-02 00:37:25 -05:00
blake ebfb46082f add keys file host 2026-05-02 00:33:50 -05:00
blake d7af3ae96f tls to internal 2026-05-02 00:03:31 -05:00
blake d2fec2e53d remove hardcoded snowbelle 2026-05-01 17:58:53 -05:00
blake bcb37120e0 add wsl config 2026-05-01 14:45:14 -05:00
blake 31d59f89a9 add wsl config 2026-05-01 14:44:28 -05:00
blake fe112cb380 wyoming fin 2026-05-01 02:39:04 -05:00
blake d84db54669 wyoming testing start 2026-05-01 02:23:24 -05:00
blake e781ca769b wyoming testing start 2026-05-01 02:22:43 -05:00
blake ba07db9dbf holocron now automounts 2026-05-01 01:59:03 -05:00
blake d77ba8c4a1 add lumiose to ssh config 2026-05-01 01:54:20 -05:00
blake 6f1a27648d smartd emails working 2026-05-01 01:48:33 -05:00
blake 2b3c0e71d5 fixup from addr 2026-05-01 00:51:09 -05:00
blake 08fb5b3adf fixup address 2026-05-01 00:46:38 -05:00
blake cb98b17f44 add mail i guess for some reason im doing this LMAO 2026-05-01 00:43:59 -05:00
blake 2bfabc246a temp disable copy party and syncthing 2026-05-01 00:28:29 -05:00
blake d3e5528951 temp disable copy party and syncthing 2026-05-01 00:25:24 -05:00
blake 4a02453b74 wyoming dev 2026-05-01 00:20:36 -05:00
blake b3ab37b40b rename to wyoming 2026-04-30 19:51:00 -05:00
blake 1194076dc2 add ability to use local voice assistant 2026-04-30 19:48:21 -05:00
blake 1b1244d2db update zfs to not use file systems and add keep alive to lumiose in prep for networking 2026-04-30 19:40:16 -05:00
blake 9c967dd96a I have decided I am just moving holocron to lumiose, this is the temp files to not break snowbelle 2026-04-30 19:16:43 -05:00
blake 5fd3cfa3cd update time machine share settings 2026-04-30 18:50:29 -05:00
blake 87eeda1744 move fileshares to subdir 2026-04-30 18:36:14 -05:00
blake 00ca8596cb add bebe to dns 2026-04-28 23:42:56 -05:00
blake ebfd5df134 add allow for expansion of dns 2026-04-28 15:28:39 -05:00
blake 4bb8ecb146 add always run to dnsmasq 2026-04-28 15:25:24 -05:00
blake 4edd79feac add wifiman 2026-04-28 10:43:12 -05:00
blake aafb198c42 add smartmontools to default nix pkgs 2026-04-27 17:20:53 -05:00
blake 0b15109b85 add import for keepalive 2026-04-27 16:23:46 -05:00
blake 875f016242 temp disable caddy 2026-04-27 16:06:56 -05:00
blake 2530341c1f add keepalive url 2026-04-27 15:38:25 -05:00
blake 2df4812035 disable caddy for now, issue is with forwarding port 80 and 443 2026-04-27 15:34:24 -05:00
blake 6312d24aa9 remove key link 2026-04-27 14:54:43 -05:00
blake 7d97fdee7a add hardware config handling to bootstrap 2026-04-27 14:52:14 -05:00
blake 6d194f8103 add keepalive config to snowbelle 2026-04-27 14:18:20 -05:00
blake a0980ffd87 add keepalive to system config for uptime kuma monitoring 2026-04-27 14:16:14 -05:00
blake c64fbb845c add caddy 2026-04-27 14:03:35 -05:00
blake 1148340fad clean up file and add uptime kuma 2026-04-27 14:01:06 -05:00
blake 2c14ad4a2a works wonderfully now! 2026-04-26 03:46:28 -05:00
blake 8f7868b0a4 fix hardware issues 2026-04-26 03:46:15 -05:00
blake 681ef9ae6e bootstrap optimizations 2026-04-26 03:18:41 -05:00
blake 64d4f36d4d lumiose setup fin 2026-04-26 03:15:29 -05:00
blake 559d5615ea updates for script 2026-04-26 03:12:58 -05:00
blake c6af375164 lumiose stuff finished up 2026-04-26 03:08:32 -05:00
blake 320a4be81c finishing touches for lumiose 2026-04-26 02:12:05 -05:00
blake 37bc3712dd paste in ai generated bootstrap script 2026-04-26 02:09:04 -05:00
blake 0dd7cf5cd6 add lumiose, init install notes 2026-04-26 01:54:04 -05:00
blake c631ad5e05 add lumiose, init install notes 2026-04-26 01:19:47 -05:00
blake 594132d038 add lumiose 2026-04-26 01:16:10 -05:00
blake 9b4d196371 add runescape 2026-04-25 02:17:38 -05:00
blake f425ca7fd4 add runelite 2026-04-25 02:12:59 -05:00
blake d6a7761524 remove slippi nonsense 2026-04-25 00:32:17 -05:00
blake e3a85a83dd make config overlay consistent 2026-04-25 00:29:15 -05:00
blake 83e0903edb remove temp config 2026-04-24 20:24:27 -05:00
blake 7bda8925e8 add torrent kit 2026-04-24 19:10:27 -05:00
blake ce4ccab1c0 add discord 2026-04-24 18:37:21 -05:00
blake d663a17046 update ssh keys 2026-04-24 18:09:53 -05:00
blake 782e73745f update ssh keys 2026-04-24 18:08:17 -05:00
blake 223d7f8fec add vaniville to ssh config 2026-04-24 17:54:50 -05:00
blake 2f1bbf3e62 add vaniville to ssh config 2026-04-24 17:54:39 -05:00
blake db0e912139 cloudflare ddns and network forwarding fin 2026-04-24 16:23:49 -05:00
blake fe1242a5fd adding ddns with cloudflare 2026-04-24 15:47:57 -05:00
blake 56b0db801e tailscale forwarding is working 2026-04-24 15:27:06 -05:00
blake 909b25c217 enable dhcp for internet 2026-04-24 14:28:20 -05:00
blake 9ea854565d make preps for linnode 2026-04-24 12:43:50 -05:00
blake 837b38594a update ts auth key 2026-04-24 12:25:52 -05:00
blake 08c91e1671 add more apps 2026-04-24 03:48:25 -05:00
blake 4826f78894 add more cyber tools 2026-04-24 03:19:09 -05:00
blake d6f208de92 breakout cyber apps 2026-04-24 03:05:56 -05:00
blake 2b309abe9e fix neovide by installing w/ nix 2026-04-24 02:06:14 -05:00
blake 4188371e9a fix nvf by killing neovide 2026-04-24 02:01:32 -05:00
blake 6c88add21a ssh config 2026-04-24 01:41:52 -05:00
blake 5466cd4a27 ssh config 2026-04-24 01:40:12 -05:00
blake c93e3ed8ae add ssh config for snowbelle 2026-04-24 01:21:53 -05:00
blake 93563ba2d8 ssh key for macos and nvf edits 2026-04-24 01:18:12 -05:00
blake a41407b123 nvf testing 2026-04-24 01:16:03 -05:00
blake 9ae3b7e98e add ssh darwin 2026-04-24 01:07:21 -05:00
blake 3f9a9eedc0 nvf off of v0.8 pin 2026-04-24 00:56:28 -05:00
blake b344da8950 remove daisy disk 2026-04-24 00:28:05 -05:00
blake d1300baadd add jumpdesktop 2026-04-24 00:23:11 -05:00
blake 0b975a2f18 add more mac apps and gaming stuff 2026-04-23 22:00:20 -05:00
blake 4100adbc0b add more mac apps and gaming stuff 2026-04-23 22:00:09 -05:00
blake 5bf33a9c6b updates 2026-04-23 21:59:49 -05:00
blake e0775ca7e6 macos finishing touches 2026-04-23 20:55:52 -05:00
blake 66b5af02b1 mas rebuild error fix 2026-04-23 19:53:32 -05:00
blake 47dfb00e43 macos working like a charm 2026-04-23 19:12:13 -05:00
blake 9f8104e7b8 first macos attempt 2026-04-23 19:11:58 -05:00
blake 8563489682 move system settings to darwin default 2026-04-23 15:56:45 -05:00
blake 1ec90889e4 breakdown work and genral apps to be modular 2026-04-23 15:53:00 -05:00
blake 6dd0ab1eea fix oopsie again 2026-04-23 15:32:38 -05:00
blake 9b3d344fb5 fix oopsie 2026-04-23 15:27:16 -05:00
blake 6eb4ddf0a5 add yubikey 2026-04-23 15:26:36 -05:00
blake 1a609d14dc add yubikey 2026-04-23 15:26:14 -05:00
blake f6011be1d1 sops is no go, made syncthing and tailscale modular for no reason 2026-04-23 15:20:27 -05:00
blake 48cac1436a darwin modules 2026-04-23 14:53:37 -05:00
blake 6dcd5201b5 add git stuff to lf 2026-04-22 14:15:35 -05:00
blake 8b2659ded5 add user 2026-04-21 05:16:26 -05:00
blake b1aa39af57 add macos system settings to config 2026-04-21 04:47:53 -05:00
blake 9a1b1a99c6 add list of apps for refrence 2026-04-20 16:49:55 -05:00
blake a9a2e17261 add mas for app store apps 2026-04-20 16:37:15 -05:00
blake d81be14cfb add mas for app store apps 2026-04-20 16:35:41 -05:00
blake f918502587 prep for vaniville to be nix 2026-04-20 15:56:15 -05:00
blake 08b4a7de24 macos config continues, pretty much done just migrate some lists from brew 2026-04-20 15:22:19 -05:00
blake 48b0ea202f macos modifications 2026-04-20 10:20:35 -05:00
blake dcd8459904 macos is building, yippee 2026-04-16 17:08:55 -05:00
blake 0e6ec014eb macos is building 2026-04-16 17:07:34 -05:00
blake 089a38bdcf udiskie is not core bro what was I smokin 2026-04-16 17:06:13 -05:00
blake 8a3292d81c macos is building 2026-04-16 17:05:28 -05:00
blake c303142659 macos might actually build 2026-04-16 16:55:59 -05:00
blake 9112d9402d macOS shit 2026-04-16 15:49:34 -05:00
blake 1c48ba8c9d add ds_store to ignore 2026-04-07 19:01:57 -05:00
blake 9620100aa1 init macos shit 2026-04-07 19:00:53 -05:00
blake c02f808d49 darwin config 2026-04-07 19:00:49 -05:00
blake c364d6dd74 updates 2026-04-06 16:56:06 -05:00
blake 04b7752ac8 updates 2026-04-06 16:51:57 -05:00
blake d1de74d177 updates 2026-04-06 16:49:29 -05:00
blake aef886a880 add mudkip to syncthing 2026-02-27 17:58:22 -06:00
blake c9193fc7bd updates and pin vaultwarden to unstable 2026-02-27 15:38:13 -06:00
blake f6230480f5 updates and pin vaultwarden to unstable 2026-02-27 15:37:10 -06:00
blake d81469e9bc updates and pin vaultwarden to unstable 2026-02-27 15:36:54 -06:00
blake 1f4494d333 fix postfix hopefully 2026-01-28 15:09:47 -06:00
blake 85255adb2c fix postfix hopefully 2026-01-28 14:10:10 -06:00
blake f251a6f5c7 fix postfix hopefully 2026-01-28 13:48:37 -06:00
blake 1f84cf19c7 fix postfix hopefully 2026-01-28 12:28:14 -06:00
blake 0e49c1b9ee add japanese fonts and input 2026-01-09 23:10:42 -06:00
blake 3ff5251b15 add yveltal back to device list 2026-01-09 20:23:13 -06:00
blake 007c66c007 device list on syncthing 2026-01-09 20:17:00 -06:00
blake d37a0ce652 updates for mew setup 2026-01-09 20:00:08 -06:00
blake 5ab6c9e4c8 add anki 2026-01-09 19:46:02 -06:00
blake fccec4d504 add anki 2026-01-09 19:45:49 -06:00
blake 8feda54866 updates for mew setup 2026-01-09 19:18:15 -06:00
blake 7179e6f047 mew added 2026-01-09 18:50:18 -06:00
blake 1da9d994de add new host 2026-01-09 18:02:44 -06:00
blake e213c64481 add key for ipad 2026-01-09 00:02:43 -06:00
blake 49ac3c2bf5 add ipad to syncthing client 2026-01-08 16:32:21 -06:00
blake 8acebb13cc add ipad to syncthing fixed 2026-01-08 16:28:56 -06:00
blake ff08538bae add ipad to syncthing 2026-01-08 16:26:40 -06:00
blake 494ac6cf57 switch back to listen address 2025-12-30 13:53:50 -06:00
blake 4cfddd2c7e updates 2025-12-30 13:30:18 -06:00
blake 60509f93f0 fix proxys 2025-12-27 21:02:34 -06:00
blake 96d8fd1129 bind dns to interfact rather then ip 2025-12-13 13:20:55 -06:00
blake 39264279e0 add cobblemon to motd 2025-12-04 20:59:21 -06:00
blake 07c9533255 fix ssh message 2025-12-04 20:32:30 -06:00
blake 015f416169 finish cobblemon, add to glance 2025-12-04 20:30:00 -06:00
blake 35d8c83423 fix postfix 2025-12-04 20:13:38 -06:00
blake b488af297a fixin cobblemon, and new version warning finally GOD 2025-12-04 20:10:35 -06:00
blake dbb5560793 fixin cobblemon 2025-12-04 20:01:52 -06:00
blake 7bcfef3ccf enable cobblemon and modded mc in general 2025-12-04 19:57:06 -06:00
blake a1fd3b3af2 fix postfix 2025-12-04 19:44:13 -06:00
blake a45d9014dd 25.11 2025-12-04 19:39:07 -06:00
blake 80451e9430 added cobblemon 2025-12-04 19:37:52 -06:00
blake df1a77f73e added cobblemon 2025-12-04 19:37:40 -06:00
blake 6f51671dbb updates 2025-11-25 19:28:49 -06:00
blake a238d2b61c updates 2025-11-20 16:56:11 -06:00
blake 62dd3f5d7c darwin updates 2025-11-17 15:43:55 -06:00
blake 8b8dc8cde8 show casing shit 2025-11-17 15:37:38 -06:00
blake 3047ff97b4 add wallpapers 2025-11-12 22:11:01 -06:00
blake 1c963f5563 fin udiskie 2025-11-12 21:48:02 -06:00
blake c02f2853c1 add icons, didnt do anything lmao 2025-11-12 21:47:12 -06:00
blake d73a561b9d add udiskie for automount 2025-11-12 21:11:10 -06:00
blake 7d97acfdfb add udiskie for automount 2025-11-12 21:10:22 -06:00
blake cfb55f980d fix zdot till stable update 2025-11-12 00:36:23 -06:00
blake 1a67b02d7c make gpg work with yubi smartcard 2025-11-12 00:19:07 -06:00
blake 0196b1d8b2 a whole lotta shit 2025-11-12 00:14:50 -06:00
blake d7a6a85841 add folder for new device 2025-11-11 22:04:48 -06:00
blake cc7aca0fce fix gitea 2025-11-11 20:17:13 -06:00
blake 6b393c7e4f add default branch 2025-11-11 20:15:35 -06:00
blake c9bcda6043 fix relative path in dotdir 2025-11-11 19:29:37 -06:00
blake 7ce43bf8e7 add cifs client side mounts 2025-11-11 19:28:22 -06:00
blake 5a451bcaa1 add cifs client side mounts 2025-11-11 19:08:56 -06:00
blake b4bba876ae ssh temp fix for stable rn 2025-11-11 17:36:06 -06:00
blake 005d0451f5 testing ssh 2025-11-11 17:33:52 -06:00
blake d20a1787c2 testing ssh 2025-11-11 17:25:42 -06:00
blake 6bb1a13741 test id file 2025-11-11 17:15:27 -06:00
blake b21060e78d fix snowbelle specific home man config 2025-11-11 17:10:51 -06:00
blake 8caa3b6fe7 ssh changes 2025-11-11 17:04:24 -06:00
blake 6fb6dc7abb add blake ssh key 2025-11-11 16:50:42 -06:00
blake 4a6eb5059c add blake ssh key 2025-11-11 16:49:10 -06:00
blake d92a192a7f random shit 2025-11-11 16:34:13 -06:00
blake 51c3ae6d1e fin secureboot support 2025-11-11 16:29:31 -06:00
blake 2ea0b96230 add secure boot support 2025-11-11 15:55:18 -06:00
blake f7ece5059d add secure boot support 2025-11-11 15:51:22 -06:00
blake b84a2d7628 change wallpaper back 2025-11-11 15:35:29 -06:00
blake b78a43d40a add fastfetch 2025-11-08 12:15:03 -06:00
blake f5ff1a6639 attempt to fix flatpaks not appearing in tofi 2025-11-07 20:54:57 -06:00
blake 0534a04108 mime shit 2025-11-07 18:55:05 -06:00
blake 4af26da42f add flatpaks with nix-flatpak, but like right this time 2025-11-07 18:38:37 -06:00
blake d014733441 add flatpaks with nix-flatpak 2025-11-07 18:22:05 -06:00
blake 38c0191ad2 clean up gitea config from testing 2025-11-07 17:22:35 -06:00
blake 2bbbd49a07 fix ssh config 2025-11-07 17:21:00 -06:00
blake 38a22b5255 update ssh config 2025-11-07 17:17:01 -06:00
blake a787a7dfc5 fin gitea testing 2025-11-07 17:10:37 -06:00
blake 4349ccb132 fix ssh, back to built in 2025-11-07 17:09:29 -06:00
blake 96920b6b3d attempt to use systemssh 2025-11-07 16:35:13 -06:00
blake b97d7e4cb1 just add a second entry for local access 2025-11-07 16:23:01 -06:00
blake 59927a4e3d testing local access 2025-11-07 16:21:06 -06:00
blake 076653fd15 remove local url 2025-11-07 16:19:49 -06:00
blake 63dcc450b6 change reverseproxy for gitea 2025-11-07 16:19:32 -06:00
blake c15704eb22 add local root url 2025-11-07 16:19:32 -06:00
blake 85f7a2889c restructure slippi into gaming subdir 2025-11-07 15:35:58 -06:00
blake 6bfea61ffe restructure slippi into gaming subdir 2025-11-07 15:35:45 -06:00
blake 4e0cc2a322 hope this is the right binary lmao 2025-11-07 15:06:54 -06:00
blake 7ef99c8dd1 add userspace tools and passwdless sudo 2025-11-07 15:05:42 -06:00
blake 1655c0a867 add nh, a nix cli helper tool 2025-11-07 14:54:33 -06:00
blake 724c63f9ff add shortcut to goto ~/.nix 2025-11-07 04:21:22 -06:00
blake 5813db8160 rearrange common nix config, add optimising and garbage collecting 2025-11-07 04:18:09 -06:00
blake cdf8403991 restructure programs (yes again okay like shut up), reorg standard packages, add obs : ) 2025-11-07 03:54:32 -06:00
blake 10488b90c9 adjust default packages 2025-11-07 03:38:03 -06:00
blake bcb1b88861 add motd alias 2025-11-07 03:13:49 -06:00
blake e27be65861 explain gcc import 2025-11-07 03:10:34 -06:00
blake 0e0e58b909 slippi sucess! 2025-11-07 02:59:34 -06:00
blake 4e3a31cf87 more config shullfing, browsers moved, slippi added WOOO 2025-11-07 02:17:58 -06:00
blake 58e68a003a cleaning up my mess so hopefully this shit builds 2025-11-07 01:41:48 -06:00
blake 82d61d54eb add even more programs 2025-11-07 01:34:30 -06:00
blake fa981032d4 add even more programs 2025-11-07 01:34:26 -06:00
blake 5090fa9cd4 add even more programs 2025-11-07 01:34:06 -06:00
blake 125d639f9f add even more programs 2025-11-07 01:33:20 -06:00
blake 9ad80827ee add a whole shit ton of programs 2025-11-07 01:14:38 -06:00
blake f0fa2540b5 remove icon for non urgent messages 2025-11-07 00:35:21 -06:00
blake 0bfe74abb7 fix icon paths 2025-11-07 00:33:56 -06:00
blake 766e20ffc4 update icon paths 2025-11-07 00:29:47 -06:00
blake 178fba9c84 remove unused scripts, renamed the rest, updated zsh conf to reflect this 2025-11-07 00:22:42 -06:00
blake eef41bbca8 fucking with tofi 2025-11-06 23:53:44 -06:00
blake a0c728f147 tofi adjustments 2025-11-06 23:48:15 -06:00
blake 35645a3e9c fixed launch option comment 2025-11-06 23:29:40 -06:00
blake 67002a94dd finally figured out the cursors, needed to use the setcursor commadn in hyprctl 2025-11-06 23:11:37 -06:00
blake 6beb28477f add hypr specific? 2025-11-06 22:42:07 -06:00
blake dc03836ac0 with the right name this time 2025-11-06 22:40:12 -06:00
blake 646ba6d63f try w/o pointer cursor just vars 2025-11-06 22:39:19 -06:00
blake e34b5161d4 this is the one, add the links 2025-11-06 22:38:15 -06:00
blake 81c59857e5 this is the one I swear the env vars will work 2025-11-06 22:36:24 -06:00
blake 7576364d43 happy middle ground 2025-11-06 22:30:22 -06:00
blake f31eefe6eb fuck this custom cursor shit 2025-11-06 22:26:01 -06:00
blake 788155194f finished troubleshooting a ghost 2025-11-06 22:15:37 -06:00
blake 777c4f3192 fix paths... again 2025-11-06 22:10:49 -06:00
blake e7ed3e584d fix paths 2025-11-06 22:07:53 -06:00
blake af9d2553d5 try and add cursors 2025-11-06 22:04:43 -06:00
blake 14c67a8bb3 test failed, large sad 2025-11-06 00:26:41 -06:00
blake 97d2610240 fprintd test 2025-11-06 00:22:37 -06:00
blake 2e36efa1c3 cleanup 2025-11-06 00:11:13 -06:00
blake 8a781d6b2a fix bb alias 2025-11-06 00:06:25 -06:00
blake c8a036edc2 all hardcoded paths in home man 2025-11-06 00:05:12 -06:00
blake f0a8d8f0fb remove more hard coded paths 2025-11-05 23:58:04 -06:00
blake 303c759bb4 remove hard coded paths 2025-11-05 23:51:05 -06:00
blake c243c4393f adjust popup settings 2025-11-05 23:45:06 -06:00
blake de4822bc68 make dunst declaritive 2025-11-05 23:30:42 -06:00
blake ed3046e18a wrap up suspend-then-hibernate 2025-11-05 23:14:26 -06:00
blake e3546caeb5 i think i finally figured out hibernate then sleep 2025-11-05 22:53:27 -06:00
blake cc083128a3 testing timeout 2025-11-05 22:23:24 -06:00
blake 9faad0e16c add proper target 2025-11-05 22:21:05 -06:00
blake e50f503270 wait its something else 2025-11-05 22:18:46 -06:00
blake 8a502bdf15 didnt work lmao 2025-11-05 22:17:53 -06:00
blake 32d737f011 attempt to use suspend then hibrnate again 2025-11-05 22:16:51 -06:00
blake 7f84ae360c add theming for qt 2025-11-05 22:15:46 -06:00
blake bce6234c10 add qalculate-qt 2025-11-05 22:13:38 -06:00
blake 7572b52d6f please? 2025-11-05 21:56:42 -06:00
blake 68ca7ff5f8 i swear this time 2025-11-05 21:54:50 -06:00
blake 51d9300990 fix clipboard once and for all 2025-11-05 21:51:59 -06:00
blake 183eb27980 fix controller 2025-11-05 21:38:12 -06:00
blake 3f689d46f4 all renames 2025-11-05 21:34:52 -06:00
blake 2a576d8d39 did it, add all sinks 2025-11-05 21:30:34 -06:00
blake e92206ae43 this is the one 2025-11-05 21:25:15 -06:00
blake 733145692f maybe? 2025-11-05 21:12:19 -06:00
blake ad8b20fd0c actually install the fucking wl-clipboard idiot 2025-11-05 21:00:23 -06:00
blake d9c20efa16 make nvf use wl-copy 2025-11-05 20:52:31 -06:00
blake 3bbe306485 add clipboard 2025-11-05 20:48:56 -06:00
blake f9ac7944b3 add explicit pipewire config 2025-11-05 19:33:15 -06:00
blake eff39f2218 add explicit pipewire config 2025-11-05 19:33:07 -06:00
blake cdbb5f913d add gaming 2025-11-05 19:09:55 -06:00
blake e329c17546 add gaming 2025-11-05 19:05:56 -06:00
blake 85c8b9ec1c restructure desktop with option config wrappers 2025-11-05 18:41:33 -06:00
blake 96fd9d96c1 restructure desktop with option config wrappers 2025-11-05 18:41:07 -06:00
blake 090889dff2 restructure desktop with option config wrappers 2025-11-05 18:40:34 -06:00
blake 8c4a82a73f restructure desktop with option config wrappers 2025-11-05 18:40:25 -06:00
blake f448ce43ec add userspace tools for intel 2025-11-05 18:31:13 -06:00
blake 2fb0dc4c50 fix refs to graphics 2025-11-05 18:28:15 -06:00
blake 2ed9add88e more stupid shit 2025-11-05 18:27:20 -06:00
blake 881d4dd78a punc error lmao 2025-11-05 18:26:48 -06:00
blake ad487e6715 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:25:55 -06:00
blake f107cf19c7 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:24:30 -06:00
blake f5bc0400ae change cert to one for blakedheld.xyz 2025-11-04 23:52:17 -06:00
blake 96ca6c6ea0 hopeing 2025-11-04 23:43:29 -06:00
blake 610513edb7 change extraUpFlags to extraSetFlags across the board 2025-11-04 23:18:56 -06:00
blake f49978d587 add extraSetFlags to tailscale config 2025-11-04 23:15:39 -06:00
blake cb4234630b ts test 2025-11-04 23:13:05 -06:00
blake 992616c1ca testing ts 2025-11-04 23:12:19 -06:00
blake 7b39e418c9 add advertisement to snowbelle itself 2025-11-04 23:08:21 -06:00
blake adf9d1ee4a could fix it all 2025-11-04 22:58:38 -06:00
blake 0c4aed6591 add some packages 2025-11-04 22:54:41 -06:00
2773 changed files with 11590 additions and 2312 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
.DS_Store
.keyring .keyring
.keyring/ .keyring/
.nixos-switch-log .nixos-switch-log
-203
View File
@@ -1,203 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE OPTIONS ---
BORG_PASSPHRASE=""
SHOW_FOLDERS_ONLY=false
SHOW_FILES=false # Default to showing files and directories
while getopts "k:fp" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
f)
SHOW_FOLDERS_ONLY=true
echo "Only directories will be shown in fzf by default."
SHOW_FILES=false
;;
p)
SHOW_FILES=true
echo "Both files and directories will be shown in fzf."
;;
*)
echo "Usage: $0 [-k passphrase_file] [-f] [-p] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ $# -eq 0 ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/archives/servers/snowbelle}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort -r)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/$(uuidgen | sha256sum | head -c 2)-restore-${selected}"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
# --- LIST FILES AND DIRECTORIES ---
echo "Scanning files and directories..."
if command -v fd >/dev/null 2>&1; then
# List both files and directories with fd
if [ "$SHOW_FILES" = true ]; then
files=$(fd . "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(fd --type d . "$MOUNT_POINT" | sort) # Only directories
fi
else
# Fall back to find if fd is not available
if [ "$SHOW_FILES" = true ]; then
files=$(find "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(find "$MOUNT_POINT" -type d | sort) # Only directories
fi
fi
if [ -z "$files" ]; then
echo "No files or directories found in archive."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
fi
# --- FZF FILE/DIRECTORY SELECTION ---
if [ "$SHOW_FILES" = true ]; then
# If showing files and directories, we pass everything to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select files or directories to restore: " \
--preview "tree -C -L 5 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
else
# If only showing directories, pass directories to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select directories to restore: " \
--preview "tree -C -d -L 3 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
fi
if [ -z "$selected_items" ]; then
echo "No items selected. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
fi
# --- SUMMARY OF SELECTED ITEMS ---
echo "Selected items:"
for item in $selected_items; do
echo " $item"
done
# --- OPTIONS MENU (concise) ---
# Default to option 1 if no input is given
echo "Select restore destination: 1) Restore to ./${selected}_restore 2) Restore to original dirs 3) Quit"
read -p "Enter your choice (1/2/3) [default: 1]: " choice
# Default to option 1 if user presses Enter without providing input
choice="${choice:-1}"
# --- SET RESTORE DESTINATION BASED ON USER CHOICE ---
case "$choice" in
1)
DEST="./${selected}_restore"
;;
2)
DEST="$MOUNT_POINT"
;;
3)
echo "Quitting. No items restored."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
;;
*)
echo "Invalid choice. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
;;
esac
mkdir -p "$DEST"
# --- RESTORE SELECTED ITEMS (FILES OR DIRECTORIES) ---
echo "Restoring selected items..."
while IFS= read -r item; do
dest_path="$DEST/$item"
mkdir -p "$(dirname "$dest_path")"
if [ -d "$MOUNT_POINT/$item" ]; then
cp -r "$MOUNT_POINT/$item" "$dest_path"
else
cp -a "$MOUNT_POINT/$item" "$dest_path"
fi
echo "Restored: $item"
done <<< "$selected_items"
# --- CLEANUP ---
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
echo "Restore complete."
Executable
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
# this will one day be an interactive install bootstrap script for my nix config!
# right now this shall be treated as psudocode but also just a list of steps for installing
# without further adoo:
#
# 1. boot target device into nixos installer iso
# 2. `sudo -i``
# 3. `git clone https://git.blakedheld.xyz/blake/nix.git bootstrap_nix`
# 4. if new host use `ls -l /dev/disk/by-id/` to get the id of the target disk and update the related line in the disko config for that host (or partition the target disk manually however you wish)
# 5. run the disko install command `nix run github:nix-community/disko -- --mode destroy,format,mount --flake bootstrap_nix#hostname` to just format the disk(s)
# 6. generate hardware config `nixos-generate-config --root /mnt`
# 7. create directories for keys `mkdir -p /mnt/etc/sops` `mkdir -p /mnt/home/blake/.config/sops/age`
# 8. move nix config to home dir `mv /bootstrap_nix /mnt/home/blake/.nix`
# 9. copy age keys.txt to previously made dirs `echo "<key>" | tee /mnt/etc/sops/keys.txt /mnt/home/blake/.config/sops/age/keys.txt > dev/null`
# 10. install the os (let it fail, fix it, repeat, etc) `nixos-install --flake /mnt/home/blake/.nix#hostname`
# 11. set the root password
# 12. reboot and dont forget to `sudo chown -R blake:blake /home/blake`
# 13. change nix repo upstream to ssh `cd ~/.nix && git remote remove origin && git remote add origin ssh://gitea@git.blakedheld.xyz:7567/blake/nix.git`
#!/usr/bin/env bash
set -euo pipefail
AGE_KEY_FILE="/keys.txt"
echo "nixos bootstrap installer =="
# --- input ---
read -rp "hostname: " HOSTNAME
#read -rp "age key (will not be echoed): " AGE_KEY
if [[ ! -f "$AGE_KEY_FILE" ]]; then
echo "cannot find age keyfile"
exit 1
fi
AGE_KEY="$(cat "$AGE_KEY_FILE")"
echo
echo
echo "install mode:"
echo " 1) disko (auto partition/format/mount)"
echo " 2) manual (you already mounted disks)"
read -rp "choice [1/2]: " MODE
echo
if [[ -d /bootstrap_nix ]]; then
echo "repo already exists, skipping clone"
else
echo "cloning nix config..."
git clone https://git.blakedheld.xyz/blake/nix.git /bootstrap_nix
fi
cd /bootstrap_nix
# fix origin
git remote remove origin
git remote add origin ssh://gitea@git.blakedheld.xyz:7567/blake/nix.git
# --- disk setup ---
if [[ "$MODE" == "1" ]]; then
echo
echo "running disko (THIS WILL DESTROY DISKS)..."
echo "make sure /dev/disk/by-id is correct in your host config!"
# nix run github:nix-community/disko --extra-experimental-features "nix-command flakes" -- \
# --mode destroy,format,mount \
# --flake .#"${HOSTNAME}"
nix run github:nix-community/disko --extra-experimental-features "nix-command flakes" -- \
--mode destroy,format,mount \
--yes-wipe-all-disks \
/bootstrap_nix/hosts/nixos/$HOSTNAME/disko.nix
elif [[ "$MODE" == "2" ]]; then
echo
echo "MANUAL MODE SELECTED"
echo "WARNING: you must have already partitioned + mounted disks to /mnt"
read -rp "press ENTER to continue once disks are mounted..."
else
echo "invalid selection"
exit 1
fi
# --- generate hardware config ---
echo
echo "generating hardware config..."
nixos-generate-config --root /mnt
# --- setup directories ---
echo "creating sops/age directories..."
mkdir -p /mnt/etc/sops
mkdir -p /mnt/home/blake/.config/sops/age
# --- move config ---
echo "moving nix config into /mnt/home/blake/.nix ..."
cp -r /bootstrap_nix /mnt/home/blake/.nix
echo "moving hardware into /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME ..."
cp /mnt/etc/nixos/hardware-configuration.nix /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME
cd /mnt/home/blake/.nix
git add /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME
# --- write age key ---
echo "writing age key..."
echo "$AGE_KEY" | tee \
/mnt/etc/sops/keys.txt \
/mnt/home/blake/.config/sops/age/keys.txt \
> /dev/null
# --- install ---
echo
echo "running nixos-install..."
set +e
nixos-install --root /mnt --flake /mnt/home/blake/.nix#"${HOSTNAME}"
INSTALL_EXIT=$?
set -e
if [[ $INSTALL_EXIT -ne 0 ]]; then
echo
echo "install failed. fix issues and re-run nixos-install manually if needed."
exit $INSTALL_EXIT
fi
# --- post install ---
echo
echo "installation complete!"
echo "set root password if needed, then reboot."
echo "after reboot: sudo chown -R blake:blake /home/blake"
nixos-enter --root /mnt -- run --login bash <<'EOF'
set -e
chown -R blake:blake /home/blake
nixos-rebuild switch --flake /home/blake/.nix
systemd-cryptenroll --tpm2-device=auto /dev/nvme0n1p2
EOF
echo "fin."
-99
View File
@@ -1,99 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE OPTIONS ---
BORG_PASSPHRASE=""
SHOW_FOLDERS_ONLY=false
SHOW_FILES=false # Default to showing files and directories
while getopts "k:fp" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
f)
SHOW_FOLDERS_ONLY=true
echo "Only directories will be shown in fzf by default."
SHOW_FILES=false
;;
p)
SHOW_FILES=true
echo "Both files and directories will be shown in fzf."
;;
*)
echo "Usage: $0 [-k passphrase_file] [-f] [-p] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ $# -eq 0 ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/archives/servers/snowbelle}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort -r)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/$(uuidgen | sha256sum | head -c 2)-restore-${selected}"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
cleanup() {
echo "Unmounting archive..."
borg umount "$MOUNT_POINT" >/dev/null 2>&1 || true
rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
lf $MOUNT_POINT
View File
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
cd /home/blake/.nix
git remote remove origin
git remote add origin ssh://gitea@git.holocron.blue:7567/blake/nix.git
git fetch
git branch --set-upstream-to=origin/trunk trunk
+2
View File
@@ -26,6 +26,8 @@ echo "files:"
git status --short git status --short
read -rp "commit message: " commit_msg read -rp "commit message: " commit_msg
echo "rebuilding nixos with flake.nix..." echo "rebuilding nixos with flake.nix..."
#if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
#if ! nh os switch 2>&1 | tee "$logfile"; then
if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
echo "rebuild failed; exited with no commit" echo "rebuild failed; exited with no commit"
exit 1 exit 1
-26
View File
@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
pushd ~/.nix
# nvim flake.nix
# alejandra . &>/dev/null
# git diff -U0 *.nix
# add generation comment to flake.nix
gen=$(nixos-rebuild list-generations | grep current)
if sed -n '3p' flake.nix | grep -q '^# generation:'; then
# replace the comment on line 3
sed -i "3s/^# generation:.*/# generation: $gen/" flake.nix
else
# insert comment on line 3
sed -i "3i# generation: $gen" flake.nix
fi
git diff -U0 $(find . -name '*.nix')
echo "nixos rebuilding..."
#sudo nixos-rebuild switch --flake ~/.nix#snowbelle &>.nixos-switch-log || (
# cat .nixos-switch-log | grep --color error && false)
sudo nixos-rebuild switch --flake ~/.nix#snowbelle 2>&1 | tee .nixos-switch-log | grep --color=always -E "error|$" && true
git commit -am "$gen"
popd
Generated
+1002 -149
View File
File diff suppressed because it is too large Load Diff
+84 -23
View File
@@ -4,21 +4,28 @@
{ {
description = "blakes nix config"; description = "blakes nix config";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05"; nixpkgs.url = "nixpkgs/nixos-26.05";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nix-darwin = { nix-darwin = {
url = "github:LnL7/nix-darwin"; url = "github:nix-darwin/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs-unstable";
}; };
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-25.05"; #url = "github:nix-community/home-manager";
url = "github:nix-community/home-manager/release-26.05";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
home-manager-unstable = { home-manager-unstable = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable"; inputs.nixpkgs.follows = "nixpkgs-unstable";
}; };
plasma-manager = {
url = "github:nix-community/plasma-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
inputs.home-manager.follows = "home-manager-unstable";
};
nix-homebrew.url = "github:zhaofengli/nix-homebrew"; nix-homebrew.url = "github:zhaofengli/nix-homebrew";
nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest";
sops-nix = { sops-nix = {
url = "github:Mic92/sops-nix"; url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -27,15 +34,27 @@
url = "github:nix-community/disko/latest"; url = "github:nix-community/disko/latest";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixos-wsl = {
url = "github:nix-community/NixOS-WSL/main";
inputs.nixpkgs.follows = "nixpkgs";
};
lanzaboote = {
url = "github:nix-community/lanzaboote/v0.4.3";
inputs.nixpkgs.follows = "nixpkgs";
};
watershot = {
url = "github:Kirottu/watershot";
inputs.nixpkgs.follows = "nixpkgs";
};
vpn-confinement = { vpn-confinement = {
url = "github:Maroka-chan/VPN-Confinement"; url = "github:Maroka-chan/VPN-Confinement";
}; };
nvf = { nvf = {
url = "github:notashelf/nvf/v0.8"; url = "github:notashelf/nvf";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
autoaspm = { autoaspm = {
url = "github:notthebee/AutoASPM"; url = "git+https://git.notthebe.ee/notthebee/AutoASPM.git";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
stylix = { stylix = {
@@ -43,6 +62,11 @@
inputs.nixpkgs.follows = "nixpkgs-unstable"; inputs.nixpkgs.follows = "nixpkgs-unstable";
}; };
copyparty.url = "github:9001/copyparty"; copyparty.url = "github:9001/copyparty";
slippi = {
url = "github:lytedev/slippi-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
srcds-nix.url = "github:ihaveamac/srcds-nix";
}; };
outputs = { outputs = {
self, self,
@@ -50,59 +74,96 @@
nixpkgs-unstable, nixpkgs-unstable,
nix-darwin, nix-darwin,
nix-homebrew, nix-homebrew,
nixos-wsl,
plasma-manager,
... ...
} @ inputs: let } @ inputs: let
systems = { systems = {
x86_64 = "x86_64-linux"; x86_64-linux = "x86_64-linux";
arm64 = "aarch64-linux"; aarch64-linux = "aarch64-linux";
darwin = "aarch64-darwin"; aarch64-darwin = "aarch64-darwin";
}; };
unstableOverlay = final: prev: {
unstable = import nixpkgs-unstable {
#system = prev.system;
system = prev.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
# legacy
stable_pkgs = builtins.mapAttrs (k: v: import nixpkgs {system = v;}) systems; stable_pkgs = builtins.mapAttrs (k: v: import nixpkgs {system = v;}) systems;
unstable_pkgs = builtins.mapAttrs (k: v: import nixpkgs-unstable {system = v;}) systems; unstable_pkgs = builtins.mapAttrs (k: v: import nixpkgs-unstable {system = v;}) systems;
in { in {
nixosConfigurations = { nixosConfigurations = {
snowbelle = nixpkgs.lib.nixosSystem { snowbelle = nixpkgs.lib.nixosSystem {
system = systems.x86_64; system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [ modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/snowbelle/configuration.nix ./hosts/nixos/snowbelle/configuration.nix
inputs.home-manager.nixosModules.default inputs.home-manager.nixosModules.default
]; ];
}; };
yveltal = nixpkgs-unstable.lib.nixosSystem { yveltal = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64; system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [ modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/yveltal/configuration.nix ./hosts/nixos/yveltal/configuration.nix
./hosts/nixos/yveltal/disko.nix
inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko
];
};
mew = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/mew/configuration.nix
./hosts/nixos/mew/disko.nix
inputs.home-manager-unstable.nixosModules.default inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
./hosts/nixos/yveltal/disko.nix
]; ];
}; };
vaniville = nixpkgs.lib.nixosSystem { vaniville = nixpkgs.lib.nixosSystem {
system = systems.x86_64; system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [ modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/vaniville/configuration.nix ./hosts/nixos/vaniville/configuration.nix
inputs.home-manager.nixosModules.default inputs.home-manager.nixosModules.default
]; ];
}; };
lumiose = nixpkgs.lib.nixosSystem {
system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/lumiose/configuration.nix
inputs.home-manager.nixosModules.default
inputs.disko.nixosModules.disko
];
};
wsl = nixpkgs.lib.nixosSystem {
system = systems.x86_64-linux;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/nixos/wsl/configuration.nix
nixos-wsl.nixosModules.default
inputs.home-manager.nixosModules.default
];
};
}; };
darwinConfigurations = { darwinConfigurations = {
CEN-IT-07 = nix-darwin.lib.darwinSystem { cen-it-07 = nix-darwin.lib.darwinSystem {
system = systems.darwin; system = systems.aarch64-darwin;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;}; specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;};
modules = [ modules = [
{nixpkgs.overlays = [unstableOverlay];}
./hosts/darwin/cen-it-07/configuration.nix ./hosts/darwin/cen-it-07/configuration.nix
inputs.home-manager.darwinModules.default inputs.home-manager.darwinModules.default
nix-homebrew.darwinModules.nix-homebrew
{
nix-homebrew = {
enable = true; # install homebrew
enableRosetta = true; # install homebrew for rosetta as well
user = "blake"; # user owning homebrew prefix
};
}
]; ];
}; };
}; };
+108
View File
@@ -0,0 +1,108 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
imports = [
inputs.nix-homebrew.darwinModules.nix-homebrew
../default.nix
../../../modules/darwin
];
# home grown nixos modules
darwin = {
syncthing.enable = true;
tailscale.enable = true;
nextdns.enable = true;
yubikey.enable = true;
work.enable = true;
apps.enable = true;
cyber.enable = true;
gaming.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.bhelderman.imports = [
../../../users/blake/hosts/cen-it-07.nix
];
users = {
users = {
bhelderman = {
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBrNHm/n7BrA8Vz0Lsc3fZQ5QJOm01InFvrzEDuD4BoD me@blakedheld.xyz"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBK0AGJfZGyqW8/krvQV+PL7axcDW/EnKyHy9M8wryQx klefki"
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPdC9cCX8awvA19Ri65fvbYjZYe8X1Ef+nOZAIv92AS6u4SkJYqOvPYfqRHXORNDpbzjTV6nackyCKvV5EO4niv4MFIgdkEQwuVHcYX32/dOsWdDoeXBT/l2sFFM7JESwQ== blake@zygarde"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOVsjLEbnW/KeFXogppi0AP6ZbCZpObu7zFeRV/aLkP9 blake@lugia"
];
};
};
};
# base system package install list
environment.systemPackages = with pkgs; [
neovide
];
nix-homebrew = {
enable = true; # install homebrew
enableRosetta = true; # install homebrew for rosetta as well
#autoMigrate = true;
user = "bhelderman"; # user owning homebrew prefix
trust = {
formulae = [];
casks = [];
commands = [];
taps = ["rogeriopradoj/cask-peazip"];
};
};
homebrew = {
enable = true;
# removes anything in homebrew not explicitly specified
onActivation = {
cleanup = "zap";
autoUpdate = false;
upgrade = true;
};
taps = [
"rogeriopradoj/cask-peazip"
];
brews = [
"mas"
"coreutils"
"ctpv"
"media-info"
];
casks = [
"kitty"
"linearmouse"
"betterdisplay"
"rectangle"
"peazip"
];
masApps = {
# "name" = app_id_number;
"hiddenbar" = 1452453066;
"testflight" = 899247664;
};
};
# for mas to not throw rebuild fit
# since darwin needs root now (will be removed in future)
system.primaryUser = "bhelderman";
power = {
sleep = {
computer = 30;
display = 5;
allowSleepByPowerButton = true;
};
};
}
+102 -4
View File
@@ -5,28 +5,55 @@
inputs, inputs,
... ...
}: { }: {
/*
instructions for first time setup for macos here
1. install the nix package manager with: `sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install)`
2. install xcode tools with `xcode-select --install`
3. allow full disk access to terminal
4. xfer or git clone flake to ~/.nix
5. sign into icloud and by extension app store for mas
6. rename some shell rc files with `sudo mv /etc/bashrc /etc/bashrc.before-nix-darwin && sudo mv /etc/zshrc /etc/zshrc.before-nix-darwin`
7. install nix-darwin with: `nix run --extra-experimental-features "nix-command flakes" nix-darwin -- switch --flake ~/.nix#host`
8. nh should be installed now so enjoy and use `nh darwin switch`
*/
imports = [ imports = [
]; ];
# general macos system settings
# base system package install list # base system package install list
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
wget wget
sl
curl curl
rsync rsync
git git
age age
fzf fzf
neofetch
usbutils usbutils
pciutils pciutils
python3 python3
vim
lf lf
btop btop
powertop pinentry_mac
]; ];
users.users.bhelderman = {
home = "/Users/bhelderman";
# optional extras, e.g. shell, uid, etc.
};
# define home-manager user
home-manager = {
extraSpecialArgs = {inherit inputs;};
backupFileExtension = "bak";
useUserPackages = true;
useGlobalPkgs = false;
users = {
"bhelderman" = import ../../users/blake/home_darwin.nix;
};
};
# set timezone # set timezone
time.timeZone = "America/Chicago"; time.timeZone = "America/Chicago";
@@ -35,6 +62,77 @@
# enable flakes # enable flakes
nix.settings.experimental-features = ["nix-command" "flakes"]; nix.settings.experimental-features = ["nix-command" "flakes"];
users.defaultUserShell = pkgs.zsh;
system = {
stateVersion = 6;
defaults = {
trackpad = {
Clicking = true;
TrackpadThreeFingerDrag = true;
TrackpadFourFingerVertSwipeGesture = 2;
TrackpadRightClick = true;
TrackpadFourFingerHorizSwipeGesture = 2;
TrackpadPinch = true;
TrackpadRotate = true;
TrackpadTwoFingerDoubleTapGesture = true;
TrackpadTwoFingerFromRightEdgeSwipeGesture = 3;
};
universalaccess = {
mouseDriverCursorSize = 3.0;
};
NSGlobalDomain = {
AppleICUForce24HourTime = true;
AppleInterfaceStyle = "Dark";
NSAutomaticCapitalizationEnabled = false;
NSDocumentSaveNewDocumentsToCloud = false;
};
WindowManager = {
EnableStandardClickToShowDesktop = false;
GloballyEnabled = false; # disable stage manager
};
controlcenter = {
BatteryShowPercentage = true;
Bluetooth = true;
Display = false;
FocusModes = false;
NowPlaying = false;
Sound = false;
};
menuExtraClock = {
ShowDate = 1;
ShowDayOfWeek = true;
Show24Hour = true;
ShowSeconds = true;
};
dock = {
autohide = true;
largesize = 16;
mineffect = "genie";
minimize-to-application = true;
orientation = "bottom";
scroll-to-open = true;
show-recents = false;
showAppExposeGestureEnabled = true;
};
finder = {
AppleShowAllExtensions = true;
NewWindowTarget = "Home";
ShowPathbar = true;
ShowStatusBar = true;
};
hitoolbox.AppleFnUsageType = "Change Input Source";
iCal = {
"first day of week" = "Monday";
};
loginwindow = {
LoginwindowText = "howdy o/";
GuestEnabled = false;
};
screencapture.type = "png";
screensaver = {
askForPassword = true;
askForPasswordDelay = 15;
};
};
};
} }
+86 -23
View File
@@ -3,48 +3,91 @@
config, config,
lib, lib,
inputs, inputs,
unstable_pkgs,
... ...
}: { }: {
imports = [ imports = [
inputs.autoaspm.nixosModules.default inputs.autoaspm.nixosModules.default
]; ];
# set timezone
time.timeZone = "America/Chicago";
nix = {
# garbage collect & remove builds older then 14 days
gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 14d";
persistent = true;
};
# optimise nix store, dedupe and such
optimise = {
automatic = true;
dates = ["daily"];
};
# the goats
settings = {
substituters = [
"https://cache.nixos.org"
];
trusted-public-keys = [
];
experimental-features = lib.mkDefault [
"nix-command"
"flakes"
];
};
};
# allow proprietary packages
nixpkgs = {
config = {
allowUnfree = true;
allowUnfreePredicate = _: true;
};
};
# power management
services.autoaspm.enable = true;
powerManagement.powertop.enable = true;
# things are better this way
users = {
defaultUserShell = pkgs.zsh;
users.root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO06en1r4+zg8JMGPq7WiZeh/DBUvfhDJX3e+J5Z5Ttk blake@snowbelle"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP0FLKK9yEPYpGuCjoX0e7Ky/zTPfzDk7IkrR3tOmELP blake@vaniville"
];
};
};
# base system package install list # base system package install list
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
wget wget
curl curl
dig dig
nmap
rsync rsync
iperf3
jq
git git
age age
fzf
neofetch
usbutils
pciutils
python3
vim vim
lf ncdu
btop btop
powertop powertop
dig iotop
cifs-utils
usbutils
pciutils
lm_sensors
smartmontools
unstable.siomon
]; ];
# set timezone # nice to have passwordless sudo
time.timeZone = "America/Chicago";
# allow proprietary packages
nixpkgs.config.allowUnfree = true;
# power management
services.autoaspm.enable = true;
powerManagement.powertop.enable = true;
# enable flakes
nix.settings.experimental-features = ["nix-command" "flakes"];
users.defaultUserShell = pkgs.zsh;
# passwordless rebuild
security.sudo = { security.sudo = {
extraRules = [ extraRules = [
{ {
@@ -66,6 +109,26 @@
command = "/run/current-system/sw/bin/tailscale"; command = "/run/current-system/sw/bin/tailscale";
options = ["NOPASSWD"]; options = ["NOPASSWD"];
} }
{
command = "/etc/profiles/per-user/blake/bin/nom";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-build";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-shell";
options = ["NOPASSWD"];
}
{
command = "/run/current-system/sw/bin/rsync";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/lf";
options = ["NOPASSWD"];
}
]; ];
} }
]; ];
+177
View File
@@ -0,0 +1,177 @@
{
config,
lib,
inputs,
modulesPath,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
./disko.nix
../../nixos
../../../users/blake
../../../modules/system
../../../modules/fileshares/holocron
../../../modules/homelab
#../../../modules/gameservers/srcds
../../../modules/gameservers/minecraft_recpro
../../../modules/gameservers/minecraft_modded
../../../modules/gameservers/valheim
];
home-manager.users.blake.imports = [
../../../users/blake/hosts/lumiose.nix
];
system = {
ssh.enable = true;
sops.enable = true;
podman.enable = true;
yubikey.enable = true;
graphics = {
enable = true;
vendor = "amd";
};
keepalive = {
enable = true;
url = "https://up.holocron.blue/api/push/7DAcvsedwB?status=up&msg=fuckingvibing&ping=";
};
};
homelab = {
enable = true;
base_domain = "lumiose.holocron.blue";
host_ip = "10.10.0.11";
gitea.enable = false;
glance.enable = true;
immich = {
enable = true;
data_dir = "/holocron/srv/immich";
backup = false;
};
vaultwarden.enable = false;
#searx.enable = true;
# home assistant
home.enable = true;
homebox.enable = true;
# network
tailscale.enable = true;
caddy = {
enable = true;
keys = false;
};
dnsmasq.enable = true;
# mediastack
mediastack.enable = true;
qbittorrent.vpn_inf = "enp34s0.69";
# system
backups.enable = true;
motd.enable = true;
msmtp.enable = true;
uptime-kuma.enable = true;
# # ai
# ollama.enable = false;
# open-webui.enable = false;
wyoming.enable = true;
};
holocron = {
# copyparty.enable = false;
syncthing.enable = true;
ensure_perms.enable = false;
offsite.enable = true;
zfs.enable = true;
smb.enable = true;
nfs.enable = true;
};
gameservers = {
minecraft_recpro.enable = true;
minecraft_modded.enable = false;
valheim.enable = true;
};
# boot (systemd is going on me)
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
boot.loader.efi.canTouchEfiVariables = true;
boot.initrd.systemd.enable = true; # better logging
# setup hostname and networking stack
services.resolved = {
enable = true;
settings = {
Resolve = {
FallbackDNS = ["1.1.1.1" "9.9.9.9"];
DNSOverTLS = "opportunistic";
};
};
};
networking = {
hostName = "lumiose"; # hostname
hostId = "007f0200";
getaddrinfo = {
enable = true;
precedence = {
"::ffff:0:0/96" = 100;
};
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
ensureProfiles.profiles = {
vpn = {
ipv4 = {
method = "manual";
addresses = "10.69.0.11/24";
gateway = "10.69.0.1";
};
ethernet.mac-address = "02:ea:6c:3c:9f:cd";
connection.type = "vlan";
connection.id = "vpn";
connection.interface-name = "enp34s0.69"; # or just "vpn-vlan"
vlan.interface-name = "enp34s0.69"; # or just "vpn-vlan"
vlan.parent = "enp34s0";
vlan.id = 69;
#ipv4.dns = "9.9.9.9";
};
};
};
};
hardware.bluetooth.enable = true;
# Open ports in the firewall.
networking.firewall.allowedTCPPorts = [
80 # set - http
111 # set - portmapper for nfs
443 # set - https
137 # set - smb
138 # set - smb
139 # set - smb
445 # set - smb
1198
1883 # set - mqtt
2049 # set - nfs
2222 # srv - syncthing
5201 # iperf3
];
networking.firewall.allowedUDPPorts = [51820];
# Or disable the firewall altogether.
networking.firewall.enable = true;
# hardware stuff
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-amd"];
boot.kernelParams = ["ipv6.disable=1"];
boot.extraModulePackages = [];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
system.stateVersion = "25.05"; # stays here : )
}
+70
View File
@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-SAMSUNG_MZVLB256HAHQ-000H2_S499NX0M112943"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}
+113
View File
@@ -0,0 +1,113 @@
{
pkgs,
config,
lib,
modulesPath,
inputs,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
];
# home grown nixos modules
system = {
secure_boot.enable = false;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true;
sops.enable = true;
japanese.enable = true;
yubikey.enable = true;
yubikey.lock_on_remove = false;
tailscale.enable = true;
syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "amd";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = true;
greetd.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = true;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = {
HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend-then-hibernate";
};
# sets the delay before hibernation for ^
systemd.sleep.extraConfig = ''
HibernateDelaySec=1800
'';
# boot (systemd is growing on me)
boot = {
kernelModules = [ "kvm-amd" ];
extraModulePackages = [];
loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true;
};
initrd = {
systemd.enable = true; # better logging
availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" "ahci"];
kernelModules = [];
};
};
# setup hostname and networking stack
networking = {
hostName = "mew"; # hostname
useDHCP = lib.mkDefault true;
interfaces = {
wlp7s0.useDHCP = lib.mkDefault true;
};
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
};
};
services.resolved = {
enable = true;
fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic";
};
hardware.bluetooth.enable = true;
system.stateVersion = "25.05"; # stays here : )
# hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
+70
View File
@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-MTFDHBA512TDV-1AZ1AABHA_UJUND0170FW7O0"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}
+106 -97
View File
@@ -1,93 +1,107 @@
{ config, lib, inputs, stable_pkgs, unstable_pkgs, ... }:
let
pkgs = stable_pkgs.x86_64;
unstable = unstable_pkgs.x86_64;
in
{ {
imports = config,
[ # Include the results of the hardware scan. lib,
./hardware-configuration.nix inputs,
../../nixos stable_pkgs,
../../../users/blake unstable_pkgs,
../../../modules/system ...
../../../modules/holocron }: {
../../../modules/homelab imports = [
../../../modules/gameservers/minecraft_recpro # Include the results of the hardware scan.
]; ./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/system
../../../modules/homelab
#../../../modules/fileshares/holocron
#../../../modules/gameservers/minecraft_recpro
../../../modules/gameservers/minecraft_modded
];
# home-manager.users.blake.imports = [ home-manager.users.blake.imports = [
# ../../../users/blake/hosts/snowbelle.nix ../../../users/blake/hosts/snowbelle.nix
# ]; ];
system = { system = {
ssh.enable = true; ssh.enable = true;
sops.enable = true; sops.enable = true;
podman.enable = true; podman.enable = true;
yubikey.enable = true; yubikey.enable = true;
nvidia.enable = true; graphics = {
}; enable = true;
holocron = { vendor = "nvidia";
syncthing.enable = true; };
copyparty.enable = false; keepalive = {
ensure_perms.enable = false; enable = true;
zfs.enable = true; url = "https://up.holocron.blue/api/push/kMoYviAuCL?status=up&msg=bigchilling&ping=";
smb.enable = true; };
nfs.enable = true;
}; };
# holocron = {
# ensure_perms.enable = true;
# zfs.enable = true;
# smb.enable = true;
# nfs.enable = true;
# };
homelab = { homelab = {
enable = true; enable = true;
base_domain = "snowbelle.holocron.blue";
# services
gitea.enable = false;
glance.enable = false;
immich.enable = false;
vaultwarden.enable = false;
#searx.enable = true;
# home assistant
home.enable = false;
# network
tailscale.enable = true; tailscale.enable = true;
backups.enable = true; caddy.enable = false;
motd.enable = true; dnsmasq.enable = false;
postfix.enable = true; # mediastack
gitea.enable = true; mediastack.enable = false;
glance.enable = true; # system
immich.enable = true; backups.enable = false;
hass.enable = true; motd.enable = false;
jellyfin.enable = true; uptime-kuma.enable = false;
audiobookshelf.enable = true; # ai
yacreader.enable = true; #ollama.enable = false;
qbittorrent.enable = true; #open-webui.enable = false;
sonarr.enable = true; wyoming.enable = false;
radarr.enable = true;
bazarr.enable = true;
prowlarr.enable = true;
flaresolverr.enable = true;
zigbee2mqtt.enable = true;
mosquitto.enable = true;
caddy.enable = true;
uptime-kuma.enable = true;
vaultwarden.enable = true;
}; };
gameservers = { gameservers = {
minecraft_recpro.enable = true; # minecraft_recpro.enable = true;
minecraft_modded = {
enable = true;
url = "raceraskedforthisenjoyyall.recoil.pro";
};
}; };
# boot (systemd is going on me) # boot (systemd is going on me)
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
boot.initrd.systemd.enable = true; # better logging boot.initrd.systemd.enable = true; # better logging
# setup hostname and networking stack # setup hostname and networking stack
services.resolved = { services.resolved = {
enable = true; enable = true;
fallbackDns = [ "1.1.1.1" "9.9.9.9" ]; #fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic"; settings.Resolve.DNSOverTLS = "opportunistic";
}; };
networking = { networking = {
hostName = "snowbelle"; # hostname hostName = "snowbelle"; # hostname
hostId = "3e6e7055"; # zfs wants this hostId = "3e6e7055"; # zfs wants this
networkmanager = { networkmanager = {
enable = true; # the goat enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer! dns = "systemd-resolved"; # the backup dancer!
ensureProfiles.profiles = { ensureProfiles.profiles = {
vpn = { vpn = {
ethernet.mac-address = "7a:e4:07:8d:22:76"; ethernet.mac-address = "7a:e4:07:8d:22:76";
connection.type = "vlan"; connection.type = "vlan";
connection.id = "vpn"; connection.id = "vpn";
connection.interface-name = "enp89s0.69"; # or just "vpn-vlan" connection.interface-name = "enp89s0.69"; # or just "vpn-vlan"
vlan.interface-name = "enp89s0.69"; # or just "vpn-vlan" vlan.interface-name = "enp89s0.69"; # or just "vpn-vlan"
vlan.parent = "enp89s0"; vlan.parent = "enp89s0";
vlan.id = 69; vlan.id = 69;
#ipv4.dns = "9.9.9.9"; #ipv4.dns = "9.9.9.9";
@@ -96,54 +110,49 @@ in
}; };
}; };
hardware.bluetooth.enable = true; hardware.bluetooth.enable = true;
# Open ports in the firewall. # Open ports in the firewall.
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [
80 # set - http 80 # set - http
111 # set - portmapper for nfs 111 # set - portmapper for nfs
139 # set - smb 139 # set - smb
443 # set - https 443 # set - https
445 # set - cifs 445 # set - cifs
5201
1198 1198
1883 # set - mqtt 1883 # set - mqtt
2049 # set - nfs 2049 # set - nfs
2222 # srv - syncthing 2222 # srv - syncthing
7100 # srv - jellyfin 7100 # srv - jellyfin
7101 # srv - audiobookshelf 7101 # srv - audiobookshelf
7102 # srv - yacreader 7102 # srv - yacreader
7103 # srv - qbittorrent 7103 # srv - qbittorrent
7104 # srv - prowlarr 7104 # srv - prowlarr
7105 # srv - bazarr 7105 # srv - bazarr
7106 # srv - sonarr 7106 # srv - sonarr
7107 # srv - radarr 7107 # srv - radarr
7120 # srv - flaresolverr 7120 # srv - flaresolverr
5701 # srv - archivebox 5701 # srv - archivebox
7502 # srv - kiwix 7502 # srv - kiwix
7567 # srv - gitea ssh 7567 # srv - gitea ssh
7700 # srv - glance 7700 # srv - glance
7701 # srv - vaultwarden 7701 # srv - vaultwarden
7702 # srv - immich 7702 # srv - immich
7703 # srv - gitea 7703 # srv - gitea
7704 # srv - hass 7704 # srv - hass
7705 # srv - zigbee2mqtt 7705 # srv - zigbee2mqtt
7901 # srv - uptime kuma 7901 # srv - uptime kuma
7902 # srv - copyparty 7902 # srv - copyparty
25777 # srv - minecraft 25777 # srv - minecraft
25565 # ^ ^ ^ 25565 # ^ ^ ^
25566 # | | | 25566 # | | |
25567 # | | | 25567 # | | |
]; ];
networking.firewall.allowedUDPPorts = [ 51820 ]; networking.firewall.allowedUDPPorts = [51820];
# Or disable the firewall altogether. # Or disable the firewall altogether.
networking.firewall.enable = true; networking.firewall.enable = true;
system.stateVersion = "25.05"; # stays here : ) system.stateVersion = "25.05"; # stays here : )
} }
+191 -135
View File
@@ -1,154 +1,210 @@
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
let
pkgs = stable_pkgs.x86_64;
unstable = unstable_pkgs.x86_64;
in
{ {
imports = config,
[ # Include the results of the hardware scan. lib,
./hardware-configuration.nix pkgs,
../../users/users.nix inputs,
../../modules/system stable_pkgs,
]; unstable_pkgs,
...
}: let
vpsip4 = "100.100.1.10";
snowbelle_ip = "10.10.0.10";
lumiose_ip = "10.10.0.11";
modules = { homelab = config.homelab;
system = { in {
tailscale.enable = true; imports = [
./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/system
../../../modules/homelab
#../../../modules/holocron
];
home-manager.users.blake.imports = [
../../../users/blake/hosts/vaniville.nix
];
system = {
tailscale.enable = false;
};
homelab = {
enable = true;
base_domain = "vaniville.holocron.blue";
host_ip = "100.100.1.10";
ddns.enable = true;
uptime-kuma = {
enable = true;
url = "up.holocron.blue";
}; };
caddy = {
enable = true;
keys = true;
};
backups = {
enable = true;
databases = false;
homelab = true;
backup_repo = "/var/lib/backups/homelab";
offsite_dir = "lifeboat/vaniville/homelab";
};
gitea.enable = true;
vaultwarden.enable = true;
home.enable = false;
}; };
boot = {
# use the systemd-boot EFI boot loader. loader = {
boot.loader.systemd-boot.enable = true; efi.canTouchEfiVariables = true;
boot.loader.efi.canTouchEfiVariables = true; grub = {
enable = true;
# setup hostname and networking stack forceInstall = true;
networking.hostName = "vaniville"; # Define your hostname. };
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. };
kernel.sysctl = {
# set timezone "net.ipv4.ip_forward" = 1;
time.timeZone = "America/Chicago"; };
};
# define shell # define shell
programs.zsh.enable = true; programs.zsh.enable = true;
users.defaultUserShell = pkgs.zsh; users.defaultUserShell = pkgs.zsh;
# package install list # packages reccomended by linode
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vim inetutils
rsync mtr
wget sysstat
git
iptables
nettools
neofetch
btop
]; ];
# allow proprietary packages # services.resolved = {
nixpkgs.config.allowUnfree = true; # enable = true;
# settings = {
# Resolve = {
# FallbackDNS = ["1.1.1.1" "9.9.9.9"];
# DNSOverTLS = "opportunistic";
# };
# };
# };
# enable flakes # setup the network forwarding this host is designed for
nix.settings.experimental-features = [ "nix-command" "flakes" ]; # general networking config
networking = {
hostName = "vaniville"; # Define your hostname.
usePredictableInterfaceNames = false;
useDHCP = false;
interfaces.eth0.useDHCP = true; # public ipv4 interface
# Open ports in the firewall. # the proper way to forward ports on nixos, need to figure it out locally then try to get it working over vps
networking.firewall.enable = true; nat = {
networking.firewall.extraCommands = '' enable = true;
HOMELAB_IP="10.10.0.10" # destination address externalInterface = "eth0"; # your PUBLIC_IF
PUBLIC_IF="eth0" # vps public interface internalInterfaces = ["tailscale0"];
TAILSCALE_IF="tailscale0" # tailscale interface # maybe one day i will figure out the forward ports proper
forwardPorts = [
# flush rules (avoid dupes) # { sourcePort = 80; destination = "10.10.0.10:80"; proto = "tcp"; } # http
iptables -F # { sourcePort = 443; destination = "10.10.0.10:443"; proto = "tcp"; } # https
iptables -t nat -F # { sourcePort = 25777; destination = "10.10.0.10:25777"; proto = "tcp"; } # minecraft
iptables -t mangle -F # { sourcePort = 25777; destination = "10.10.0.10:25777"; proto = "udp"; } # minecraft
iptables -X # { sourcePort = 7567; destination = "10.10.0.10:7567"; proto = "tcp"; } # git
# set defualt policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# allow replys
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# allow vps outbound
iptables -A OUTPUT -o eth0 -j ACCEPT
# general settings
sysctl -w net.ipv4.ip_forward=1 # enable ip forwarding
iptables -t nat -A POSTROUTING -o $TAILSCALE_IF -j MASQUERADE # postrouting masquerade (outgoing packets appear to come from vps tailscale ip)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # allows pings
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # allows ssh
# --- minecraft ---
# port: 25777 tcp & udp
# prerouting:
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 25777 -j DNAT --to-destination $HOMELAB_IP:25777 # tcp packets on port 25777
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p udp --dport 25777 -j DNAT --to-destination $HOMELAB_IP:25777 # udp packets on port 25777
# forwards:
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 25777 -j ACCEPT # vps -> homelab: tcp on port 25777
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p udp --dport 25777 -j ACCEPT # vps -> homelab: udp on port 25777
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 25777 -j ACCEPT # homelab -> vps: tcp on port 25777
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p udp --sport 25777 -j ACCEPT # homelab -> vps: udp on port 25777
# --- reverse proxy ---
# ports: 80 & 443 tcp
# prerouting:
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 80 -j DNAT --to-destination $HOMELAB_IP:80 # tcp packets on port 80
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 443 -j DNAT --to-destination $HOMELAB_IP:443 # tcp packets on port 443
# forwards:
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 80 -j ACCEPT # vps -> homelab: tcp on port 80
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 80 -j ACCEPT # homelab -> vps: tcp on port 80
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 443 -j ACCEPT # vps -> homelab: tcp on port 443
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 443 -j ACCEPT # homelab -> vps: tcp on port 443
# --- gitea ssh ---
# port: 7567 tcp
# prerouting:
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 7567 -j DNAT --to-destination $HOMELAB_IP:7567 # tcp packets on port 7567
# forwards:
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 7567 -j ACCEPT # vps -> homelab: tcp on port 7567
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 7567 -j ACCEPT # homelab -> vps: tcp on port 7567
# --- rustdesk ---
# ports 2114-2119
# hbbs ports
# 21115 tcp (nat type test)
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21115 -j DNAT --to-destination $HOMELAB_IP:21115 # tcp packets on port 21115
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21115 -j ACCEPT # vps -> homelab: tcp on port 21115
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21115 -j ACCEPT # homelab -> vps: tcp on port 21115
# 21116 tcp&udp (id registration, heartbeat, TCP hole punching)
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21116 -j DNAT --to-destination $HOMELAB_IP:21116 # tcp packets on port 21116
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21116 -j ACCEPT # vps -> homelab: tcp on port 21116
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21116 -j ACCEPT # homelab -> vps: tcp on port 21116
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p udp --dport 21116 -j DNAT --to-destination $HOMELAB_IP:21116 # udp packets on port 21116
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p udp --dport 21116 -j ACCEPT # vps -> homelab: tcp on port 21116
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p udp --sport 21116 -j ACCEPT # homelab -> vps: tcp on port 21116
# 21118 tcp (web client support)
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21118 -j DNAT --to-destination $HOMELAB_IP:21118 # tcp packets on port 21118
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21118 -j ACCEPT # vps -> homelab: tcp on port 21118
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21118 -j ACCEPT # homelab -> vps: tcp on port 21118
# hbbr ports
# 21117 tcp (relay services)
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21117 -j DNAT --to-destination $HOMELAB_IP:21117 # tcp packets on port 21117
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21117 -j ACCEPT # vps -> homelab: tcp on port 21117
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21117 -j ACCEPT # homelab -> vps: tcp on port 21117
# 21119 tcp (web client support)
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21119 -j DNAT --to-destination $HOMELAB_IP:21119 # tcp packets on port 21119
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21119 -j ACCEPT # vps -> homelab: tcp on port 21119
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21119 -j ACCEPT
'';
# Rustdesk ports
# { sourcePort = 21115; destination = "10.10.0.10:21115"; proto = "tcp"; }
# { sourcePort = 21116; destination = "10.10.0.10:21116"; proto = "tcp"; }
# { sourcePort = 21116; destination = "10.10.0.10:21116"; proto = "udp"; }
# { sourcePort = 21118; destination = "10.10.0.10:21118"; proto = "tcp"; }
# { sourcePort = 21117; destination = "10.10.0.10:21117"; proto = "tcp"; }
# { sourcePort = 21119; destination = "10.10.0.10:21119"; proto = "tcp"; }
];
};
# what actually does the forwarding
firewall = {
enable = true;
allowedTCPPorts = [22 80 443 25777 25579 7567 21115 21116 21117 21118 21119];
# tailscale will also need its UDP port open:
allowedUDPPorts = [config.services.tailscale.port 2456 2457 25777 21116 25580];
trustedInterfaces = ["tailscale0"];
/*
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination ${snowbelle_ip}:80 # http
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination ${snowbelle_ip}:443 # https
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 80 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # http
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 443 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # https
*/
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 7567 -j DNAT --to-destination ${lumiose_ip}:7567 # gitea ssh
# iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 7567 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # gitea ssh
extraCommands = ''
# Clear any previous rules if you are iterating
iptables -t nat -F
# DNAT: internet -> homelab over tailscale
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25777 -j DNAT --to-destination ${lumiose_ip}:25777 # recpro mc
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 25777 -j DNAT --to-destination ${lumiose_ip}:25777 # recpro mc
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25579 -j DNAT --to-destination ${snowbelle_ip}:25579 # craftoria mc
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 25580 -j DNAT --to-destination ${snowbelle_ip}:25580 # craftoria mc voice chat
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 2456 -j DNAT --to-destination ${lumiose_ip}:2456 # valheim server
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 2457 -j DNAT --to-destination ${lumiose_ip}:2457 # valheim server
# SNAT: ensure replies go back through VPS tailscale IP
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 25777 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # recpro mc
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 25777 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # recpro mc
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 25579 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # craftoria mc
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 25580 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # craftoria mc voicechat
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 2456 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # valheim server
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 2457 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # valheim server
'';
};
};
# enable tailscale for to forward over!
services.tailscale = {
enable = true;
useRoutingFeatures = "server";
extraSetFlags = [
"--advertise-exit-node"
];
};
# forwarding for caddy
services.caddy = {
globalConfig = ''
auto_https ignore_loaded_certs
'';
virtualHosts = {
# for central uptime monitoring
"up.${homelab.public_domain}".extraConfig = ''
reverse_proxy 127.0.0.1:7901
'';
# below is basically just manually reverse proxying everything in the homelab
# this is instead of forwarding all 80 & 443 traffic to have more explicit
# publishing things to the open web
"media.${homelab.public_domain}".extraConfig = ''
reverse_proxy ${lumiose_ip}:7100
'';
"photos.${homelab.public_domain}".extraConfig = ''
reverse_proxy ${lumiose_ip}:7702
'';
"hass.${homelab.public_domain}".extraConfig = ''
reverse_proxy ${lumiose_ip}:7704 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto https
}
'';
# now hosted on vaniville!
# "pass.${homelab.public_domain}".extraConfig = ''
# reverse_proxy 127.0.0.1:7701
# '';
# "git.${homelab.public_domain}".extraConfig = ''
# reverse_proxy localhost:7703
# '';
};
};
system.stateVersion = "25.05"; # Did you read the comment? system.stateVersion = "25.05"; # Did you read the comment?
} }
@@ -0,0 +1,34 @@
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
boot.kernelParams = [ "console=ttyS0,19200n8" ];
boot.loader.grub.device = "nodev";
boot.loader.timeout = 10;
boot.loader.grub.extraConfig = ''
serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
terminal_input serial;
terminal_output serial
'';
fileSystems."/" =
{ device = "/dev/sda";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/sdb"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+58
View File
@@ -0,0 +1,58 @@
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
let
pkgs = stable_pkgs.x86_64;
unstable = unstable_pkgs.x86_64;
in
{
imports =
[
./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/system
#../../../modules/homelab
];
home-manager.users.blake.imports = [
../../../users/blake/hosts/wsl.nix
];
wsl = {
enable = true;
defaultUser = "blake";
};
system = {
ssh.enable = true;
sops.enable = true;
};
boot = {
loader = {
efi.canTouchEfiVariables = true;
grub = {
enable = true;
forceInstall = true;
};
};
};
# define shell
programs.zsh.enable = true;
users.defaultUserShell = pkgs.zsh;
# packages reccomended by linode
environment.systemPackages = with pkgs; [
];
# setup the network forwarding this host is designed for
# general networking config
networking = {
hostName = "zygarde"; # Define your hostname.
};
system.stateVersion = "25.05"; # Did you read the comment?
}
+74 -44
View File
@@ -1,87 +1,117 @@
{ config, lib, modulesPath, inputs, stable_pkgs, unstable_pkgs, ... }:
{ {
imports = pkgs,
[ # Include the results of the hardware scan. config,
(modulesPath + "/installer/scan/not-detected.nix") lib,
#./hardware-configuration.nix modulesPath,
../../nixos inputs,
../../../modules/desktop/hypr stable_pkgs,
../../../modules/desktop/greetd unstable_pkgs,
../../../users/blake ...
../../../modules/system }: {
]; imports = [
# Include the results of the hardware scan.
home-manager.users.blake.imports = [ (modulesPath + "/installer/scan/not-detected.nix")
../../../users/blake/hosts/yveltal.nix #./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
]; ];
# home grown nixos modules
system = { system = {
secure_boot.enable = true;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true; ssh.enable = true;
sops.enable = true; sops.enable = true;
yubikey.enable = true; yubikey.enable = true;
yubikey.lock_on_remove = false;
tailscale.enable = true; tailscale.enable = true;
syncthing.enable = true; syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "intel";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = false;
greetd.enable = true;
kde.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = false;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
}; };
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons # fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = { services.logind.settings.Login = {
HandlePowerKey = "suspend"; HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend"; HandleLidSwitch = "suspend-then-hibernate";
#HibernateDelaySec = "30min"; };
# sets the delay before hibernation for ^
systemd.sleep.settings.Sleep = {
HibernateDelaySec = "30m";
}; };
# boot (systemd is growing on me) # boot (systemd is growing on me)
boot = { boot = {
kernelModules = [ "kvm-intel" ]; kernelModules = ["kvm-intel"];
extraModulePackages = [ ]; extraModulePackages = [];
loader = { loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
}; };
initrd = { initrd = {
systemd.enable = true; # better logging systemd.enable = true; # better logging
availableKernelModules = [ "xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" ]; availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod"];
kernelModules = [ ]; kernelModules = [];
}; };
}; };
# setup hostname and networking stack # setup hostname and networking stack
services.resolved = {
enable = true;
fallbackDns = [ "1.1.1.1" "9.9.9.9" ];
dnsovertls = "opportunistic";
};
networking = { networking = {
hostName = "yveltal"; # hostname hostName = "yveltal"; # hostname
useDHCP = lib.mkDefault true; useDHCP = lib.mkDefault true;
interfaces = { interfaces = {
wlp0s20f3.useDHCP = lib.mkDefault true; wlp0s20f3.useDHCP = lib.mkDefault true;
}; };
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = { networkmanager = {
enable = true; # the goat enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer! dns = "systemd-resolved"; # the backup dancer!
}; };
}; };
services.resolved = {
enable = true;
settings = {
Resolve = {
FallbackDNS = ["1.1.1.1" "9.9.9.9"];
DNSOverTLS = "opportunistic";
};
};
};
hardware.bluetooth.enable = true; hardware.bluetooth.enable = true;
# Open ports in the firewall.
networking.firewall.allowedTCPPorts = [
22
];
networking.firewall.allowedUDPPorts = [ 51820 ];
# Or disable the firewall altogether.
networking.firewall.enable = true;
system.stateVersion = "25.05"; # stays here : ) system.stateVersion = "25.05"; # stays here : )
# hardware shit # hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }
+63
View File
@@ -0,0 +1,63 @@
{
pkgs,
config,
lib,
...
}: let
service = "apps";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "installs generally wanted apps";
};
config = lib.mkIf cfg.enable {
# environment.systemPackages = with pkgs; [
# open-webui
# ];
homebrew = {
brews = [
"iperf3"
"p7zip"
"sl"
"cowsay"
"apfel"
"yt-dlp"
"ffmpeg"
"ffmpeg-full"
];
casks = [
"gnucash"
"utm"
"libreoffice"
"firefox"
"zen"
"grandperspective"
"spotify"
"obs"
"gimp"
"audacity"
"anki"
"rustdesk"
"mullvad-vpn"
"transmission"
"finetune"
"yacreader"
"keepassxc"
"thunderbird"
"musicbrainz-picard"
];
masApps = {
"pages" = 361309726;
"numbers" = 361304891;
"keynote" = 361285480;
"bitwarden" = 1352778147;
"darkreader" = 1438243180;
"ghostery" = 6504861501;
"privacy" = 6449850851;
"flo" = 6529533140;
};
};
};
}
+40
View File
@@ -0,0 +1,40 @@
{
pkgs,
config,
lib,
...
}:
let
service = "cyber";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "install cyber sec apps";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
metasploit
];
homebrew = {
brews = [
"nmap"
"rustscan"
"masscan"
"nikto"
"aircrack-ng"
"hashcat"
"john"
"sqlmap"
"gobuster"
"ffuf"
];
casks = [
"wireshark-app"
];
};
};
}
+17
View File
@@ -0,0 +1,17 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
./tailscale
./nextdns
./syncthing
./yubikey
./work
./apps
./cyber
./gaming
];
}
+33
View File
@@ -0,0 +1,33 @@
{
pkgs,
config,
lib,
...
}: let
service = "gaming";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "installs generally wanted apps";
};
config = lib.mkIf cfg.enable {
# environment.systemPackages = with pkgs; [
# uhhh
# ];
homebrew = {
brews = [
];
casks = [
"steam"
"prismlauncher"
"discord"
# "runelite"
# "jagex"
];
masApps = {
};
};
};
}
+23
View File
@@ -0,0 +1,23 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "nextdns";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "enables ${service}";
};
config = lib.mkIf cfg.enable {
services.${service} = {
enable = true;
arguments = [
"-profile 527db2"
];
};
};
}
+25
View File
@@ -0,0 +1,25 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "sops";
cfg = config.darwin.${service};
in {
imports = [inputs.sops-nix.nixosModules.sops];
options.darwin.sops = {
enable = lib.mkEnableOption "enables sops";
};
config = lib.mkIf cfg.enable {
# enable and configure sops for secrets
sops = {
defaultSopsFile = ../../../secrets/secrets.yaml;
defaultSopsFormat = "yaml";
age.keyFile = "/etc/sops/keys.txt";
};
};
}
+35
View File
@@ -0,0 +1,35 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "syncthing";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "enables syncthing";
host = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = config.networking.hostName;
};
};
config = lib.mkIf cfg.enable {
# environment.systemPackages = with pkgs; [
# syncthing
# syncthingtray
# ];
#
homebrew = {
# brews = [
# "syncthing"
# ];
casks = [
"syncthing-app"
];
};
};
}
+32
View File
@@ -0,0 +1,32 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "tailscale";
cfg = config.darwin.${service};
in {
options.darwin.tailscale = {
enable = lib.mkEnableOption "enables tailscale";
};
config = lib.mkIf cfg.enable {
# services.tailscale = {
# enable = true;
# #overrideLocalDns = true;
# #authKeyFile = authkey_file;
# };
# environment.systemPackages = with pkgs; [
# tailscale-gui
# ];
# homebrew = {
# casks = [
# "tailscale-app"
# ];
# };
};
}
+36
View File
@@ -0,0 +1,36 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "work";
cfg = config.darwin.${service};
in {
options.darwin.work = {
enable = lib.mkEnableOption "installs apps for work";
};
config = lib.mkIf cfg.enable {
# services.tailscale = {
# enable = true;
# #overrideLocalDns = true;
# #authKeyFile = authkey_file;
# };
homebrew = {
casks = [
"asana"
"microsoft-teams"
"microsoft-office"
"jump-desktop"
"wifiman"
"adobe-acrobat-pro"
];
masApps = {
"configurator" = 1037126344;
};
};
};
}
+34
View File
@@ -0,0 +1,34 @@
{
pkgs,
config,
lib,
...
}:
let
service = "yubikey";
cfg = config.darwin.${service};
in {
options.darwin.${service} = {
enable = lib.mkEnableOption "enables ${service}";
};
config = lib.mkIf cfg.enable {
# environment.systemPackages = with pkgs; [
# yubikey-personalization
# yubikey-manager
# yubikey-piv-tool
# ];
homebrew = {
brews = [
"yubico-piv-tool"
];
casks = [
"yubico-authenticator"
];
};
};
}
+14
View File
@@ -0,0 +1,14 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
./pipewire
./hypr
./greetd
./gaming
./kde
];
}
+16
View File
@@ -0,0 +1,16 @@
{
pkgs,
config,
inputs,
lib,
...
}: {
imports = [
inputs.slippi.nixosModules.default # gcc drivers
./steam
./lutris
./proton_ge
./gamemode
./mangohud
];
}
@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.gamemode;
in {
options.gaming.gamemode = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# enable gamemode for game optimizations
# requires setting launch option `gamemoderun %command%`
programs.gamemode.enable = true;
};
}
+19
View File
@@ -0,0 +1,19 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.lutris;
in {
options.gaming.lutris = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
lutris
wine
];
};
}
@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.mangohud;
in {
options.gaming.mangohud = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# preformance overlay
# requires setting launch option `mangohud %command%`
environment.systemPackages = with pkgs; [
mangohud
];
};
}
@@ -0,0 +1,24 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.proton_ge;
in {
options.gaming.proton_ge = {
enable = lib.mkEnableOption "enable proton ge";
};
# this is an imperitive install after rebuild run `protonup`
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
protonup-ng
];
# tells `protonup` what path to use
environment.sessionVariables = {
STEAM_EXTRA_COMPACT_TOOLS_PATHS = "/home/blake/.steam/root/compatibilitytools.d";
};
};
}
+22
View File
@@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.steam;
in {
options.gaming.steam = {
enable = lib.mkEnableOption "enable steam";
};
config = lib.mkIf cfg.enable {
programs.steam = {
enable = true;
gamescopeSession.enable = true; # requires setting launch option `gamescope <options> -- %command%`
remotePlay.openFirewall = true; # open ports for remote play
#dedicatedServer.openFirewall = true; # open ports for source dedicated server
protontricks.enable = true;
};
};
}
+22 -15
View File
@@ -3,25 +3,32 @@
lib, lib,
config, config,
... ...
}: { }: let
cfg = config.desktop.greetd;
in {
options.desktop.greetd = {
enable = lib.mkEnableOption "enable greetd with tuigreet";
};
services.greetd = { config = lib.mkIf cfg.enable {
enable = true; services.greetd = {
# tuigreet command to run enable = true;
settings = { # tuigreet command to run
default_session = { settings = {
user = "greeter"; default_session = {
command = "${pkgs.tuigreet}/bin/tuigreet -c Hyprland -t --greeting \"howdy o/\" --user-menu --remember --remember-user-session --power-shutdown \"systemctl poweroff\" --power-reboot \"systemctl reboot\""; user = "greeter";
command = "${pkgs.tuigreet}/bin/tuigreet -c Hyprland -t --greeting \"howdy o/\" --user-menu --remember --remember-user-session --power-shutdown \"systemctl poweroff\" --power-reboot \"systemctl reboot\"";
};
}; };
}; };
};
# allow yubikey signin with u2f # allow yubikey signin with u2f
security.pam.services.greetd.u2fAuth = true; security.pam.services.greetd.u2fAuth = true;
# ensure the user exists # ensure the user exists
users.users.greeter = { users.users.greeter = {
isSystemUser = true; isSystemUser = true;
description = "user for greetd"; description = "user for greetd";
};
}; };
} }
+14 -6
View File
@@ -3,12 +3,20 @@
lib, lib,
config, config,
... ...
}: { }: let
cfg = config.desktop.hypr;
in {
options.desktop.hypr = {
enable = lib.mkEnableOption "enable hypr on nixos side";
};
# enable hyprland config = lib.mkIf cfg.enable {
programs.hyprland.enable = true; # enable hyprland
programs.hyprland.enable = true;
# give hyprlock perms to unlock
# give hyprlock perms to unlock security.pam.services.hyprlock = {
security.pam.services.hyprlock = {}; enable = true;
};
};
} }
+53
View File
@@ -0,0 +1,53 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.kde;
in {
options.desktop.kde = {
enable = lib.mkEnableOption "enable kde on nixos side";
};
config = lib.mkIf cfg.enable {
# enable kde plasma
services = {
desktopManager.plasma6.enable = true;
#displayManager.sddm.enable = true;
#displayManager.sddm.wayland.enable = true;
};
environment.systemPackages = with pkgs; [
# KDE Utilities
kdePackages.discover # Optional: Software center for Flatpaks/firmware updates
kdePackages.kcalc # Calculator
kdePackages.kcharselect # Character map
kdePackages.kclock # Clock app
kdePackages.kcolorchooser # Color picker
kdePackages.kolourpaint # Simple paint program
kdePackages.ksystemlog # System log viewer
kdePackages.sddm-kcm # SDDM configuration module
kdiff3 # File/directory comparison tool
# Hardware/System Utilities (Optional)
kdePackages.isoimagewriter # Write hybrid ISOs to USB
kdePackages.partitionmanager # Disk and partition management
hardinfo2 # System benchmarks and hardware info
wayland-utils # Wayland diagnostic tools
wl-clipboard # Wayland copy/paste support
vlc # Media player
];
environment.plasma6.excludePackages = with pkgs; [
kdePackages.elisa # Music player
kdePackages.kdepim-runtime # Akonadi agents
kdePackages.kmahjongg
#kdePackages.kmines
kdePackages.konversation # IRC client
kdePackages.kpat # Solitaire
kdePackages.ksudoku
kdePackages.ktorrent
];
};
}
+136
View File
@@ -0,0 +1,136 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.pipewire;
in {
options.desktop.pipewire = {
enable = lib.mkEnableOption "enable pipewire for sound!";
};
config = lib.mkIf cfg.enable {
security.rtkit.enable = true;
environment.systemPackages = with pkgs; [
qpwgraph # patching software
pavucontrol # volume mixer
pulsemixer
];
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
jack.enable = true;
wireplumber = {
enable = true;
extraConfig = {
"90-yveltal-renames" = {
"monitor.alsa.rules" = [
# audio sinks
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink";
}
];
actions = {
"update-props" = {
"node.description" = "Speakers / 3.5mm";
"node.nick" = "Speakers / 3.5mm";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 1";
"node.nick" = "HDMI / DP 1";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI2__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 2";
"node.nick" = "HDMI / DP 2";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI3__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 3";
"node.nick" = "HDMI / DP 3";
};
};
}
# audio sources
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Headset__source";
}
];
actions = {
"update-props" = {
"node.description" = "3.5mm Mic";
"node.nick" = "3.5mm Mic";
};
};
}
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Mic1__source";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Mic";
"node.nick" = "Laptop Mic";
};
};
}
# audio controllers
{
matches = [
{
"device.name" = "alsa_card.pci-0000_00_1f.3-platform-skl_hda_dsp_generic";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Controller";
"node.nick" = "Laptop Controller";
};
};
}
];
};
};
};
};
};
}
+26
View File
@@ -0,0 +1,26 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
# services show up in glance in reverse import order lmao
imports = [
./nfs
./smb
./zfs
./syncthing
./offsite
# ./copyparty
./perms
];
# # define the groups used for backups and archives
# users.users.archives = {
# isSystemUser = true;
# group = "archives";
# };
#
# users.groups.archives = {gid = 727;};
}
@@ -0,0 +1,68 @@
{
config,
pkgs,
lib,
...
}: let
service = "offsite";
cfg = config.holocron.${service};
sec = config.sops.secrets;
in {
options.holocron.offsite = {
enable = lib.mkEnableOption "enables backup script for holocron fileshare";
paths = lib.mkOption {
type = with lib.types; listOf str;
default = [
"/holocron/srv"
"/holocron/users"
];
description = "list of paths to backup";
};
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron";
description = "path to rsync offsite backups to";
};
};
config = lib.mkIf cfg.enable {
systemd.services.${service} = {
description = "holocron daily sync";
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "archives";
};
script = ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "${pkgs.openssh}/bin/ssh -o StrictHostKeyChecking=no" \
${builtins.concatStringsSep " " cfg.paths} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
'';
};
systemd.timers.${service} = {
description = "timer for ${service}";
wantedBy = ["timers.target"];
timerConfig = {
OnCalendar = "*-*-* 05:00:00";
Persistent = true;
};
};
};
}
+130
View File
@@ -0,0 +1,130 @@
{
pkgs,
config,
lib,
...
}:
# define smb shares
let
cfg = config.holocron.smb;
smb_shares = {
global = {
# time machine specifc config, must be global
"fruit:aapl" = "yes";
"fruit:nfs_aces" = "no";
"fruit:metadata" = "stream";
"fruit:model" = "TimeCapsule";
"fruit:posix_rename" = "yes";
"fruit:veto_appledouble" = "no";
"fruit:wipe_intentionally_left_blank_rfork" = "yes";
"fruit:delete_empty_adfiles" = "yes";
"vfs objects" = "catia fruit streams_xattr";
"ea support" = "yes";
"spotlight" = "no";
"multicast dns register" = "no";
"min protocol" = "SMB2";
};
archives = {
path = "/holocron/archives";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
timemachine = {
browseable = true;
"path" = "/holocron/archives/timemachine";
"valid users" = "blake";
"public" = "no";
"writeable" = "yes";
"force user" = "blake";
# time machine specifc config
"fruit:time machine" = "yes";
"fruit:time machine max size" = "5T";
"case sensitive" = "yes";
"default case" = "lower";
"preserve case" = "no";
"short preserve case" = "no";
"create mask" = "0660";
"directory mask" = "0770";
"force group" = "blake";
};
users = {
path = "/holocron/users";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0660";
"directory mask" = "0770";
};
media = {
path = "/holocron/media";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
nvr = {
path = "/holocron/nvr";
writable = true;
guestOk = false;
browseable = true;
"valid users" = "archives";
"public" = "no";
"writeable" = "yes";
"force user" = "archives";
# time machine specifc config
"create mask" = "0660";
"directory mask" = "0770";
"force group" = "archives";
};
};
in {
options.holocron.smb = {
enable = lib.mkEnableOption "enables smb";
};
config = lib.mkIf cfg.enable {
# enable smb with all shares
services.samba = {
enable = true;
package = pkgs.sambaFull;
settings = smb_shares;
};
# ensure time machine can discover the share without `tmutil`
services.avahi = {
enable = true;
openFirewall = true;
nssmdns4 = true;
publish.enable = true;
publish.userServices = true;
extraServiceFiles = {
timemachine = ''
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_smb._tcp</type>
<port>445</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=TimeCapsule8,119</txt-record>
</service>
<service>
<type>_adisk._tcp</type>
<port>0</port>
<txt-record>dk0=adVN=timemachine,adVF=0x82</txt-record>
<txt-record>sys=waMa=0,adVF=0x100</txt-record>
</service>
</service-group>
'';
};
};
};
}
@@ -7,7 +7,7 @@
service = "syncthing"; service = "syncthing";
cfg = config.holocron.${service}; cfg = config.holocron.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
url = "syncthing.snowbelle.lan"; url = "syncthing.${config.networking.hostName}.holocron.blue";
homelab = config.homelab; homelab = config.homelab;
in { in {
options.holocron.${service} = { options.holocron.${service} = {
@@ -22,30 +22,30 @@ in {
dataDir = "/var/lib/syncthing"; dataDir = "/var/lib/syncthing";
guiAddress = "0.0.0.0:2222"; guiAddress = "0.0.0.0:2222";
openDefaultPorts = true; openDefaultPorts = true;
extraFlags = ["--no-default-folder"]; #extraFlags = ["--no-default-folder"];
key = sec."${service}/snowbelle/key".path; key = sec."${service}/lumiose/key".path;
cert = sec."${service}/snowbelle/cert".path; cert = sec."${service}/lumiose/cert".path;
settings = { settings = {
devices = { devices = {
"lugia" = {id = "BKKSFPH-YEOVVAB-DTT7KK3-UDKAEJ2-PC6ECG7-Y76ZIVP-JRYMMXS-RTZYVQ3";}; "piplup" = {id = "OV4NUQK-3YHRL5R-SIZGTNL-7VZFFUX-FOJ6NTS-C7ROXR7-I2Q2W7G-QERO7AO";};
"zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";}; "zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";};
"yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";}; "yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";};
"CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";}; "CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";};
"CEN-IT-00007" = {id = "UEWNSUZ-AX75M5Y-OA4FURY-ORMEXFA-XUXU4LU-LEUYKVW-IDM2GQC-4UR4YAL";};
}; };
folders = { folders = {
"holocron" = { "holocron" = {
path = "/holocron/users/blake/holocron"; path = "/holocron/users/blake/holocron";
devices = ["lugia" "zygarde" "CEN-IT-07" "yveltal"]; devices = ["piplup" "zygarde" "CEN-IT-07" "CEN-IT-00007" "yveltal"];
id = "5voxg-c3he2"; id = "5voxg-c3he2";
versioning = { # versioning = {
type = "staggered"; # type = "staggered";
fsPath = "/holocron/users/blake/holocron/.stversions"; # fsPath = "/holocron/users/blake/holocron/.stversions";
params = { # params = {
cleanInterval = "3600"; # cleanInterval = "3600";
maxAge = "0"; # maxAge = "0";
}; # };
}; # };
}; };
}; };
options = { options = {
@@ -55,32 +55,35 @@ in {
}; };
sops.secrets = { sops.secrets = {
"${service}/snowbelle/key" = { "${service}/lumiose/key" = {
owner = "blake"; owner = "blake";
group = "blake"; group = "blake";
}; };
"${service}/snowbelle/cert" = { "${service}/lumiose/cert" = {
owner = "blake"; owner = "blake";
group = "blake"; group = "blake";
}; };
}; };
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ config.services.syncthing.dataDir ]; }; ${service} = {paths = [config.services.syncthing.dataDir];};
}; };
services.caddy.virtualHosts."${url}" = { services.caddy.virtualHosts."${url}" = {
extraConfig = '' extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key tls internal
reverse_proxy 127.0.0.1:2222 reverse_proxy 127.0.0.1:2222
''; '';
}; };
# add to glance (local service) # add to glance (local service)
homelab.glance.links.system = [{ homelab.glance.links.system = [
title = service; {
url = "https://${url}"; title = service;
error-url = "http://${homelab.host_ip}:2222"; url = "https://${url}";
check-url = "http://${homelab.host_ip}:2222"; error-url = "http://${homelab.host_ip}:2222";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:2222";
icon = "di:${service}";
}
];
}; };
} }
@@ -0,0 +1,72 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.holocron.zfs;
sec = config.sops.secrets;
in {
options.holocron.zfs = {
enable = lib.mkEnableOption "enables zfs";
};
config = lib.mkIf cfg.enable {
# set network host id
# enable zfs support
boot.kernelModules = ["zfs"];
boot.supportedFilesystems = ["zfs"];
boot.zfs.forceImportRoot = false;
# boot.initrd.services.zfs.enable = true;
# boot.zfs.requestEncryptionCredentials = true;
# arc cache size
boot.kernelParams = ["zfs.zfs_arc_max=12884901888"];
# pools to import
boot.zfs.extraPools = ["holocron"];
# enable smart monitoring
services.smartd = {
enable = true;
autodetect = true;
defaults.monitored = "-a -o on -s (S/../.././05|L/../01/./05)";
notifications = {
test = false;
mail = {
enable = true;
recipient = "blake";
sender = "alerts@blakedheld.xyz";
};
};
};
# enable zfs
services.zfs = {
autoScrub.enable = true;
autoScrub.interval = "weekly";
autoSnapshot = {
enable = true;
frequent = 4; # 15 min snapshots
hourly = 24; # hourly snapshots
daily = 7; # daily snapshots
weekly = 4; # weekly snapshots
monthly = 12; # monthly snapshots
};
# email notifs
zed = {
enableMail = true;
settings = {
ZED_EMAIL_ADDR = ["root" "blake"];
# send notification if scrub succeeds
ZED_NOTIFY_VERBOSE = true;
};
};
};
# install userspace tools for smart
environment.systemPackages = with pkgs; [smartmontools];
};
}
+162
View File
@@ -0,0 +1,162 @@
{
pkgs,
config,
lib,
...
}: let
service = "cs2";
cfg = config.gameservers.${service};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "Counter Strike 2 server";
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/cs2";
};
port = lib.mkOption {
type = lib.types.int;
default = 27015;
};
tv_port = lib.mkOption {
type = lib.types.int;
default = 27016;
};
hostname = lib.mkOption {
type = lib.types.str;
default = "recoil.pro CS2";
};
map = lib.mkOption {
type = lib.types.str;
default = "de_dust2";
};
max_players = lib.mkOption {
type = lib.types.int;
default = 10;
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/cs2";
};
};
config = lib.mkIf cfg.enable {
users.users.cs2 = {
isSystemUser = true;
group = "cs2";
home = cfg.data_dir;
createHome = true;
};
users.groups.cs2 = {};
environment.systemPackages = with pkgs; [
steamcmd
steam-run
rcon
];
systemd.tmpfiles.rules = [
"d ${cfg.data_dir} 0770 cs2 cs2 -"
"d ${cfg.data_dir}/server 0770 cs2 cs2 -"
];
environment.etc."cs2/server.cfg".text = ''
hostname "${cfg.hostname}"
sv_lan 0
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
mp_autoteambalance 1
mp_limitteams 2
'';
systemd.services.cs2-update = {
description = "Update CS2 server";
serviceConfig = {
Type = "oneshot";
User = "cs2";
};
script = ''
${pkgs.steamcmd}/bin/steamcmd \
+force_install_dir ${cfg.data_dir}/server \
+login anonymous \
+app_update 730 validate \
+quit
'';
};
systemd.services.cs2-server = {
description = "Counter Strike 2 Dedicated Server";
after = [
"network.target"
"cs2-update.service"
];
requires = [
"cs2-update.service"
];
wantedBy = ["multi-user.target"];
serviceConfig = {
User = "cs2";
Group = "cs2";
WorkingDirectory = "${cfg.data_dir}";
Restart = "always";
ExecStart = pkgs.writeShellScript "cs2-start" ''
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
exec ${pkgs.steam-run}/bin/steam-run -- \
${cfg.data_dir}/server/game/bin/linuxsteamrt64/cs2 \
-dedicated \
-usercon \
-console \
-port ${toString cfg.port} \
-tv_port ${toString cfg.tv_port} \
-maxplayers_override ${toString cfg.max_players} \
+game_type 0 \
+game_mode 1 \
+mapgroup mg_active \
+map ${cfg.map} \
+sv_setsteamaccount "$GSLT" \
+exec /etc/gameserver/cs2/server.cfg
'';
};
};
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
# backups cs2 server with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# manage secrets with sops
sops.secrets = {
"${service}/gslt" = {
owner = service;
group = service;
};
"${service}/rcon" = {
owner = service;
group = service;
};
};
};
}
+162
View File
@@ -0,0 +1,162 @@
{
pkgs,
config,
lib,
...
}: let
service = "cs2";
cfg = config.gameservers.${service};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "Counter Strike 2 server";
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/cs2";
};
port = lib.mkOption {
type = lib.types.int;
default = 27015;
};
tv_port = lib.mkOption {
type = lib.types.int;
default = 27016;
};
hostname = lib.mkOption {
type = lib.types.str;
default = "recoil.pro CS2";
};
map = lib.mkOption {
type = lib.types.str;
default = "de_dust2";
};
max_players = lib.mkOption {
type = lib.types.int;
default = 10;
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/cs2";
};
};
config = lib.mkIf cfg.enable {
users.users.cs2 = {
isSystemUser = true;
group = "cs2";
home = cfg.data_dir;
createHome = true;
};
users.groups.cs2 = {};
environment.systemPackages = with pkgs; [
steamcmd
steam-run
rcon
];
systemd.tmpfiles.rules = [
"d ${cfg.data_dir} 0770 cs2 cs2 -"
"d ${cfg.data_dir}/server 0770 cs2 cs2 -"
];
environment.etc."cs2/server.cfg".text = ''
hostname "${cfg.hostname}"
sv_lan 0
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
mp_autoteambalance 1
mp_limitteams 2
'';
systemd.services.cs2-update = {
description = "Update CS2 server";
serviceConfig = {
Type = "oneshot";
User = "cs2";
};
script = ''
${pkgs.steamcmd}/bin/steamcmd \
+force_install_dir ${cfg.data_dir}/server \
+login anonymous \
+app_update 730 validate \
+quit
'';
};
systemd.services.cs2-server = {
description = "Counter Strike 2 Dedicated Server";
after = [
"network.target"
"cs2-update.service"
];
requires = [
"cs2-update.service"
];
wantedBy = ["multi-user.target"];
serviceConfig = {
User = "cs2";
Group = "cs2";
WorkingDirectory = "${cfg.data_dir}/server";
Restart = "always";
ExecStart = pkgs.writeShellScript "cs2-start" ''
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
exec ${pkgs.steam-run}/bin/steam-run -- \
${cfg.data_dir}/server/game/cs2.sh \
-dedicated \
-usercon \
-console \
-port ${toString cfg.port} \
-tv_port ${toString cfg.tv_port} \
-maxplayers_override ${toString cfg.max_players} \
+game_type 0 \
+game_mode 1 \
+mapgroup mg_active \
+map ${cfg.map} \
+sv_setsteamaccount "$GSLT" \
+exec /etc/gameserver/cs2/server.cfg
'';
};
};
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
# backups cs2 server with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# manage secrets with sops
sops.secrets = {
"${service}/gslt" = {
owner = service;
group = service;
};
"${service}/rcon" = {
owner = service;
group = service;
};
};
};
}
@@ -0,0 +1,188 @@
{
pkgs,
config,
lib,
...
}: let
service = "minecraft_modded";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
servers = {
# cobblemon = {
# data_dir = "/var/lib/gameservers/minecraft_modded/cobblemon";
# start_file = "start.sh";
# };
linggango = {
data_dir = "/var/lib/gameservers/minecraft_modded/linggango";
start_file = "start.sh";
};
};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
url = lib.mkOption {
type = lib.types.str;
default = "modded.recoil.pro";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = 25565;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
motd_gs = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = ["craftoria"];
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/var/backup/gameservers/minecraft/modded";
description = "path to take hourly backups to with borg!";
};
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron/archives/gameservers";
description = "path to rsync offsite backups to";
};
};
config = lib.mkIf cfg.enable {
users.groups.minecraft = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.minecraft = lib.mkDefault {
description = "minecraft server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
group = "minecraft";
extraGroups = [];
};
systemd.tmpfiles.rules =
lib.attrsets.mapAttrsToList (
name: cfg: "d ${cfg.data_dir} 0770 minecraft minecraft -"
)
servers;
# Create a systemd service per server running in tmux
systemd.services =
lib.attrsets.mapAttrs (name: srv: {
description = "minecraft_recpro: ${name}";
after = ["network.target"];
wants = ["network.target"];
path = [pkgs.openjdk21];
serviceConfig = {
User = "minecraft";
Group = "minecraft";
WorkingDirectory = srv.data_dir;
UMask = "0007";
#ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx12G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true @libraries/net/neoforged/neoforge/21.1.211/unix_args.txt";
#ExecStart = "${srv.data_dir}/${srv.start_file}";
ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx24G @libraries/net/minecraftforge/forge/1.20.1-47.4.20/unix_args.txt \"$@\"";
Restart = "on-failure";
KillMode = "process";
};
wantedBy = ["multi-user.target"];
})
servers;
environment.systemPackages = with pkgs; [openjdk21 mcrcon borgbackup sshpass tree rsync];
# services.mysql = {
# enable = true;
# package = pkgs.mariadb;
# ensureDatabases = ["minecraft_recpro_db"];
# ensureUsers = [
# {
# name = "minecraft";
# ensurePermissions = {"minecraft_recpro_db.*" = "ALL PRIVILEGES";};
# }
# ];
# initialScript = pkgs.writeText "minecraft_recpro-init.sql" ''
# CREATE USER IF NOT EXISTS 'minecraft_recpro'@'localhost' IDENTIFIED BY 'IKNOWTHISISBADIJUSTNEEDTHISTOWORKRNPLS';
# GRANT ALL PRIVILEGES ON minecraft_recpro_db.* TO 'minecraft_recpro'@'localhost';
# FLUSH PRIVILEGES;
# '';
# };
# open firewall
networking.firewall.allowedTCPPorts = [25579];
networking.firewall.allowedUDPPorts = [25580]; #voicechat
sops.secrets = {
"borg_passwd" = {
owner = "root";
group = "root";
};
"lifeboat_rsync" = {
owner = "root";
group = "archives";
mode = "0440";
};
};
# helpful and for scripts
users.groups.archives = {gid = 727;};
# backups minecraft_modded with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = lib.flatten (
lib.attrValues (
lib.mapAttrs (_: srv:
[srv.data_dir]
++ (
if builtins.hasAttr "db_dump" srv
then [srv.db_dump]
else []
))
servers
)
);
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
postHook = ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
'';
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}
@@ -49,15 +49,30 @@ in {
default = false; default = false;
description = "enable backups for ${service}"; description = "enable backups for ${service}";
}; };
motd = lib.mkOption { motd_gs = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = "velocity"; default = ["velocity" "smp" "superflat" "bento"];
}; };
backup_repo = lib.mkOption { backup_repo = lib.mkOption {
type = lib.types.path; type = lib.types.path;
default = "/holocron/archives/gameservers/minecraft/recpro_stack"; default = "/holocron/archives/gameservers/minecraft/recpro_stack";
description = "path to take hourly backups to with borg!"; description = "path to take hourly backups to with borg!";
}; };
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron/archives/gameservers";
description = "path to rsync offsite backups to";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@@ -91,7 +106,7 @@ in {
Group = "minecraft"; Group = "minecraft";
WorkingDirectory = srv.data_dir; WorkingDirectory = srv.data_dir;
UMask = "0007"; UMask = "0007";
ExecStart = "${pkgs.openjdk21}/bin/java -Xmx${srv.ram} -jar server.jar nogui"; ExecStart = "${pkgs.openjdk25}/bin/java -Xmx${srv.ram} -jar server.jar nogui";
Restart = "on-failure"; Restart = "on-failure";
KillMode = "process"; KillMode = "process";
}; };
@@ -152,6 +167,13 @@ in {
); );
compression = "auto,zstd"; compression = "auto,zstd";
preHook = "systemctl start mysql-backup.service"; preHook = "systemctl start mysql-backup.service";
postHook = ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
'';
startAt = "*-*-* *:00:00"; startAt = "*-*-* *:00:00";
group = "archives"; group = "archives";
encryption.mode = "repokey-blake2"; encryption.mode = "repokey-blake2";
+149
View File
@@ -0,0 +1,149 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
nixservice = "podman-valheim";
service = "valheim";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 2456;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
motd_gs = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = ["podman-valheim"];
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/var/backup/gameservers/valheim";
description = "path to take hourly backups to with borg!";
};
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron/archives/gameservers";
description = "path to rsync offsite backups to";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
virtualisation.oci-containers.containers = {
${service} = {
image = "ghcr.io/community-valheim-tools/valheim-server";
autoStart = true;
extraOptions = [
"--cap-add=sys_nice"
"--stop-timeout=120"
];
ports = [
"2456-2457:2456-2457/udp"
"2456:80/tcp"
];
volumes = [
"${cfg.data_dir}/config:/config"
"${cfg.data_dir}/data:/opt/valheim"
];
environment = {
SERVER_NAME = "recpro";
SERVER_PASS = "recoil727pro";
#WORLD_NAME = "";
STATUS_HTTP = "true";
TZ = homelab.tz;
PUID = toString config.users.users.${service}.uid;
PGID = toString config.users.groups.${service}.gid;
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
networking.firewall.allowedUDPPorts = [2456 2457];
# backups valhiem with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = cfg.data_dir;
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
postHook = ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
'';
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}
-21
View File
@@ -1,21 +0,0 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
# services show up in glance in reverse import order lmao
imports = [
./nfs
./smb
./zfs
./syncthing
./copyparty
./perms
];
# define the groups used for backups and archives
users.groups.archives = {gid = 727;};
}
-59
View File
@@ -1,59 +0,0 @@
{
pkgs,
config,
lib,
...
}:
# define smb shares
let
cfg = config.holocron.smb;
smb_shares = {
archives = {
path = "/holocron/archives";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
timemachine = {
browseable = true;
"path" = "/holocron/archives/timemachine";
#"valid users" = "blake";
"public" = "no";
"writeable" = "yes";
#"force user" = "blake";
"fruit:aapl" = "yes";
"fruit:time machine" = "yes";
"vfs objects" = "catia fruit streams_xattr";
};
users = {
path = "/holocron/users";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0660";
"directory mask" = "0770";
};
media = {
path = "/holocron/media";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
};
in {
options.holocron.smb = {
enable = lib.mkEnableOption "enables smb";
};
config = lib.mkIf cfg.enable {
# enable smb with all shares
services.samba = {
enable = true;
settings = smb_shares;
};
};
}
-78
View File
@@ -1,78 +0,0 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.holocron.zfs;
in {
options.holocron.zfs = {
enable = lib.mkEnableOption "enables zfs";
};
config = lib.mkIf cfg.enable {
# set network host id
networking.hostId = "3e6e7055";
# enable zfs support
boot.kernelModules = ["zfs"];
boot.supportedFilesystems = ["zfs"];
# arc cache size
boot.kernelParams = [ "zfs.zfs_arc_max=12884901888" ];
# pools to import
#boot.zfs.extraPools = [ "holocron" "holocron/archives" "/holocron/media" "/holocron/users" ];
#boot.zfs.extraPools = [ "holocron" ];
# enable smart monitoring
services.smartd = {
enable = true;
autodetect = true;
defaults.monitored = "-a -o on -s (S/../.././05|L/../01/./05)";
notifications.mail = {
enable = true;
sender = "zfs@snowbelle.lan";
};
};
# enable zfs
services.zfs = {
autoScrub.enable = true;
autoScrub.interval = "weekly";
# email notifs
zed = {
enableMail = true;
settings = {
ZED_EMAIL_ADDR = ["root"];
# send notification if scrub succeeds
ZED_NOTIFY_VERBOSE = true;
};
};
};
# install userspace tools for acl's
environment.systemPackages = with pkgs; [smartmontools];
fileSystems."/holocron" = {
device = "holocron";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/archives" = {
device = "holocron/archives";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/users" = {
device = "holocron/users";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/media" = {
device = "holocron/media";
fsType = "zfs";
options = ["nofail"];
};
};
}
+9
View File
@@ -0,0 +1,9 @@
{ pkgs, config, lib, ... }:
{
# the order determines the order in glance :3
imports = [
./ollama
./open-webui
];
}
+98
View File
@@ -0,0 +1,98 @@
{
pkgs,
config,
lib,
...
}: let
service = "ollama";
cfg = config.homelab.${service};
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7710;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "ollama.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# declare the gitea service
services.${service} = {
enable = true;
host = "0.0.0.0";
port = cfg.port;
openFirewall = true;
syncModels = true;
loadModels = [
"deepseek-r1:7b"
"deepseek-r1:14b"
];
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir "/var/lib/private"];
};
};
};
}
+104
View File
@@ -0,0 +1,104 @@
{
pkgs,
config,
lib,
...
}: let
service = "open-webui";
cfg = config.homelab.${service};
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7711;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "ai.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# declare the gitea service
services.${service} = {
enable = true;
host = "0.0.0.0";
port = cfg.port;
openFirewall = true;
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
# add to glance
homelab.glance.links.services = [
{
title = service;
url = "https://ai.${homelab.base_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir "/var/lib/private"];
};
};
};
}
+7 -1
View File
@@ -38,6 +38,10 @@ in {
default = true; default = true;
description = "enable backups for ${service}"; description = "enable backups for ${service}";
}; };
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@@ -82,8 +86,10 @@ in {
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"]; serverAliases = ["${service}.${homelab.public_domain}"];
# use explicitly defined tls cert
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
extraConfig = '' extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
+29
View File
@@ -0,0 +1,29 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.homelab.nomad;
in {
options.homelab.nomad = {
enable = lib.mkEnableOption "enable in house project nomad";
tz = lib.mkOption {
default = "America/Chicago";
type = lib.types.str;
description = "set timezone";
};
};
config = lib.mkIf cfg.enable {
# the order determines the order in glance :3
imports = [
./kiwix
./maps
./kolibri
];
homelab.kiwix.enable = lib.mkDefault true;
homelab.maps.enable = lib.mkDefault true;
homelab.kolibri.enable = lib.mkDefault true;
};
}
+121
View File
@@ -0,0 +1,121 @@
{
pkgs,
config,
lib,
...
}: let
service = "kiwix";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7730;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "kiwix-serve";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {
gid = lib.mkForce cfg.ids;
};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["media"];
};
# helpful and for scripts
environment.systemPackages = with pkgs; [kiwix-tools];
# enable the ${service} service
services.kiwix-serve = {
enable = true;
openFirewall = true;
port = cfg.port;
user = service;
group = service;
libraryPath = "${cfg.data_dir}/library.xml";
extraArgs = {
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
# use explicitly defined tls cert
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance (local service)
homelab.glance.links.nomad = [
{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# sops.secrets = {
# "${service}_" = {
# owner = ;
# group = ;
# };
# };
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}
-89
View File
@@ -1,89 +0,0 @@
{
config,
lib,
pkgs,
...
}:
/*
to restore mysql/marinadb database:
mysql -u root -p -e "DROP DATABASE IF EXISTS <database_name>;" # delete old db if still lingering
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | mysql -u root -p <database_name>
to restore a postgres database:
sudo -u postgres psql -c "DROP DATABASE IF EXISTS <database_name>;" # delete old db if lingering (prolly wont work)
sudo -u postgres psql -c "CREATE DATABASE <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | sudo -u postgres psql -d immich # restore from the dump
*/
let
cfg = config.homelab.backups;
sec = config.sops.secrets;
in {
options.homelab.backups = {
enable = lib.mkEnableOption "enables borg backups for state files and db backup services";
baks = lib.mkOption {
type = lib.types.attrsOf (lib.types.attrsOf (lib.types.listOf lib.types.path));
default = {};
description = "backup jobs, nested attribute sets should be <bak_name> = paths [<list_of_paths>]";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/homelab";
description = "path to take daily backups to with borg!";
};
};
config = lib.mkIf cfg.enable {
# backups homelab with borg
services.borgbackup.jobs.homelab = lib.mkIf (cfg.baks != {}) {
archiveBaseName = "homelab";
repo = cfg.backup_repo;
paths = lib.flatten (lib.attrsets.mapAttrsToList (_: arg: arg.paths) cfg.baks);
compression = "auto,zstd";
startAt = "03:30";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${sec."borg_passwd".path}";
preHook = ''
systemctl start mysql-backup.service
systemctl start $(systemctl list-unit-files 'postgresqlBackup-*.service' --no-legend --no-pager | cut -d' ' -f1)
'';
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# mysql backups currently minecraft_recpro is the only thing using this
services.mysqlBackup = lib.mkIf (config.services.mysql.ensureDatabases != []) {
enable = true;
location = "/var/backup/mysql";
user = "root";
calendar = "daily"; # goes fast, included in back up with server dirs at **:00
compressionAlg = "zstd";
databases = config.services.mysql.ensureDatabases; # set to all databases defined in esure databases
};
# postgresql backups currently immich is the only user
services.postgresqlBackup = lib.mkIf (config.services.postgresql.ensureDatabases != []) {
enable = true;
location = "/var/backup/postgresql";
compression = "zstd"; # optional: "xz", "zstd", "none"
startAt = "daily"; # the dump is included in a backup taken at 4:00
databases = config.services.postgresql.ensureDatabases; # set to all databases defined in esure databases
};
# helpful and for scripts
environment.systemPackages = with pkgs; [borgbackup tree];
sops.secrets = {
"borg_passwd" = {
owner = "root";
group = "root";
};
};
};
}
+24 -52
View File
@@ -1,81 +1,53 @@
{ pkgs, config, lib, ... }:
let
cfg = config.homelab;
in
{ {
pkgs,
config,
lib,
inputs,
...
}: let
cfg = config.homelab;
in {
options.homelab = { options.homelab = {
enable = lib.mkEnableOption "enable homelab services and configuration"; enable = lib.mkEnableOption "enable homelab services and configuration";
media_user = lib.mkOption {
default = "media";
type = lib.types.str;
description = "user for media file permissions";
};
media_group = lib.mkOption {
default = "media";
type = lib.types.str;
description = "group for media file permissions";
};
tz = lib.mkOption { tz = lib.mkOption {
default = "America/Chicago"; default = "America/Chicago";
type = lib.types.str; type = lib.types.str;
description = "set timezone"; description = "set timezone";
}; };
base_domain = lib.mkOption { base_domain = lib.mkOption {
default = "snowbelle.lan"; default = "lumiose.holocron.blue";
type = lib.types.str; type = lib.types.str;
description = "base domain used for reverse proxy"; description = "base domain used for reverse proxy";
}; };
public_domain = lib.mkOption { public_domain = lib.mkOption {
default = "blakedheld.xyz"; default = "holocron.blue";
type = lib.types.str; type = lib.types.str;
description = "base domain used for reverse proxy"; description = "public domain used for reverse proxy";
}; };
host_ip = lib.mkOption { host_ip = lib.mkOption {
default = "10.10.0.10"; default = "10.10.0.11";
type = lib.types.str; type = lib.types.str;
description = "base domain used for reverse proxy"; description = "base ip used for reverse proxy";
}; };
}; };
# the order determines the order in glance :3 # the order determines the order in glance :3
imports = [ imports = [
./motd #./ai
./backups ./mediastack
./glance ./services
./postfix ./system
./caddy #./nomad
./home/zigbee2mqtt ./network
./vaultwarden
./gitea
./home/homeassistant
./immich
./arr/bazarr
./arr/prowlarr
./arr/radarr
./qbittorrent
./arr/sonarr
./yacreader
./audiobookshelf
./jellyfin
./arr/flaresolverr
./home/mosquitto
./uptime-kuma
./tailscale
]; ];
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
users = { # define the groups used for backups and archives
groups.${cfg.media_group} = { users.users.archives = {
gid = 700; isSystemUser = true;
}; group = "archives";
users.${cfg.media_user} = {
uid = 700;
isSystemUser = true;
group = cfg.media_group;
};
}; };
users.groups.archives = {gid = 727;};
}; };
} }
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "audiobookshelf"; service = "audiobookshelf";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,19 +44,18 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
description = "${service} server user"; description = "${service} server user";
uid = lib.mkForce cfg.ids; uid = lib.mkForce cfg.ids;
isSystemUser = true; isSystemUser = true;
# home = cfg.data_dir; # home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
@@ -64,7 +64,7 @@ in
openFirewall = true; openFirewall = true;
user = service; user = service;
group = service; group = service;
# dataDir = cfg.data_dir; # dataDir = cfg.data_dir;
host = "0.0.0.0"; host = "0.0.0.0";
port = cfg.port; port = cfg.port;
}; };
@@ -72,34 +72,32 @@ in
# override umask to make permissions work out # override umask to make permissions work out
systemd.services.${service}.serviceConfig = { systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
# User = service;
# Group = service;
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "abs.${homelab.public_domain}" ]; #serverAliases = ["abs.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} { reverse_proxy 127.0.0.1:${toString cfg.port} {
} }
''; '';
}; };
# add to glance public service # add to glance public service
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://abs.${homelab.public_domain}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://abs.${homelab.base_domain}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "bazarr"; service = "bazarr";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +44,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -55,7 +55,7 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
@@ -72,28 +72,28 @@ in
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
+66
View File
@@ -0,0 +1,66 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.homelab.mediastack;
in {
options.homelab.mediastack = {
enable = lib.mkEnableOption "enable the mediastack";
media_user = lib.mkOption {
default = "media";
type = lib.types.str;
description = "user for media file permissions";
};
media_group = lib.mkOption {
default = "media";
type = lib.types.str;
description = "group for media file permissions";
};
tz = lib.mkOption {
default = "America/Chicago";
type = lib.types.str;
description = "set timezone";
};
};
# the order determines the order in glance :3
imports = [
./yacreader
./bazarr
./qbittorrent
./prowlarr
./lidarr
./radarr
./sonarr
./audiobookshelf
./navidrome
./jellyfin
./flaresolverr
];
config = lib.mkIf cfg.enable {
users = {
groups.${cfg.media_group} = {
gid = 700;
};
users.${cfg.media_user} = {
uid = 700;
isSystemUser = true;
group = cfg.media_group;
};
};
homelab.jellyfin.enable = lib.mkDefault true;
homelab.yacreader.enable = lib.mkDefault true;
homelab.qbittorrent.enable = lib.mkDefault true;
homelab.bazarr.enable = lib.mkDefault true;
homelab.prowlarr.enable = lib.mkDefault true;
homelab.radarr.enable = lib.mkDefault true;
homelab.sonarr.enable = lib.mkDefault true;
homelab.lidarr.enable = lib.mkDefault true;
homelab.audiobookshelf.enable = lib.mkDefault true;
homelab.navidrome.enable = lib.mkDefault true;
homelab.flaresolverr.enable = lib.mkDefault true;
};
}
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "flaresolverr"; service = "flaresolverr";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +44,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -68,13 +68,10 @@ in
Group = service; Group = service;
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "jellyfin"; service = "jellyfin";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in host = config.networking.hostName;
{ in {
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +45,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -55,12 +56,13 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" "video" "render" ]; extraGroups = ["media" "video" "render"];
}; };
# enable the ${service} service # enable the ${service} service
services.${service} = { services.${service} = {
enable = true; enable = true;
package = pkgs.unstable.jellyfin;
openFirewall = true; openFirewall = true;
user = service; user = service;
group = service; group = service;
@@ -72,29 +74,29 @@ in
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "media.${homelab.public_domain}" ]; serverAliases = ["media.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://media.${homelab.public_domain}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://media.${host}.${homelab.public_domain}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -0,0 +1,108 @@
{
pkgs,
config,
lib,
...
}: let
service = "lidarr";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7109;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# required
environment.systemPackages = with pkgs; [ffmpeg_6-headless yt-dlp];
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["media"];
};
# enable the ${service} service
services.${service} = {
enable = true;
openFirewall = true;
user = service;
group = service;
dataDir = cfg.data_dir;
settings = {
server.port = cfg.port;
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = service;
# Group = service;
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.mediastack = [
{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir];};
};
};
}
@@ -0,0 +1,115 @@
{
pkgs,
config,
lib,
...
}: let
service = "navidrome";
cfg = config.homelab.${service};
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7108;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "music.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
# home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["media"];
};
# enable the ${service} service
services.${service} = {
enable = true;
openFirewall = true;
user = service;
group = service;
# plugins = [
# ];
environmentFile = "${cfg.data_dir}/navidrome.env";
settings = {
Address = "0.0.0.0";
Port = cfg.port;
MusicFolder = "/holocron/media/music";
EnableInsightsCollector = false;
LyricsPriority = "nd-lyrics";
Plugins = {
Enabled = true;
#Folder = lib.mkForce "${cfg.data_dir}/plugins";
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
EnvironmentFile = "${cfg.data_dir}/navidrome.env";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
#serverAliases = ["abs.${homelab.public_domain}"];
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} {
}
'';
};
# add to glance public service
homelab.glance.links.mediastack = [
{
title = service;
url = "https://music.${homelab.base_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir];};
};
};
}
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "prowlarr"; service = "prowlarr";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +44,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -55,7 +55,7 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
@@ -74,28 +74,30 @@ in
Group = service; Group = service;
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {
paths = [cfg.data_dir "/var/lib/private"];
};
}; };
}; };
} }
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "qbittorrent"; service = "qbittorrent";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -16,11 +17,11 @@ in
default = 7103; default = 7103;
description = "set port for ${service} (default: ${toString cfg.port}"; description = "set port for ${service} (default: ${toString cfg.port}";
}; };
# torrenting_port = lib.mkOption { # torrenting_port = lib.mkOption {
# type = lib.types.int; # type = lib.types.int;
# default = ; # default = ;
# description = "set port for ${service} (default: ${toString cfg.port}"; # description = "set port for ${service} (default: ${toString cfg.port}";
# }; # };
url = lib.mkOption { url = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "qbit.${homelab.base_domain}"; default = "qbit.${homelab.base_domain}";
@@ -53,11 +54,10 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# ensure media dirs existence # ensure media dirs existence
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /holocron/media/downloads 2775 qbittorrent media -" "d /holocron/media/downloads 2775 qbittorrent media -"
]; ];
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -74,10 +74,10 @@ in
enable = true; enable = true;
openFirewall = true; openFirewall = true;
user = service; user = service;
group = lib.mkForce "media"; # override for permissions group = lib.mkForce "media"; # override for permissions
profileDir = cfg.data_dir; profileDir = cfg.data_dir;
webuiPort = cfg.port; webuiPort = cfg.port;
# torrentingPort = cfg.torrenting_port; # torrentingPort = cfg.torrenting_port;
}; };
# override umask to make permissions work out # override umask to make permissions work out
@@ -102,37 +102,28 @@ in
iptables -A QBIT -j DROP iptables -A QBIT -j DROP
''; '';
# boilerplate for if you ever want to try to get this working again
# ------------------------------------------------------------------------------
# # add systemd service to VPN network namespace
# vpnConfinement = {
# enable = true;
# vpnNamespace = "wgmex";
# };
# ------------------------------------------------------------------------------
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "radarr"; service = "radarr";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,12 +45,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# required # required
environment.systemPackages = with pkgs; [ffmpeg_6-headless]; environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -58,7 +59,7 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
@@ -76,32 +77,32 @@ in
# override umask to make permissions work out # override umask to make permissions work out
systemd.services.${service}.serviceConfig = { systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
# User = service; # User = service;
# Group = service; # Group = service;
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "sonarr"; service = "sonarr";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,12 +44,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# required # required
environment.systemPackages = with pkgs; [ffmpeg_6-headless]; environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -58,7 +58,7 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
@@ -78,28 +78,28 @@ in
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
}; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -1,12 +1,13 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "yacreader"; service = "yacreader";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,12 +44,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# install the binary # install the binary
environment.systemPackages = with pkgs; [ yacreader ]; environment.systemPackages = with pkgs; [yacreader];
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -58,15 +58,15 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" ]; extraGroups = ["media"];
}; };
# enable the ${service} service # enable the ${service} service
systemd.services.${service} = { systemd.services.${service} = {
description = "${service} library server"; description = "${service} library server";
wantedBy = [ "multi-user.target" ]; wantedBy = ["multi-user.target"];
after = [ "network.target" ]; after = ["network.target"];
serviceConfig = { serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
User = service; User = service;
@@ -81,29 +81,31 @@ in
}; };
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ]; networking.firewall.allowedTCPPorts = [cfg.port];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} { reverse_proxy 127.0.0.1:${toString cfg.port} {
} }
''; '';
}; };
# add to glance local service # add to glance local service
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:yac-reader"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:yac-reader";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "caddy"; service = "caddy";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -16,6 +18,11 @@ in
default = "/var/lib/${service}"; default = "/var/lib/${service}";
description = "set data directory for ${service}"; description = "set data directory for ${service}";
}; };
keys = lib.mkOption {
type = lib.types.bool;
default = false;
description = "host keys directory";
};
backup = lib.mkOption { backup = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
@@ -28,7 +35,6 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = {}; users.groups.${service} = {};
@@ -48,16 +54,30 @@ in
user = service; user = service;
group = service; group = service;
dataDir = cfg.data_dir; dataDir = cfg.data_dir;
package = pkgs.caddy.withPlugins {
plugins = [
"github.com/caddy-dns/cloudflare@v0.2.4"
];
hash = "sha256-dQvk6ezY6TQ1J7PjhCXnThF/SqVgPwBO8/RXzHCY+js=";
# Replace with the hash from the build error the first time you build.
};
email = "me@blakedheld.xyz"; email = "me@blakedheld.xyz";
globalConfig = '' globalConfig = ''
auto_https ignore_loaded_certs auto_https ignore_loaded_certs
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
''; '';
virtualHosts."key.${homelab.public_domain}" = { # static page for hosting key files
extraConfig = '' virtualHosts = {
root * /var/www/keys "keys.${homelab.base_domain}" = lib.mkIf cfg.keys {
file_server serverAliases = ["keys.${homelab.public_domain}"];
''; extraConfig = ''
tls internal
root /var/www/keys
file_server browse
'';
};
}; };
}; };
@@ -70,10 +90,13 @@ in
# override umask to make permissions work out # override umask to make permissions work out
systemd.services.${service}.serviceConfig = { systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
# make cloudflare token readable
EnvironmentFile = sec."cloudflare/api_token_caddy".path;
#LoadCredential = "CLOUDFLARE_API_TOKEN:${sec."cloudflare/api_token_caddy".path}";
}; };
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [80 443];
sops.secrets = { sops.secrets = {
"ssl_blakedheld_crt" = { "ssl_blakedheld_crt" = {
@@ -86,17 +109,41 @@ in
group = "caddy"; group = "caddy";
path = "/etc/ssl/blakedheld.xyz.key"; path = "/etc/ssl/blakedheld.xyz.key";
}; };
"cloudflare/api_token_caddy" = {
owner = "caddy";
group = "caddy";
};
"klefki_pub.asc" = { "klefki_pub.asc" = {
owner = "caddy"; owner = "caddy";
group = "caddy"; group = "caddy";
path = "/var/www/keys/klefki_pub.asc"; path = "/var/www/keys/klefki_pub.asc";
}; };
"caddy_root.crt" = {
owner = "caddy";
group = "caddy";
path = "/var/www/keys/caddy_root.crt";
};
}; };
environment.etc."caddy/browse.html".text = ''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>keyring</title>
<style>
footer { display: none !important; }
</style>
</head>
<body>
{{template "listing" .}}
</body>
</html>
'';
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
+64
View File
@@ -0,0 +1,64 @@
{
pkgs,
config,
lib,
...
}: let
service = "cloudflare-ddns";
cfg = config.homelab.ddns;
sec = config.sops.secrets;
in {
options.homelab.ddns = {
enable = lib.mkEnableOption "enables ddns with cloudflare";
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
services.${service} = {
enable = true;
credentialsFile = sec."cloudflare/api_token".path;
domains = [
# recoil.pro
"recoil.pro"
"*.recoil.pro"
"mc.recoil.pro"
"smp.recoil.pro"
"superflat.recoil.pro"
"skyblock.recoil.pro"
"cobblemon.recoil.pro"
"valheim.recoil.pro"
# blakedheld.xyz
#"blakedheld.xyz"
#"*.blakedheld.xyz"
#"git.blakedheld.xyz"
#"up.blakedheld.xyz"
# holocron.blue
#"holocron.blue"
#"*.holocron.blue"
"git.holocron.blue"
"pass.holocron.blue"
"photos.holocron.blue"
"media.holocron.blue"
"up.holocron.blue"
# mc servers
"mine.holocron.blue"
"smp.holocron.blue"
"skyblock.holocron.blue"
"superflat.holocron.blue"
];
};
# declare authkey secrets
sops.secrets = {
"cloudflare/api_token" = {
owner = "cloudflare-ddns";
group = "cloudflare-ddns";
};
};
};
}
+11
View File
@@ -0,0 +1,11 @@
{ pkgs, config, lib, ... }:
{
# the order determines the order in glance :3
imports = [
./dnsmasq
./caddy
./tailscale
./ddns
];
}
@@ -0,0 +1,59 @@
{
pkgs,
config,
lib,
...
}: let
service = "dnsmasq";
cfg = config.homelab.${service};
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
port = lib.mkOption {
type = lib.types.int;
default = 53;
description = "set port for ${service} (default: ${toString cfg.port}";
};
upstream = lib.mkOption {
type = lib.types.str;
default = "10.10.0.1";
description = "set upstream dns server for ${service} (default: $cfg.upstream}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# enable the ${service} service
services.${service} = {
enable = true;
alwaysKeepRunning = true;
settings = {
no-resolv = true;
listen-address = config.homelab.host_ip; # your LAN IP
#interface = "enp89s0";
bind-interfaces = true;
# address = [
# "/snowbelle.blakedheld.xyz/10.10.0.10"
# "/lumiose.blakedheld.xyz/10.10.0.10"
# "/bebe.blakedheld.xyz/10.10.0.1"
# ];
server = [
# upstream dns
cfg.upstream
];
};
};
systemd.services.dnsmasq.serviceConfig = {
RestartSec = "5s";
StartLimitBurst = 10;
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
networking.firewall.allowedUDPPorts = [cfg.port];
};
}
@@ -4,22 +4,31 @@
lib, lib,
... ...
}: let }: let
service = "tailscale";
cfg = config.homelab.tailscale; cfg = config.homelab.tailscale;
authkey_file = config.sops.secrets."tailscale_authkey".path; sec = config.sops.secrets;
in { in {
options.homelab.tailscale = { options.homelab.tailscale = {
enable = lib.mkEnableOption "enables tailscale"; enable = lib.mkEnableOption "enables tailscale";
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "tailscaled";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.tailscale = { services.${service} = {
enable = true; enable = true;
openFirewall = true;
useRoutingFeatures = "both"; useRoutingFeatures = "both";
authKeyFile = authkey_file; authKeyFile = sec."tailscale_authkey".path;
extraUpFlags = [ extraSetFlags = [
"--advertise-routes=${config.homelab.host_ip}/32,10.10.0.1/32,10.10.0.5/32,10.10.0.10/32" # advertise self
"--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit) "--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved "--accept-dns=true" # explicitly allow resolved
]; ];
extraUpFlags = [
];
}; };
# network config # network config
+17
View File
@@ -0,0 +1,17 @@
{
pkgs,
config,
lib,
...
}: {
# the order determines the order in glance :3
imports = [
./home
./glance
./vaultwarden
./gitea
./immich
./homebox
#./searxng
];
}
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "gitea"; service = "gitea";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -48,20 +50,23 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
description = lib.mkForce "${service} server user"; description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids; uid = lib.mkForce cfg.ids;
isSystemUser = true; isSystemUser = true;
shell = pkgs.bash; shell = pkgs.bash;
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = []; extraGroups = [];
# if you wanna attempt system ssh again
#openssh.authorizedKeys.keyFiles = [
# "${cfg.data_dir}/.ssh/authorized_keys"
#];
}; };
# declare the gitea service # declare the gitea service
@@ -70,23 +75,33 @@ in
user = "gitea"; user = "gitea";
group = "gitea"; group = "gitea";
stateDir = cfg.data_dir; stateDir = cfg.data_dir;
appName = "gitea"; appName = "gitea";
settings = { settings = {
server = { server = {
ROOT_URL = "https://git.blakedheld.xyz"; # http config
DOMAIN = "git.blakedheld.xyz"; ROOT_URL = "https://git.${homelab.public_domain}";
DOMAIN = "git.${homelab.public_domain}";
HTTP_PORT = cfg.port; HTTP_PORT = cfg.port;
# local network config
#LOCAL_ROOT_URL = "https://git.snowbelle.lan";
ALLOW_LOCALNETWORKS = true;
ALLOWED_DOMAINS = homelab.host_ip;
SKIP_TLS_VERIFY = true;
# configure for system ssh (trying to use the systms on nix sucks)
SSH_PORT = cfg.ssh_port; SSH_PORT = cfg.ssh_port;
START_SSH_SERVER = true; START_SSH_SERVER = true;
# SSH_PORT = 22;
# START_SSH_SERVER = false;
# SSH_ROOT_PATH = "${cfg.data_dir}/.ssh";
# SSH_CREATE_AUTHORIZED_KEYS_FILE = true;
# actual git config
DEFAULT_BRANCH = "trunk";
ENABLE_PUSH_CREATE_USER = true; ENABLE_PUSH_CREATE_USER = true;
ALLOW_LOCALNETWORKS = true; DEFAULT_PUSH_CREATE_PRIVATE = true;
ALLOWED_DOMAINS = "10.10.0.10";
SKIP_TLS_VERIFY = true;
}; };
}; };
database = { database = {
passwordFile = "${toString config.sops.secrets."gitea_database_password".path}"; passwordFile = "${toString sec."gitea_database_password".path}";
}; };
}; };
@@ -96,25 +111,33 @@ in
}; };
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ]; networking.firewall.allowedTCPPorts = [cfg.port cfg.ssh_port];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."git.${homelab.public_domain}" = {
serverAliases = [ "git.${homelab.public_domain}" ];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} reverse_proxy localhost:${toString cfg.port} {
}
'';
};
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy localhost:${toString cfg.port} { reverse_proxy localhost:${toString cfg.port} {
} }
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.services = [{ homelab.glance.links.services = [
title = service; {
url = "https://git.${homelab.public_domain}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://git.${homelab.public_domain}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# manage secrets with sops # manage secrets with sops
sops.secrets = { sops.secrets = {
@@ -126,7 +149,7 @@ in
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -4,23 +4,21 @@
lib, lib,
... ...
}: }:
/* /*
this is a wrapper module for glance that allows you to this is a wrapper module for glance that allows you to
to pass monitor entries in with nix, all declaratively! to pass monitor entries in with nix, all declaratively!
| <8yy> | | <8yy> |
V V V V
# add to glance # add to glance
homelab.glance.links.mediastack = [{ homelab.glance.links.mediastack = [{
title = service; title = service;
url = "https://${cfg.url}"; url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; icon = "di:${service}";
allow-insecure = true; }]; allow-insecure = true; }];
*/ */
let let
service = "glance"; service = "glance";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
@@ -29,8 +27,7 @@ let
uptimekuma_url = "localhost:7901"; uptimekuma_url = "localhost:7901";
uptimekuma_page = "glance"; uptimekuma_page = "glance";
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -67,24 +64,28 @@ in
links = { links = {
services = lib.mkOption { services = lib.mkOption {
type = lib.types.listOf lib.types.attrs; type = lib.types.listOf lib.types.attrs;
default = [ ]; default = [];
description = "list of links for ${service}"; description = "list of links for ${service}";
}; };
mediastack = lib.mkOption { mediastack = lib.mkOption {
type = lib.types.listOf lib.types.attrs; type = lib.types.listOf lib.types.attrs;
default = [ ]; default = [];
description = "list of links for ${service}"; description = "list of links for ${service}";
}; };
system = lib.mkOption { system = lib.mkOption {
type = lib.types.listOf lib.types.attrs; type = lib.types.listOf lib.types.attrs;
default = [ ]; default = [];
description = "list of links for ${service}";
};
network = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [];
description = "list of links for ${service}"; description = "list of links for ${service}";
}; };
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { users.groups.${service} = {
gid = lib.mkForce cfg.ids; gid = lib.mkForce cfg.ids;
@@ -98,7 +99,7 @@ in
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ ]; extraGroups = [];
}; };
services.${service} = { services.${service} = {
@@ -120,12 +121,13 @@ in
}; };
}; };
branding = { branding = {
#logo-url = "/assets/icons/${config.networking.hostName}.png";
logo-url = "/assets/icons/snowbelle.png"; logo-url = "/assets/icons/snowbelle.png";
favicon-url = "/assets/icons/favicon.ico"; favicon-url = "/assets/icons/favicon.ico";
}; };
pages = [ pages = [
{ {
name = "snowbelle"; name = config.networking.hostName;
hide-desktop-navigation = true; hide-desktop-navigation = true;
columns = [ columns = [
{ {
@@ -140,13 +142,25 @@ in
servers = [ servers = [
{ {
type = "local"; type = "local";
name = "snowbelle"; name = config.networking.hostName;
hide-mountpoints-by-default = true; hide-mountpoints-by-default = true;
mountpoints = { mountpoints = {
"/" = {name = "root"; hide = false;}; "/" = {
"/holocron" = {name = "holocron"; hide = false;}; name = "root";
"/holocron/media" = {name = "media"; hide = false;}; hide = false;
"/holocron/vault" = {name = "vault"; hide = false;}; };
"/holocron" = {
name = "holocron";
hide = false;
};
"/holocron/media" = {
name = "media";
hide = false;
};
"/holocron/vault" = {
name = "vault";
hide = false;
};
}; };
} }
]; ];
@@ -203,17 +217,17 @@ in
{ {
title = "nixos options"; title = "nixos options";
shortcut = "!no"; shortcut = "!no";
url = "https://search.nixos.org/options?channel=25.05&query={QUERY}"; url = "https://search.nixos.org/options?channel=26.05&query={QUERY}";
} }
{ {
title = "nixos packages"; title = "nixos packages";
shortcut = "!np"; shortcut = "!np";
url = "https://search.nixos.org/packages?channel=25.05&query={QUERY}"; url = "https://search.nixos.org/packages?channel=26.05&query={QUERY}";
} }
{ {
title = "home-manager options"; title = "home-manager options";
shortcut = "!hm"; shortcut = "!hm";
url = "https://home-manager-options.extranix.com/?query={QUERY}&release=release-25.05"; url = "https://home-manager-options.extranix.com/?query={QUERY}&release=release-26.05";
} }
]; ];
} }
@@ -235,6 +249,12 @@ in
title = "system"; title = "system";
sites = cfg.links.system; sites = cfg.links.system;
} }
{
type = "monitor";
cache = "1m";
title = "network";
sites = cfg.links.network;
}
{ {
type = "custom-api"; type = "custom-api";
title = "recpro"; title = "recpro";
@@ -242,6 +262,13 @@ in
cache = "5s"; cache = "5s";
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>"; template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
} }
# {
# type = "custom-api";
# title = "linggango";
# url = "https://api.mcstatus.io/v2/status/java/raceraskedforthisenjoyyall.recoil.pro";
# cache = "5s";
# template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
# }
]; ];
} }
{ {
@@ -307,7 +334,7 @@ in
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
# serverAliases = [ "${homelab.public_domain}" ]; # serverAliases = [ "${homelab.public_domain}" ];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
@@ -315,17 +342,88 @@ in
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { ${service} = {
paths = [ cfg.data_dir ]; paths = [cfg.data_dir "/var/lib/private"];
}; };
}; };
# add to vaniville services to glance
homelab.glance.links.services = [
{
title = "vaultwarden";
url = "https://pass.${homelab.public_domain}";
error-url = "https://pass.vaniville.${homelab.public_domain}";
check-url = "https://pass.${homelab.public_domain}";
icon = "di:vaultwarden";
}
{
title = "gitea";
url = "https://git.${homelab.public_domain}";
error-url = "https://git.vaniville.${homelab.public_domain}";
check-url = "https://git.${homelab.public_domain}";
icon = "di:gitea";
}
];
homelab.glance.links.system = [
{
title = "vaniville uptime";
url = "https://up.${homelab.public_domain}";
error-url = "https://up.vaniville.${homelab.public_domain}";
check-url = "https://up.${homelab.public_domain}";
icon = "di:uptime-kuma";
}
];
# add to udr to glance # add to udr to glance
homelab.glance.links.system = [{ homelab.glance.links.network = [
title = "bebe"; {
url = "https://bebe.lan"; title = "shauna";
error-url = "https://10.10.0.1"; url = "https://shauna.holocron.blue";
check-url = "https://10.10.0.1"; error-url = "https://10.0.0.1";
icon = "di:unifi"; check-url = "https://10.0.0.1";
allow-insecure = true; }]; icon = "di:unifi";
allow-insecure = true;
}
{
title = "lifeboat";
url = "https://lifeboat.holocron.blue";
error-url = "https://100.101.11.5";
check-url = "https://100.101.11.5";
icon = "di:unifi";
allow-insecure = true;
}
{
title = "korrina";
url = "https://korrina.holocron.blue";
error-url = "https://100.101.11.1";
check-url = "https://100.101.11.1";
icon = "di:unifi";
allow-insecure = true;
}
{
title = "linode";
url = "https://cloud.linode.com/linodes";
error-url = "https://status.linode.com";
check-url = "https://cloud.linode.com/linodes";
icon = "di:linode";
allow-insecure = true;
}
{
title = "tailscale";
url = "https://console.tailscale.com/admin/machines";
error-url = "https://status.tailscale.com/";
check-url = "https://console.tailscale.com/admin/machines";
icon = "di:tailscale";
allow-insecure = true;
}
{
title = "nextdns";
url = "https://my.nextdns.io";
error-url = "https://test.nextdns.io";
check-url = "https://my.nextdns.io/527db2/setup";
icon = "di:nextdns";
allow-insecure = true;
}
];
}; };
} }
+27
View File
@@ -0,0 +1,27 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.homelab.home;
in {
options.homelab.home = {
enable = lib.mkEnableOption "enable the smarthome stack";
};
# the order determines the order in glance :3
imports = [
./zigbee2mqtt
./mosquitto
./homeassistant
./wyoming
];
config = lib.mkIf cfg.enable {
homelab.hass.enable = lib.mkDefault true;
homelab.mosquitto.enable = lib.mkDefault true;
homelab.zigbee2mqtt.enable = lib.mkDefault true;
homelab.wyoming.enable = lib.mkDefault true;
};
}
@@ -1,13 +1,16 @@
{ pkgs, config, lib, inputs, ... }: {
pkgs,
let config,
lib,
inputs,
...
}: let
nixservice = "home-assistant"; nixservice = "home-assistant";
service = "hass"; service = "hass";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -44,9 +47,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -71,10 +73,6 @@ in
volumes = [ volumes = [
"${cfg.data_dir}:/config" "${cfg.data_dir}:/config"
]; ];
# ports = [
# "0.0.0.0:7704:8123"
# "0.0.0.0:4141:4141"
# ];
environment = { environment = {
TZ = homelab.tz; TZ = homelab.tz;
PUID = toString config.users.users.${service}.uid; PUID = toString config.users.users.${service}.uid;
@@ -89,34 +87,42 @@ in
}; };
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port 8123 ]; networking.firewall.allowedTCPPorts = [cfg.port 8123 21063 21064];
networking.firewall.allowedUDPPorts = [5353];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "${service}.${homelab.public_domain}" ]; serverAliases = ["${service}.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port} {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto https
}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.services = [{ homelab.glance.links.services = [
title = "home assistant"; {
url = "https://hass.${homelab.public_domain}"; title = "home assistant";
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://hass.${homelab.public_domain}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${nixservice}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${nixservice}";
}
];
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
# here lies my tough, and I mean fucking tough, swing at # here lies my tough, and I mean fucking tough, swing at
# getting this to work bare metal, ggs ill see you again # getting this to work bare metal, ggs ill see you again
# - didnt take long # - didnt take long
@@ -158,4 +164,3 @@ in
## }; ## };
# }; # };
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "mosquitto"; service = "mosquitto";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +45,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -65,15 +66,16 @@ in
port = 1883; port = 1883;
address = "0.0.0.0"; address = "0.0.0.0";
users.zigbee = { users.zigbee = {
acl = [ "readwrite #" ]; acl = ["readwrite #"];
hashedPassword = "$7$101$140powz2MtsRawFT$ydndjal9wCAywIWtUEAh/IusdfDFvnHMupTFjdS7Ad/EjsEIbJgHrLY9waCe4Z3142XieuxMrXUDjMTp2qwyiw=="; hashedPassword = "$7$101$140powz2MtsRawFT$ydndjal9wCAywIWtUEAh/IusdfDFvnHMupTFjdS7Ad/EjsEIbJgHrLY9waCe4Z3142XieuxMrXUDjMTp2qwyiw==";
}; };
# use with no auth # use with no auth
# settings.allow_anonymous = true; # settings.allow_anonymous = true;
# acl = [ "pattern readwrite #" ]; # acl = [ "pattern readwrite #" ];
# omitPasswordAuth = true; # omitPasswordAuth = true;
} }
]; ];
# override umask to make permissions work out # override umask to make permissions work out
systemd.services.${service}.serviceConfig = { systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
@@ -82,7 +84,7 @@ in
}; };
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ]; networking.firewall.allowedTCPPorts = [cfg.port];
sops.secrets = { sops.secrets = {
"${service}_hashed_passwd" = { "${service}_hashed_passwd" = {
@@ -93,7 +95,7 @@ in
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -0,0 +1,56 @@
{
pkgs,
config,
lib,
...
}: let
service = "wyoming";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
faster_whisper_port = lib.mkOption {
type = lib.types.int;
default = 7706;
description = "set port for ${service} (default: ${toString cfg.port}";
};
piper_port = lib.mkOption {
type = lib.types.int;
default = 7707;
description = "set port for ${service} (default: ${toString cfg.port}";
};
};
config = lib.mkIf cfg.enable {
# enable the ${service} service
services.${service} = {
faster-whisper = {
servers = {
vanessa = {
enable = true;
language = "en";
uri = "tcp://0.0.0.0:${toString cfg.faster_whisper_port}";
model = "medium";
device = "auto";
};
};
};
piper = {
servers = {
vanessa = {
enable = true;
uri = "tcp://0.0.0.0:${toString cfg.piper_port}";
voice = "en_US-amy-medium";
};
};
};
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.faster_whisper_port cfg.piper_port];
};
}
@@ -1,12 +1,14 @@
{ pkgs, config, lib, ... }: {
pkgs,
let config,
lib,
...
}: let
service = "zigbee2mqtt"; service = "zigbee2mqtt";
cfg = config.homelab.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in in {
{
options.homelab.${service} = { options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
@@ -43,9 +45,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# declare ${service} group # declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; }; users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user # declare ${service} user
users.users.${service} = { users.users.${service} = {
@@ -63,28 +64,29 @@ in
enable = true; enable = true;
dataDir = cfg.data_dir; dataDir = cfg.data_dir;
settings = { settings = {
mqtt = { mqtt = {
base_topic = "zigbee2mqtt"; base_topic = "zigbee2mqtt";
client_id = "zigbee2mqtt"; client_id = "zigbee2mqtt";
server = "mqtt://localhost:1883"; server = "mqtt://localhost:1883";
user = "!/run/secrets/mosquitto_passwd.yaml user"; user = "!/run/secrets/mosquitto_passwd.yaml user";
password = "!/run/secrets/mosquitto_passwd.yaml password"; password = "!/run/secrets/mosquitto_passwd.yaml password";
keepalive = 20; keepalive = 20;
}; };
serial = { serial = {
port = "/dev/serial/by-id/usb-Itead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_V2_4a4e75d63653ef1198d728e0174bec31-if00-port0"; port = "/dev/serial/by-id/usb-Itead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_V2_4a4e75d63653ef1198d728e0174bec31-if00-port0";
adapter = "ember"; adapter = "ember";
}; };
advanced = { advanced = {
channel = 11; channel = 11;
}; };
frontend = { frontend = {
enabled = true; enabled = true;
port = cfg.port; port = cfg.port;
}; };
homeassistant = { homeassistant = {
enabled = true; enabled = true;
}; experimental_event_entities = true;
};
}; };
}; };
@@ -95,25 +97,28 @@ in
Group = service; Group = service;
}; };
# # open firewall # # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ]; networking.firewall.allowedTCPPorts = [cfg.port];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "z2m.${homelab.public_domain}" ]; serverAliases = ["z2m.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
# add to glance # add to glance
homelab.glance.links.services = [{ homelab.glance.links.services = [
title = service; {
url = "https://${cfg.url}"; title = service;
error-url = "http://${homelab.host_ip}:${toString cfg.port}"; url = "https://${cfg.url}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}"; error-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }]; check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
sops.secrets = { sops.secrets = {
"mosquitto_passwd.yaml" = { "mosquitto_passwd.yaml" = {
@@ -124,7 +129,7 @@ in
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; }; ${service} = {paths = [cfg.data_dir];};
}; };
}; };
} }
@@ -2,23 +2,20 @@
pkgs, pkgs,
config, config,
lib, lib,
inputs,
... ...
}: let }: let
service = "copyparty"; service = "homebox";
cfg = config.holocron.${service}; cfg = config.homelab.${service};
sec = config.sops.secrets; sec = config.sops.secrets;
homelab = config.homelab; homelab = config.homelab;
in { in {
imports = [inputs.copyparty.nixosModules.default]; options.homelab.${service} = {
options.holocron.${service} = {
enable = lib.mkEnableOption "enables ${service}"; enable = lib.mkEnableOption "enables ${service}";
# set port options # set port options
port = lib.mkOption { port = lib.mkOption {
type = lib.types.int; type = lib.types.int;
default = 7902; default = 7709;
description = "set port for ${service} (default: ${toString cfg.port}"; description = "set port for ${service} (default: ${toString cfg.port}";
}; };
url = lib.mkOption { url = lib.mkOption {
@@ -41,10 +38,13 @@ in {
default = true; default = true;
description = "enable backups for ${service}"; description = "enable backups for ${service}";
}; };
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
nixpkgs.overlays = [inputs.copyparty.overlays.default];
# declare ${service} group # declare ${service} group
users.groups.${service} = { users.groups.${service} = {
gid = lib.mkForce cfg.ids; gid = lib.mkForce cfg.ids;
@@ -58,7 +58,6 @@ in {
home = cfg.data_dir; home = cfg.data_dir;
createHome = true; createHome = true;
group = service; group = service;
extraGroups = [ "media" "blake" "archives" ];
}; };
# enable the ${service} service # enable the ${service} service
@@ -67,73 +66,39 @@ in {
user = service; user = service;
group = service; group = service;
settings = { settings = {
i = "0.0.0.0"; HBOX_WEB_PORT = toString cfg.port;
p = [7902]; HBOX_STORAGE_CONN_STRING = "file://${cfg.data_dir}";
rproxy = 1; HBOX_STORAGE_PREFIX_PATH = "data";
}; HBOX_DATABASE_DRIVER = "sqlite3";
accounts = { HBOX_DATABASE_SQLITE_PATH = "${cfg.data_dir}/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
blake = { HBOX_OPTIONS_ALLOW_REGISTRATION = "false";
passwordFile = sec."copyparty_passwd".path; HBOX_OPTIONS_GITHUB_RELEASE_CHECK = "false";
}; HBOX_MODE = "production";
}; HOME = cfg.data_dir;
groups = { TMPDIR = "${cfg.data_dir}/tmp";
media = ["blake"];
};
volumes = {
"/archives" = {
path = "/holocron/archives";
access = {
r = "*";
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
#gid = ?;
};
};
"/media" = {
path = "/holocron/media";
access = {
r = "*";
w = "@media";
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
gid = "700";
};
};
"/users/blake" = {
path = "/holocron/users/blake";
access = {
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
gid = "1000";
};
};
}; };
}; };
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
};
# open firewall # open firewall
networking.firewall.allowedTCPPorts = [cfg.port]; networking.firewall.allowedTCPPorts = [cfg.port];
# add to caddy for reverse proxy # add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} { reverse_proxy 127.0.0.1:${toString cfg.port}
}
''; '';
}; };
# add to glance (local service) # add to glance (local service)
homelab.glance.links.system = [ homelab.glance.links.services = [
{ {
title = service; title = service;
url = "https://${cfg.url}"; url = "https://${cfg.url}";
@@ -142,13 +107,14 @@ in {
icon = "di:${service}"; icon = "di:${service}";
} }
]; ];
#---------------------------------------------------------------------------
sops.secrets = { #
"${service}_passwd" = { # sops.secrets = {
owner = service; # "${service}_" = {
group = service; # owner = ;
}; # group = ;
}; # };
# };
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
@@ -44,6 +44,11 @@ in {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = "immich-server"; default = "immich-server";
}; };
library_sync_dir = lib.mkOption {
type = lib.types.str;
default = "/holocron/users/blake/pictures/library";
description = "set directory to automatically rsync library to storage pool";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@@ -65,7 +70,7 @@ in {
services.${service} = { services.${service} = {
enable = true; enable = true;
#package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich; #package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich;
package = unstable_pkgs.x86_64.immich; package = pkgs.unstable.immich;
openFirewall = true; openFirewall = true;
user = service; user = service;
group = service; group = service;
@@ -73,9 +78,33 @@ in {
host = "0.0.0.0"; host = "0.0.0.0";
port = cfg.port; port = cfg.port;
settings = null; settings = null;
#settings.server.externalDomain = "https://photos.blakedheld.xyz";
}; };
# too lazy to add an option, this is on the storage pool now anyway
# systemd.services.immich_library_sync = {
# description = "twice daily sync immich library to holocron";
# serviceConfig = {
# Type = "oneshot";
# User = "root";
# };
#
# script = ''
# ${pkgs.rsync}/bin/rsync -avh --info=progress2 --delete \
# --chown=blake:blake \
# /var/lib/immich/library/blake/ \
# /holocron/users/blake/pictures/library/
# '';
# };
#
# systemd.timers.immich_library_sync = {
# wantedBy = ["timers.target"];
# timerConfig = {
# OnBootSec = "5m";
# OnUnitActiveSec = "12h";
# Persistent = true;
# };
# };
# override umask to make permissions work out # override umask to make permissions work out
# systemd.services."${toString service}-server".serviceConfig = { # systemd.services."${toString service}-server".serviceConfig = {
# UMask = lib.mkForce "0007"; # UMask = lib.mkForce "0007";
@@ -91,7 +120,7 @@ in {
services.caddy.virtualHosts."${cfg.url}" = { services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["photos.${homelab.public_domain}"]; serverAliases = ["photos.${homelab.public_domain}"];
extraConfig = '' extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path} tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} reverse_proxy 127.0.0.1:${toString cfg.port}
''; '';
}; };
@@ -108,13 +137,12 @@ in {
]; ];
# add postgresql database that is automatically created to the backup list # add postgresql database that is automatically created to the backup list
#services.postgresqlBackup.databases = ["immich"]; # set to all databases defined in esure databases
services.postgresql.ensureDatabases = [service]; # set to all databases defined in esure databases services.postgresql.ensureDatabases = [service]; # set to all databases defined in esure databases
# add to backups # add to backups
homelab.backups.baks = { homelab.backups.baks = {
${service} = {paths = [cfg.data_dir "/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];}; ${service} = {paths = ["/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];};
#${service} = {paths = [cfg.data_dir "/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];};
}; };
}; };
} }
@@ -0,0 +1,122 @@
{
pkgs,
config,
lib,
...
}: let
service = "radicale";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7705;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "cal.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {
gid = lib.mkForce cfg.ids;
};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["media"];
};
# enable the ${service} service
services.${service} = {
enable = true;
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = service;
# Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
# use explicitly defined tls cert
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
#---------------------------------------------------------------------------
# # add to glance (public service)
# homelab.glance.links.<category> = [{
# title = service;
# url = "https://${service}.${homelab.public_domain}";
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
# icon = "di:${service}"; }];
#---------------------------------------------------------------------------
# # add to glance (local service)
# homelab.glance.links.<category> = [{
# title = service;
# url = "https://${cfg.url}";
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
# icon = "di:${service}"; }];
#---------------------------------------------------------------------------
#
# sops.secrets = {
# "${service}_" = {
# owner = ;
# group = ;
# };
# };
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}
@@ -0,0 +1,115 @@
{
pkgs,
config,
lib,
...
}: let
service = "searx";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7709;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "search.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# declare the gitea service
services.${service} = {
enable = true;
settings = {
server.port = cfg.port;
server.bind_address = "0.0.0.0";
#server.secret_key = "$SEARX_SECRET_KEY";
engines = [
];
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
# add to glance
homelab.glance.links.services = [
{
title = service;
url = "https://search.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# manage secrets with sops
sops.secrets = {
"${service}_database_password" = {
owner = service;
group = service;
};
};
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir];};
};
};
}
@@ -0,0 +1,116 @@
{
pkgs,
config,
lib,
...
}: let
service = "vaultwarden";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
domain = "https://pass.holocron.blue";
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7701;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "pass.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# enable the vaultwarden service
services.${service} = {
enable = true;
package = pkgs.unstable.vaultwarden;
config = {
DOMAIN = "pass.${homelab.public_domain}";
IP_HEADER = "X-Forwarded-For";
ROCKET_ADDRESS = "0.0.0.0";
ROCKET_PORT = cfg.port;
SIGNUPS_ALLOWED = true;
ADMIN_TOKEN = "$argon2id$v=19$m=19456,t=2,p=1$YXJKa0ZubE9OZkp5c0NlMC95TFhBcFh3K1VsUkk1bElTSFJkbmdYdmp4az0$bsLT8/18BmexUbzqlHp0S4aoIxi6bYxl0IY0EweF5N4";
EXPERIMENTAL_CLIENT_FEATURE_FLAGS = "ssh-key-vault-item";
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {UMask = lib.mkForce "0007";};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["pass.${homelab.public_domain}"];
#tls internal
extraConfig = ''
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.services = [
{
title = service;
url = "https://pass.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
sops.secrets = {
"${service}_admin_token" = {
owner = "${service}";
group = "${service}";
};
};
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir];};
};
};
}
+125
View File
@@ -0,0 +1,125 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
nixservice = "wger";
service = "wger";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7707;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "podman-wger";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# still suss as fuck bro man fuck
virtualisation.oci-containers.containers = {
hass = {
image = "homeassistant/home-assistant:stable";
autoStart = true;
extraOptions = [
"--pull=newer"
"--network=host"
];
volumes = [
"${cfg.data_dir}:/config"
];
environment = {
TZ = homelab.tz;
PUID = toString config.users.users.${service}.uid;
PGID = toString config.users.groups.${service}.gid;
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port 8123 21063 21064];
networking.firewall.allowedUDPPorts = [5353];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port} {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto https
}
'';
};
# add to glance
homelab.glance.links.services = [
{
title = "wger";
url = "https://hass.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${nixservice}";
}
];
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir];};
};
};
}
+141
View File
@@ -0,0 +1,141 @@
{
config,
lib,
pkgs,
...
}:
/*
to restore mysql/marinadb database:
mysql -u root -p -e "DROP DATABASE IF EXISTS <database_name>;" # delete old db if still lingering
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | mysql -u root -p <database_name>
to restore a postgres database:
sudo -u postgres psql -c "DROP DATABASE IF EXISTS <database_name>;" # delete old db if lingering (prolly wont work)
sudo -u postgres psql -c "CREATE DATABASE <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | sudo -u postgres psql -d <database_name> # restore from the dump
*/
let
cfg = config.homelab.backups;
sec = config.sops.secrets;
host = config.networking.hostName;
in {
options.homelab.backups = {
enable = lib.mkEnableOption "enables borg backups for state files and db backup services";
baks = lib.mkOption {
type = lib.types.attrsOf (lib.types.attrsOf (lib.types.listOf lib.types.path));
default = {};
description = "backup jobs, nested attribute sets should be <bak_name> = paths [<list_of_paths>]";
};
databases = lib.mkOption {
type = lib.types.bool;
default = true;
description = "if databases are present, runs dumps";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/servers/${host}/homelab";
description = "path to take daily backups to with borg!";
};
offsite = lib.mkOption {
type = lib.types.bool;
default = true;
description = "bool to control weather or not the repo is backed up offsite";
};
homelab = lib.mkOption {
type = lib.types.bool;
default = false;
description = "bool to control weather or not the repo is backed up to homelab";
};
offsite_user = lib.mkOption {
type = lib.types.str;
default = "lifeboat";
description = "user to connect to offsite host with";
};
offsite_target = lib.mkOption {
type = lib.types.str;
default = "lifeboat.holocron.blue";
description = "ip or domain for offsite backups";
};
offsite_dir = lib.mkOption {
type = lib.types.str;
default = "lifeboat/holocron/archives";
description = "path to rsync offsite backups to";
};
};
config = lib.mkIf cfg.enable {
# backups homelab with borg
services.borgbackup.jobs.homelab = lib.mkIf (cfg.baks != {}) {
archiveBaseName = "homelab";
repo = cfg.backup_repo;
paths = lib.flatten (lib.attrsets.mapAttrsToList (_: arg: arg.paths) cfg.baks);
compression = "auto,zstd";
startAt = "03:30";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${sec."borg_passwd".path}";
preHook = lib.mkIf cfg.databases ''
systemctl start mysql-backup.service
systemctl start $(systemctl list-unit-files 'postgresqlBackup-*.service' --no-legend --no-pager | cut -d' ' -f1)
'';
postHook = lib.mkIf (cfg.offsite || cfg.homelab) ''
${lib.optionalString cfg.offsite ''
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
''}
${lib.optionalString cfg.homelab ''
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
-e "ssh -i /home/blake/.ssh/id_vaniville -o StrictHostKeyChecking=no" \
${toString cfg.backup_repo} \
blake@lumiose:/holocron/archives/servers/vaniville
''}
'';
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# mysql backups currently minecraft_recpro is the only thing using this
services.mysqlBackup = lib.mkIf (config.services.mysql.ensureDatabases != []) {
enable = true;
location = "/var/backup/mysql";
user = "root";
calendar = "daily"; # goes fast, included in back up with server dirs at **:00
compressionAlg = "zstd";
databases = config.services.mysql.ensureDatabases; # set to all databases defined in esure databases
};
# postgresql backups currently immich is the only user
services.postgresqlBackup = lib.mkIf (config.services.postgresql.ensureDatabases != []) {
enable = true;
location = "/var/backup/postgresql";
compression = "zstd"; # optional: "xz", "zstd", "none"
startAt = "daily"; # the dump is included in a backup taken at 4:00
databases = config.services.postgresql.ensureDatabases; # set to all databases defined in esure databases
};
# helpful and for scripts
environment.systemPackages = with pkgs; [borgbackup sshpass tree rsync];
sops.secrets = {
"borg_passwd" = {
owner = "root";
group = "root";
};
"lifeboat_rsync" = {
owner = "root";
group = "archives";
mode = "0440";
};
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{
pkgs,
config,
lib,
...
}: {
# the order determines the order in glance :3
imports = [
./motd
./backups
./uptime-kuma
./msmtp
#./postfix
];
}
@@ -6,11 +6,29 @@
}: let }: let
inherit (lib) mkIf mkOption types filterAttrs mapAttrsToList; inherit (lib) mkIf mkOption types filterAttrs mapAttrsToList;
cfg = config.homelab.motd; cfg = config.homelab.motd;
homelab = lib.attrByPath ["homelab"] {} config;
gameservers = lib.attrByPath ["gameservers"] {} config;
# collect services to display # collect services to display
motd_list = motd_list =
mapAttrsToList (_: v: v.motd) mapAttrsToList (_: v: v.motd)
(filterAttrs (_: v: v ? motd && v.motd != null) config.homelab); (filterAttrs (
_: v:
(v.enable or false)
&& v ? motd
&& v.motd != null
)
homelab);
motd_gs_list = lib.concatLists (
mapAttrsToList (_: v: v.motd_gs)
(filterAttrs (
_: v:
(v.enable or false)
&& v ? motd_gs
&& v.motd_gs != null
)
gameservers)
);
in { in {
options.homelab.motd = { options.homelab.motd = {
enable = mkOption { enable = mkOption {
@@ -75,18 +93,20 @@ in {
motd_list)} motd_list)}
echo echo
${lib.optionalString (motd_gs_list != []) ''
# --- gameservers ---
echo -e "''${headings}gameservers:''${reset}"
${lib.concatStringsSep "\n" (map (service: ''
status=$(systemctl is-active ${service} 2>/dev/null)
# --- gameservers --- if [ "$status" = "active" ]; then
echo -e "''${headings}gameservers:''${reset}" printf "%-32s%s\n" " ''${active}[${service}]''${reset}" "running"
for service in velocity smp superflat bento; do else
status=$(systemctl is-active $service 2>/dev/null) printf "%-32s%s\n" " ''${active}[${service}]''${reset}" "not running"
if [ "$status" = "active" ]; then fi
printf "%-32s%s\n" " ''${active}[$service]''${reset}" "running" '')
else motd_gs_list)}
printf "%-32s%s\n" " ''${active}[$service]''${reset}" "not running" ''}
fi
done
echo
''; '';
environment.etc."motd".mode = "0755"; environment.etc."motd".mode = "0755";

Some files were not shown because too many files have changed in this diff Show More