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 = 2; 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 = [ 207 "detect" 208 "record" 209 ]; 210 } 211 ]; 212 }; 213 detect = { 214 enabled = true; 215 width = 1920; 216 height = 1080; 217 fps = 3; 218 }; 219 record = { 220 enabled = true; 221 retain = { 222 days = 7; 223 mode = "active_objects"; 224 }; 225 }; 226 snapshots = { 227 enabled = true; 228 bounding_box = true; 229 retain = { 230 default = 14; 231 }; 232 }; 233 objects = { 234 track = [ 235 "person" 236 "dog" 237 "cat" 238 "car" 239 ]; 240 }; 241 zones = { 242 driveway = { 243 coordinates = "0,0.243,1,0.544,1,1,0,1,0,0.75"; 244 objects = [ 245 "person" 246 "car" 247 "dog" 248 "cat" 249 ]; 250 }; 251 }; 252 }; 253 254 pizerocam = { 255 enabled = true; 256 ffmpeg = { 257 hwaccel_args = "preset-nvidia-h264"; 258 inputs = [ 259 { 260 path = "rtsp://pizero:8554/pizerocam"; 261 roles = [ "record" ]; 262 } 263 ]; 264 }; 265 detect = { 266 enabled = false; 267 }; 268 record = { 269 enabled = true; 270 retain = { 271 days = 2; 272 mode = "all"; 273 }; 274 }; 275 }; 276 }; 277 278 record = { 279 enabled = true; 280 retain = { 281 days = 7; 282 mode = "active_objects"; 283 }; 284 }; 285 }; 286 }; 287 288 # Home Assistant service 289 services.home-assistant = { 290 enable = true; 291 customComponents = with pkgs.home-assistant-custom-components; [ 292 frigate 293 ]; 294 extraComponents = [ 295 "esphome" 296 "met" 297 "radio_browser" 298 "homekit" 299 "homekit_controller" 300 "isal" 301 "mqtt" 302 "tasmota" 303 "wiz" 304 "google_translate" # TTS - was missing gtts module 305 "ecobee" # Was missing pyecobee module 306 "ibeacon" # Was missing ibeacon_ble module 307 "go2rtc" # Camera streaming 308 "generic" # Generic camera integration 309 ]; 310 config = { 311 homeassistant = { 312 time_zone = "America/Toronto"; 313 }; 314 default_config = { }; 315 zeroconf = { }; 316 # MQTT configuration - broker must be set up via UI 317 mqtt = { }; 318 # Automations 319 automation = [ 320 { 321 id = "1761448856909"; 322 alias = "Lower heat at night"; 323 trigger = [ 324 { 325 platform = "time"; 326 at = "23:00:00"; 327 } 328 ]; 329 condition = [ ]; 330 action = [ 331 { 332 action = "climate.set_temperature"; 333 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 334 data = { 335 hvac_mode = "heat"; 336 temperature = 18; 337 }; 338 } 339 ]; 340 mode = "single"; 341 } 342 { 343 id = "1766200000001"; 344 alias = "Raise heat in morning"; 345 trigger = [ 346 { 347 platform = "time"; 348 at = "06:00:00"; 349 } 350 ]; 351 condition = [ ]; 352 action = [ 353 { 354 action = "climate.set_temperature"; 355 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 356 data = { 357 hvac_mode = "heat"; 358 temperature = 21; 359 }; 360 } 361 ]; 362 mode = "single"; 363 } 364 { 365 id = "1766153071796"; 366 alias = "Close Garage Door"; 367 trigger = [ 368 { 369 platform = "device"; 370 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 371 domain = "cover"; 372 entity_id = "cf36763543169888aa106b1acb02ad72"; 373 type = "opened"; 374 for = { 375 hours = 0; 376 minutes = 10; 377 seconds = 0; 378 }; 379 } 380 ]; 381 condition = [ ]; 382 action = [ 383 { 384 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 385 domain = "cover"; 386 entity_id = "cf36763543169888aa106b1acb02ad72"; 387 type = "close"; 388 } 389 ]; 390 mode = "single"; 391 } 392 ]; 393 }; 394 }; 395 396 # Invidious (self-hosted YouTube frontend for Kodi addon) 397 services.invidious = { 398 enable = true; 399 port = 3001; 400 address = "0.0.0.0"; 401 settings = { 402 registration_enabled = false; 403 local = true; 404 invidious_companion = [ 405 { 406 private_url = "http://127.0.0.1:8282/companion"; 407 } 408 ]; 409 invidious_companion_key = "k9x2mP4qR7wL3nYz"; 410 }; 411 }; 412 413 # Invidious Companion (replaces deprecated inv-sig-helper) 414 virtualisation.oci-containers.containers.invidious-companion = { 415 image = "quay.io/invidious/invidious-companion:latest"; 416 ports = [ "127.0.0.1:8282:8282" ]; 417 environment = { 418 SERVER_SECRET_KEY = "k9x2mP4qR7wL3nYz"; 419 }; 420 extraOptions = [ 421 "--read-only" 422 "--cap-drop=ALL" 423 ]; 424 }; 425 426 environment.systemPackages = [ 427 pkgs.lm_sensors 428 ]; 429 430 # Enable the OpenSSH daemon. 431 # services.openssh.enable = true; 432 433 security.pam.loginLimits = [ 434 { 435 domain = "*"; 436 type = "soft"; 437 item = "nofile"; 438 value = "8192"; 439 } 440 ]; 441 442 # trmnl-rs server 443 systemd.services.trmnl-rs = { 444 description = "TRMNL Server"; 445 wantedBy = [ "multi-user.target" ]; 446 wants = [ "network-online.target" ]; 447 after = [ 448 "network-online.target" 449 "nss-lookup.target" 450 ]; 451 serviceConfig = { 452 ExecStart = "${inputs.trmnl-rs.packages.x86_64-linux.default}/bin/server"; 453 Restart = "on-failure"; 454 RestartSec = 5; 455 DynamicUser = true; 456 StateDirectory = "trmnl-rs"; 457 WorkingDirectory = "/var/lib/trmnl-rs"; 458 }; 459 }; 460 461 # Open ports in the firewall. 462 networking.firewall.allowedTCPPorts = [ 463 8096 # jellyfin 464 5055 # jellyseer 465 3000 # vite dev port 466 3001 # Invidious 467 1883 # MQTT for Tasmota devices 468 2300 # trmnl 469 5000 # Frigate web UI 470 8971 # Frigate API 471 config.services.home-assistant.config.http.server_port 472 ]; 473 networking.firewall.allowedUDPPorts = [ 474 ]; 475 # networking.firewall.enable = false; 476 477 # This value determines the NixOS release from which the default 478 # settings for stateful data, like file locations and database versions 479 # on your system were taken. It‘s perfectly fine and recommended to leave 480 # this value at the release version of the first install of this system. 481 # Before changing this value read the documentation for this option 482 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 483 system.stateVersion = "25.05"; # Did you read the comment? 484 485}