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 = false; 399 port = 3001; 400 address = "0.0.0.0"; 401 database.port = 5433; 402 settings = { 403 registration_enabled = false; 404 local = true; 405 invidious_companion = [ 406 { 407 private_url = "http://127.0.0.1:8282/companion"; 408 } 409 ]; 410 invidious_companion_key = "k9x2mP4qR7wL3nYz"; 411 }; 412 }; 413 414 # Invidious Companion (replaces deprecated inv-sig-helper) 415 virtualisation.oci-containers.containers.invidious-companion = { 416 image = "quay.io/invidious/invidious-companion:latest"; 417 ports = [ "127.0.0.1:8282:8282" ]; 418 environment = { 419 SERVER_SECRET_KEY = "k9x2mP4qR7wL3nYz"; 420 }; 421 extraOptions = [ 422 "--read-only" 423 "--cap-drop=ALL" 424 ]; 425 }; 426 427 environment.systemPackages = [ 428 pkgs.lm_sensors 429 ]; 430 431 # Enable the OpenSSH daemon. 432 # services.openssh.enable = true; 433 434 security.pam.loginLimits = [ 435 { 436 domain = "*"; 437 type = "soft"; 438 item = "nofile"; 439 value = "8192"; 440 } 441 ]; 442 443 # trmnl-rs server 444 systemd.services.trmnl-rs = { 445 description = "TRMNL Server"; 446 wantedBy = [ "multi-user.target" ]; 447 wants = [ "network-online.target" ]; 448 after = [ 449 "network-online.target" 450 "nss-lookup.target" 451 ]; 452 serviceConfig = { 453 ExecStart = "${inputs.trmnl-rs.packages.x86_64-linux.default}/bin/server"; 454 Restart = "on-failure"; 455 RestartSec = 5; 456 DynamicUser = true; 457 StateDirectory = "trmnl-rs"; 458 WorkingDirectory = "/var/lib/trmnl-rs"; 459 }; 460 }; 461 462 # Open ports in the firewall. 463 networking.firewall.allowedTCPPorts = [ 464 8096 # jellyfin 465 5055 # jellyseer 466 3000 # vite dev port 467 3001 # Invidious 468 1883 # MQTT for Tasmota devices 469 2300 # trmnl 470 5000 # Frigate web UI 471 8971 # Frigate API 472 config.services.home-assistant.config.http.server_port 473 ]; 474 networking.firewall.allowedUDPPorts = [ 475 ]; 476 # networking.firewall.enable = false; 477 478 # This value determines the NixOS release from which the default 479 # settings for stateful data, like file locations and database versions 480 # on your system were taken. It‘s perfectly fine and recommended to leave 481 # this value at the release version of the first install of this system. 482 # Before changing this value read the documentation for this option 483 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 484 system.stateVersion = "25.05"; # Did you read the comment? 485 486}