me like nix
0

Configure Feed

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

1{ 2 pkgs, 3 config, 4 inputs, 5 ... 6}: 7 8let 9 jellyfinKodiSyncQueue = pkgs.fetchzip { 10 url = "https://repo.jellyfin.org/releases/plugin/kodi-sync-queue/kodi-sync-queue_15.0.0.0.zip"; 11 stripRoot = false; 12 hash = "sha256-xtlG3UQ/WClt/Hvxe+oId2CeJ+PWMDXBUJXh5+k+mZQ="; 13 }; 14in 15{ 16 imports = [ 17 # Include the results of the hardware scan. 18 ./hardware-configuration.nix 19 ../common/common.nix 20 ]; 21 22 networking.hostName = "mira"; # Define your hostname. 23 24 # Prevent NetworkManager from managing USB Ethernet 25 networking.networkmanager.unmanaged = [ "interface-name:enp0s20f0u4u3" ]; 26 27 # ZRAM swap to prevent OOM freezes 28 zramSwap = { 29 enable = true; 30 memoryPercent = 50; 31 }; 32 33 # Kill runaway processes before the system locks up 34 services.earlyoom = { 35 enable = true; 36 freeMemThreshold = 5; 37 freeSwapThreshold = 5; 38 enableNotifications = true; 39 }; 40 # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. 41 42 # Configure network proxy if necessary 43 # networking.proxy.default = "http://user:password@proxy:port/"; 44 # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; 45 46 # this is like a network devices discovery thing 47 services.avahi = { 48 enable = true; 49 nssmdns4 = true; 50 openFirewall = true; 51 }; 52 53 services.copyparty.enable = true; 54 55 services.openssh = { 56 enable = true; 57 settings = { 58 PasswordAuthentication = false; 59 KbdInteractiveAuthentication = false; 60 PermitRootLogin = "no"; 61 AllowUsers = [ "sean" ]; 62 }; 63 }; 64 65 users.users.sean.openssh.authorizedKeys.keys = [ 66 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc=" 67 "no-touch-required sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILdilHXHdAP/V8Zq28EzHKtLAMMaFPu4+1det2N50QfhAAAABHNzaDo= sean@framework16" 68 ]; 69 70 # List services that you want to enable: 71 services.flaresolverr.enable = true; 72 nixarr = { 73 enable = true; 74 mediaDir = "/mnt/storage1/nixarr/media"; 75 vpn = { 76 enable = true; 77 wgConf = "/mnt/storage1/nixarr/wireguard.conf"; 78 }; 79 80 jellyfin = { 81 enable = true; 82 openFirewall = true; 83 }; 84 85 transmission = { 86 enable = true; 87 vpn.enable = true; 88 }; 89 sabnzbd = { 90 enable = true; 91 vpn.enable = true; 92 openFirewall = true; 93 }; 94 95 prowlarr.enable = true; 96 radarr.enable = true; 97 sonarr.enable = true; 98 jellyseerr = { 99 enable = true; 100 openFirewall = true; 101 }; 102 103 recyclarr = { 104 enable = true; 105 configuration = { 106 sonarr = { 107 series = { 108 base_url = "http://localhost:8989"; 109 api_key = "!env_var SONARR_API_KEY"; 110 quality_definition = { 111 type = "series"; 112 }; 113 delete_old_custom_formats = true; 114 custom_formats = [ 115 { 116 trash_ids = [ 117 "85c61753df5da1fb2aab6f2a47426b09" # BR-DISK 118 "9c11cd3f07101cdba90a2d81cf0e56b4" # LQ 119 ]; 120 assign_scores_to = [ 121 { 122 name = "WEB-DL (1080p)"; 123 score = -10000; 124 } 125 ]; 126 } 127 ]; 128 }; 129 }; 130 radarr = { 131 movies = { 132 base_url = "http://localhost:7878"; 133 api_key = "!env_var RADARR_API_KEY"; 134 quality_definition = { 135 type = "movie"; 136 }; 137 delete_old_custom_formats = true; 138 custom_formats = [ 139 { 140 trash_ids = [ 141 "570bc9ebecd92723d2d21500f4be314c" # Remaster 142 "eca37840c13c6ef2dd0262b141a5482f" # 4K Remaster 143 ]; 144 assign_scores_to = [ 145 { 146 name = "HD Bluray + WEB"; 147 score = 25; 148 } 149 ]; 150 } 151 ]; 152 }; 153 }; 154 }; 155 }; 156 }; 157 158 # Install Kodi Sync Queue plugin into Jellyfin 159 systemd.services.jellyfin.serviceConfig.ExecStartPre = 160 let 161 pluginDir = "/data/.state/nixarr/jellyfin/data/plugins/Kodi Sync Queue/15.0.0.0"; 162 in 163 pkgs.writeShellScript "install-jellyfin-plugins" '' 164 mkdir -p "${pluginDir}" 165 cp -f ${jellyfinKodiSyncQueue}/*.dll ${jellyfinKodiSyncQueue}/meta.json "${pluginDir}/" 166 ''; 167 168 # MQTT broker for Home Assistant (Tasmota devices, Frigate) 169 services.mosquitto = { 170 enable = true; 171 listeners = [ 172 { 173 acl = [ "pattern readwrite #" ]; 174 omitPasswordAuth = true; 175 settings.allow_anonymous = true; 176 } 177 ]; 178 }; 179 180 # Frigate NVR for camera recording and AI object detection 181 services.frigate = { 182 enable = true; 183 hostname = "frigate"; 184 settings = { 185 mqtt = { 186 enabled = true; 187 host = "localhost"; 188 port = 1883; 189 }; 190 191 detectors = { 192 cpu = { 193 type = "cpu"; 194 num_threads = 4; 195 }; 196 }; 197 198 cameras = { 199 picam = { 200 enabled = true; 201 ffmpeg = { 202 hwaccel_args = "preset-nvidia-h264"; 203 inputs = [ 204 { 205 path = "rtsp://pi:8554/picam"; 206 roles = [ "detect" "record" ]; 207 } 208 ]; 209 }; 210 detect = { 211 enabled = true; 212 width = 1920; 213 height = 1080; 214 fps = 5; 215 }; 216 record = { 217 enabled = true; 218 retain = { 219 days = 7; 220 mode = "active_objects"; 221 }; 222 }; 223 snapshots = { 224 enabled = true; 225 bounding_box = true; 226 retain = { 227 default = 14; 228 }; 229 }; 230 objects = { 231 track = [ "person" "dog" "cat" "car" ]; 232 }; 233 zones = { 234 driveway = { 235 coordinates = "0,0.243,1,0.544,1,1,0,1,0,0.75"; 236 objects = [ "person" "car" "dog" "cat" ]; 237 }; 238 }; 239 }; 240 241 pizerocam = { 242 enabled = true; 243 ffmpeg = { 244 hwaccel_args = "preset-nvidia-h264"; 245 inputs = [ 246 { 247 path = "rtsp://pizero:8554/pizerocam"; 248 roles = [ "record" ]; 249 } 250 ]; 251 }; 252 detect = { 253 enabled = false; 254 }; 255 record = { 256 enabled = true; 257 retain = { 258 days = 2; 259 mode = "all"; 260 }; 261 }; 262 }; 263 }; 264 265 record = { 266 enabled = true; 267 retain = { 268 days = 7; 269 mode = "active_objects"; 270 }; 271 }; 272 }; 273 }; 274 275 # Home Assistant service 276 services.home-assistant = { 277 enable = true; 278 customComponents = with pkgs.home-assistant-custom-components; [ 279 frigate 280 ]; 281 extraComponents = [ 282 "esphome" 283 "met" 284 "radio_browser" 285 "homekit" 286 "homekit_controller" 287 "isal" 288 "mqtt" 289 "tasmota" 290 "wiz" 291 "google_translate" # TTS - was missing gtts module 292 "ecobee" # Was missing pyecobee module 293 "ibeacon" # Was missing ibeacon_ble module 294 "go2rtc" # Camera streaming 295 "generic" # Generic camera integration 296 ]; 297 config = { 298 homeassistant = { 299 time_zone = "America/Toronto"; 300 }; 301 default_config = { }; 302 zeroconf = { }; 303 # MQTT configuration - broker must be set up via UI 304 mqtt = { }; 305 # Automations 306 automation = [ 307 { 308 id = "1761448856909"; 309 alias = "Lower heat at night"; 310 trigger = [ 311 { 312 platform = "time"; 313 at = "23:00:00"; 314 } 315 ]; 316 condition = [ ]; 317 action = [ 318 { 319 action = "climate.set_temperature"; 320 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 321 data = { 322 hvac_mode = "heat"; 323 temperature = 18; 324 }; 325 } 326 ]; 327 mode = "single"; 328 } 329 { 330 id = "1766200000001"; 331 alias = "Raise heat in morning"; 332 trigger = [ 333 { 334 platform = "time"; 335 at = "06:00:00"; 336 } 337 ]; 338 condition = [ ]; 339 action = [ 340 { 341 action = "climate.set_temperature"; 342 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 343 data = { 344 hvac_mode = "heat"; 345 temperature = 21; 346 }; 347 } 348 ]; 349 mode = "single"; 350 } 351 { 352 id = "1766153071796"; 353 alias = "Close Garage Door"; 354 trigger = [ 355 { 356 platform = "device"; 357 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 358 domain = "cover"; 359 entity_id = "cf36763543169888aa106b1acb02ad72"; 360 type = "opened"; 361 for = { 362 hours = 0; 363 minutes = 10; 364 seconds = 0; 365 }; 366 } 367 ]; 368 condition = [ ]; 369 action = [ 370 { 371 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 372 domain = "cover"; 373 entity_id = "cf36763543169888aa106b1acb02ad72"; 374 type = "close"; 375 } 376 ]; 377 mode = "single"; 378 } 379 ]; 380 }; 381 }; 382 383 # Invidious (self-hosted YouTube frontend for Kodi addon) 384 services.invidious = { 385 enable = true; 386 port = 3001; 387 address = "0.0.0.0"; 388 settings = { 389 registration_enabled = false; 390 local = true; 391 invidious_companion = [ 392 { 393 private_url = "http://127.0.0.1:8282/companion"; 394 } 395 ]; 396 invidious_companion_key = "k9x2mP4qR7wL3nYz"; 397 }; 398 }; 399 400 # Invidious Companion (replaces deprecated inv-sig-helper) 401 virtualisation.oci-containers.containers.invidious-companion = { 402 image = "quay.io/invidious/invidious-companion:latest"; 403 ports = [ "127.0.0.1:8282:8282" ]; 404 environment = { 405 SERVER_SECRET_KEY = "k9x2mP4qR7wL3nYz"; 406 }; 407 extraOptions = [ 408 "--read-only" 409 "--cap-drop=ALL" 410 ]; 411 }; 412 413 # Enable the OpenSSH daemon. 414 # services.openssh.enable = true; 415 416 security.pam.loginLimits = [ 417 { 418 domain = "*"; 419 type = "soft"; 420 item = "nofile"; 421 value = "8192"; 422 } 423 ]; 424 425 # trmnl-rs server 426 systemd.services.trmnl-rs = { 427 description = "TRMNL Server"; 428 wantedBy = [ "multi-user.target" ]; 429 wants = [ "network-online.target" ]; 430 after = [ "network-online.target" "nss-lookup.target" ]; 431 serviceConfig = { 432 ExecStart = "${inputs.trmnl-rs.packages.x86_64-linux.default}/bin/server"; 433 Restart = "on-failure"; 434 RestartSec = 5; 435 DynamicUser = true; 436 StateDirectory = "trmnl-rs"; 437 WorkingDirectory = "/var/lib/trmnl-rs"; 438 }; 439 }; 440 441 # Open ports in the firewall. 442 networking.firewall.allowedTCPPorts = [ 443 8096 # jellyfin 444 5055 # jellyseer 445 3000 # vite dev port 446 3001 # Invidious 447 1883 # MQTT for Tasmota devices 448 2300 # trmnl 449 5000 # Frigate web UI 450 8971 # Frigate API 451 config.services.home-assistant.config.http.server_port 452 ]; 453 networking.firewall.allowedUDPPorts = [ 454 ]; 455 # networking.firewall.enable = false; 456 457 # This value determines the NixOS release from which the default 458 # settings for stateful data, like file locations and database versions 459 # on your system were taken. It‘s perfectly fine and recommended to leave 460 # this value at the release version of the first install of this system. 461 # Before changing this value read the documentation for this option 462 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 463 system.stateVersion = "25.05"; # Did you read the comment? 464 465}