diff --git a/hosts/miniserver/configuration.nix b/hosts/miniserver/configuration.nix index 008a3f3..83b9968 100644 --- a/hosts/miniserver/configuration.nix +++ b/hosts/miniserver/configuration.nix @@ -1,5 +1,5 @@ { ... }: { - imports = [ ./hardware-configuration.nix ../../base.nix ]; + imports = [ ./hardware-configuration.nix ../../base.nix ./temp-nginx.nix ]; my = { emacs.enable = true; apps.dictionaries.enable = true; @@ -30,7 +30,7 @@ }; servers = { jellyfin = { - enable = true; + enable = false; enableCron = false; }; nextcloud = { @@ -54,7 +54,7 @@ multi-scrobbler.enable = true; paperless.enable = true; postgres.enable = true; - prowlarr.enable = false; + prowlarr.enable = true; qbittorrent.enable = true; radarr.enable = false; ryot.enable = true; diff --git a/hosts/miniserver/temp-nginx.nix b/hosts/miniserver/temp-nginx.nix new file mode 100644 index 0000000..d7660b5 --- /dev/null +++ b/hosts/miniserver/temp-nginx.nix @@ -0,0 +1,134 @@ +{ config, lib, pkgs, ... }: +let + proxy = locations: { + inherit locations; + forceSSL = true; + enableACME = true; + http2 = true; + }; + proxyReverse = port: + proxy { + "/" = { + proxyPass = "http://192.168.1.69:${toString port}"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect http://192.168.1.69:${ + toString port + }/ https://your_domain.com/; + ''; + }; + }; + proxyReverseArr = port: + proxyReverse port // { + extraConfig = '' + proxy_set_header X-Forwarded-Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + proxy_redirect off; + proxy_http_version 1.1; + ''; + }; +in { + services = { + nginx = { + appendHttpConfig = '' + # JELLYFIN + proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=1d max_size=35000m; + proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=1d use_temp_path=off; + map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; } + map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; } + ''; + virtualHosts = { + "series.${config.my.domain}" = proxyReverse 8989 // { }; + "movies.${config.my.domain}" = proxyReverseArr 7878 // { }; + "music.${config.my.domain}" = proxyReverseArr 8686 // { }; + "subs.${config.my.domain}" = + proxyReverse config.services.bazarr.listenPort // { }; + "library.${config.my.domain}" = proxyReverse config.services.kavita.port + // { }; + "flix.${config.my.domain}" = { + forceSSL = true; + enableACME = true; + http2 = true; + extraConfig = '' + # use a variable to store the upstream proxy + # in this example we are using a hostname which is resolved via DNS + # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address + resolver 192.168.1.69 valid=30; + + location = / { + return 302 http://$host/web/; + #return 302 https://$host/web/; + } + + location = /web/ { + # Proxy main Jellyfin traffic + proxy_pass 192.168.1.69:8096/web/index.html; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + ''; + locations = { + "/" = { + proxyPass = "http://192.168.1.69:8096"; + proxyWebsockets = true; + }; + "/socket" = { + proxyPass = "http://192.168.1.69:8096"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + "~ /Items/(.*)/Images" = { + proxyPass = "http://192.168.1.69:8096"; + extraConfig = '' + proxy_cache jellyfin; + proxy_cache_revalidate on; + proxy_cache_lock on; + ''; + }; + "~* ^/Videos/(.*)/(?!live)" = { + proxyPass = "http://192.168.1.69:8096"; + extraConfig = '' + # Set size of a slice (this amount will be always requested from the backend by nginx) + # Higher value means more latency, lower more overhead + # This size is independent of the size clients/browsers can request + # slice 2m; + + proxy_cache jellyfin-videos; + proxy_cache_valid 200 206 301 302 30d; + proxy_ignore_headers Expires Cache-Control Set-Cookie X-Accel-Expires; + proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; + proxy_connect_timeout 15s; + proxy_http_version 1.1; + proxy_set_header Connection ""; + # Transmit slice range to the backend + proxy_set_header Range 2m; + + # This saves bandwidth between the proxy and jellyfin, as a file is only downloaded one time instead of multiple times when multiple clients want to at the same time + # The first client will trigger the download, the other clients will have to wait until the slice is cached + # Esp. practical during SyncPlay + proxy_cache_lock on; + proxy_cache_lock_age 60s; + + proxy_cache_key "jellyvideo$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level&slicerange=2m"; + + # add_header X-Cache-Status $upstream_cache_status; # This is only for debugging cache + ''; + }; + }; + }; + }; + }; + }; +}