diff --git a/roles/jellyfin/defaults/main.yml b/roles/jellyfin/defaults/main.yml index d87e21e..1682958 100644 --- a/roles/jellyfin/defaults/main.yml +++ b/roles/jellyfin/defaults/main.yml @@ -1,3 +1,7 @@ --- jellyfin_root: /srv/jellyfin +jellyfin_backend: main +jellyfin_nginx_listen_port: "443" +jellyfin_nginx_enabled: true +jellyfin_auth_enabled: false diff --git a/roles/jellyfin/handlers/main.yml b/roles/jellyfin/handlers/main.yml index 6315f35..1bc0e8b 100644 --- a/roles/jellyfin/handlers/main.yml +++ b/roles/jellyfin/handlers/main.yml @@ -4,6 +4,7 @@ service: name: nginx state: reloaded + when: jellyfin_nginx_enabled - name: restart telegraf service: diff --git a/roles/jellyfin/tasks/jellyfin.yml b/roles/jellyfin/tasks/jellyfin.yml index 5dbe70e..7280442 100644 --- a/roles/jellyfin/tasks/jellyfin.yml +++ b/roles/jellyfin/tasks/jellyfin.yml @@ -30,15 +30,17 @@ - name: create dir structure file: - path: "{{ jellyfin_root }}/{{ item }}" + path: "{{ jellyfin_root }}/{{ item.name }}" state: directory - mode: 0750 + mode: "{{ item.mode | default('0750') }}" owner: jellyfin group: jellyfin with_items: - - config - - config/plugins/configurations - - cache + - name: config + - name: config/plugins/configurations + - name: cache + - name: jellyfin-web + mode: "0755" tags: jellyfin-dirs - name: create nginx cache dir @@ -60,6 +62,7 @@ tags: - nginx-config - jellyfin-conf + when: jellyfin_auth_enabled notify: reload nginx - name: template html @@ -72,6 +75,7 @@ with_items: - jellyfin_auth_ok.html - jellyfin_auth_prompt.html + when: jellyfin_auth_enabled tags: - nginx-config - jellyfin-conf @@ -83,14 +87,16 @@ owner: www-data group: www-data mode: 0755 + tags: + - jellyfin-web-config.json - name: start container docker_container: name: jellyfin - image: jellyfin/jellyfin:10.8.7 - auto_remove: no - detach: yes - pull: yes + image: jellyfin/jellyfin:{{ jellyfin_version }} + auto_remove: false + detach: true + pull: true restart_policy: "unless-stopped" state: started user: "{{ systemuserlist.jellyfin.uid }}:{{ grouplist.media.gid }}" @@ -100,7 +106,9 @@ dockerlogs_format: jellyfin ports: - 127.0.0.1:8096:8096 - networks_cli_compatible: no + - 1999:1900/tcp + - 1900:1900/udp + networks_cli_compatible: true networks: - name: bridgewithdns ipv4_address: "{{ bridgewithdns.notflix }}" @@ -120,7 +128,7 @@ # - type: bind # source: "{{ jellyfin_root }}/index.html" # target: /jellyfin/jellyfin-web/index.html - # read_only: yes + # read_only: true env: JELLYFIN_PublishedServerUrl: "{{ jellyfin_url }}" tags: @@ -154,6 +162,8 @@ owner: jellyfin group: jellyfin mode: 0644 + tags: + - jellyfin-log - name: jellyfin nginx dir file: @@ -169,6 +179,7 @@ owner: jellyfin group: jellyfin mode: 0775 + when: jellyfin_auth_enabled changed_when: false - name: template auth stuff @@ -184,6 +195,7 @@ with_items: - users.digest - jellyfin_auth.conf + when: jellyfin_auth_enabled - name: template acl script template: @@ -192,6 +204,7 @@ mode: 0755 owner: www-data group: www-data + when: jellyfin_auth_enabled tags: - jellyfin-auth @@ -199,6 +212,7 @@ template: src: private/jellyfin_auth.service.j2 dest: "/etc/systemd/system/jellyfin_auth.service" + when: jellyfin_auth_enabled tags: - jellyfin-auth @@ -208,6 +222,7 @@ enabled: false daemon_reload: true name: jellyfin_auth + when: jellyfin_auth_enabled - name: template robots.txt template: diff --git a/roles/jellyfin/templates/01-jellyfin.j2 b/roles/jellyfin/templates/01-jellyfin.j2 index f69cb51..ef761a4 100644 --- a/roles/jellyfin/templates/01-jellyfin.j2 +++ b/roles/jellyfin/templates/01-jellyfin.j2 @@ -5,9 +5,9 @@ # map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; } #} server { - listen 443 ssl http2; + listen {{ jellyfin_nginx_listen_port }} ssl http2; {% if inventory_hostname in wg_clients -%} - listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2; + listen {{ wg_clients[inventory_hostname].ip }}:{{ jellyfin_nginx_listen_port }} ssl http2; {% endif -%} include /etc/nginx/sudo-known.conf; @@ -20,7 +20,6 @@ server { # set $jellyfin jellyfin; # resolver 127.0.0.1 valid=30; - # access log is used by python script access_log /var/log/nginx/access_{{ jellyfin_url }}.log main; error_log /var/log/nginx/error_{{ jellyfin_url }}.log warn; @@ -58,20 +57,6 @@ server { proxy_set_header X-Forwarded-Host $http_host; proxy_set_header Accept-Encoding ""; - proxy_hide_header last-modified; - proxy_hide_header cache-control; - proxy_hide_header date; - - etag off; - proxy_hide_header "ETag"; - - if_modified_since off; - expires off; - # this causes nginx to add a second cache-control header - # but with value 'no-cache'. - #expires -1; - add_header Last-Modified $date_gmt always; - add_header Cache-Control 'no-store' always; # Disable buffering when the nginx proxy gets very resource # heavy upon streaming @@ -93,22 +78,40 @@ server { proxy_set_header X-Forwarded-Host $http_host; proxy_set_header Accept-Encoding ""; - proxy_hide_header last-modified; - proxy_hide_header cache-control; - proxy_hide_header date; - etag off; - proxy_hide_header "ETag"; + # ## this was also in the 'location /' block, if i add it back, also add it + # ## back there! (2023-02) + + # proxy_hide_header last-modified; + # proxy_hide_header cache-control; + # proxy_hide_header date; + + # etag off; + # proxy_hide_header "ETag"; + + # if_modified_since off; + # expires off; + # add_header Last-Modified $date_gmt always; + # add_header Cache-Control 'no-store' always; + # add_header Clear-Site-Data "cache" always; + + # # useful until builds/jellyfin-web is in use. + # sub_filter_types application/javascript; + # sub_filter_once off; + # sub_filter 'config.json' 'config.json?id=$request_id'; - if_modified_since off; - expires off; - add_header Last-Modified $date_gmt always; - add_header Cache-Control 'no-store' always; - #add_header Clear-Site-Data "cache" always; } - # location = /web/config.json { - # alias "{{ jellyfin_root }}/jellyfin-web/config.json"; - # } + location = /web/config.json { + # redirect = 302 = temporary + # + # seems to work this way without rewriting the javascript with sub_filter and + # overriding cache entries (providing the client/browser doesnt already have + # the stupid service worker cache already) + if ($is_args = '') { + rewrite "^/web/config.json$" "/web/config.json?id=$request_id" redirect; + } + alias "{{ jellyfin_root }}/jellyfin-web/config.json"; + } location /socket { proxy_pass http://127.0.0.1:{{ jellyfin_port }}; @@ -127,7 +130,9 @@ server { {% for item in ["/health", "/GetUtcTime"] -%} location {{ item }} { allow 127.0.0.1; + {% if inventory_hostname in my_public_ips -%} allow {{ my_public_ips[inventory_hostname] }}/32; + {% endif -%} allow {{ my_public_ips[ansible_control_host] }}/32; allow {{ wireguard_cidr }}; deny all; @@ -187,9 +192,6 @@ server { # ## in addition to “text/html”. # sub_filter_types application/javascript; - # sub_filter_types application/javascript; - # sub_filter_once off; - # sub_filter 'config.json' 'config.json?foo=$date_gmt'; } diff --git a/roles/jellyfin/templates/filebeat-jellyfin.yml.j2 b/roles/jellyfin/templates/filebeat-jellyfin.yml.j2 index e5fa92e..9594d7b 100644 --- a/roles/jellyfin/templates/filebeat-jellyfin.yml.j2 +++ b/roles/jellyfin/templates/filebeat-jellyfin.yml.j2 @@ -16,6 +16,7 @@ fields_under_root: true fields: service.type: jellyfin + jellyfin.backend: {{ jellyfin_backend }} tags: - jellyfin diff --git a/roles/jellyfin/templates/jellyfin-web-config.json.j2 b/roles/jellyfin/templates/jellyfin-web-config.json.j2 index c6e2ef9..c01606d 100644 --- a/roles/jellyfin/templates/jellyfin-web-config.json.j2 +++ b/roles/jellyfin/templates/jellyfin-web-config.json.j2 @@ -50,12 +50,18 @@ "url": "https://status-{{ jellyfin_url }}/" }, { - "name": "Password reset", + "name": "change password", "url": "https://{{ authelia_login_url }}/reset-password/step1" }, { - "name": "TV show calendar", + "name": "tv calendar", "url": "https://pirate.sudo.is/sonarr/feed/calendar/Sonarr.ics" + }, + { + "name": "chatroom: #{{ jellyfin_url.replace('.', ':', 1) }}", + "url": "https://matrix.to/#/#{{ jellyfin_url.replace('.', ':', 1) }}" } + + ] } diff --git a/roles/jellyfin/templates/logging.json.j2 b/roles/jellyfin/templates/logging.json.j2 index 7e2ecfb..d330291 100644 --- a/roles/jellyfin/templates/logging.json.j2 +++ b/roles/jellyfin/templates/logging.json.j2 @@ -1,18 +1,17 @@ { "Serilog": { - // "Using": [ "Serilog.Sinks.Http" ], "MinimumLevel": { "Default": "Information", "Override": { - "Microsoft": "Warning", - "System": "Warning" + "Microsoft": "Information", + "System": "Information" } }, "WriteTo": [ { "Name": "Async", "Args": { - //"bufferSize": 10000000, + {# "bufferSize": 10000000, -#} "configure": [ { "Name": "File", @@ -22,24 +21,11 @@ "retainedFileCountLimit": 3, "rollOnFileSizeLimit": true, "fileSizeLimitBytes": 100000000, - //"outputTemplate": "{\"@timestamp\":\"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}\",\"level\":\"{Level:u3}\",\"thread_id\":\"{ThreadId}\",\"logger_name\":\"{SourceContext}\",\"message\":\"{Message:lj}\",\"exception\":\"{Exception:lj}\"} {NewLine}" - //"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u4}] [{ThreadId}] {SourceContext}: {Message}{NewLine}{Exception}" + {# "outputTemplate": "{\"@timestamp\":\"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}\",\"level\":\"{Level:u3}\",\"thread_id\":\"{ThreadId}\",\"logger_name\":\"{SourceContext}\",\"message\":\"{Message:lj}\",\"exception\":\"{Exception:lj}\"} {NewLine}" -#} + {# "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u4}] [{ThreadId}] {SourceContext}: {Message}{NewLine}{Exception}" -#} "outputTemplate": "[{Level:u4}] - {SourceContext} - {Message}{NewLine}{Exception}" - } - } // , - // { - // "Name": "Http", - // "Args": - // { - // //"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message}{NewLine}{Exception}" - // "outputTemplate": "{\"@timestamp\":\"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}\",\"level\":\"{Level:u3}\",\"thread_id\":\"{ThreadId}\",\"logger_name\":\"{SourceContext}\",\"message\":\"{Message:lj}\",\"exception\":\"{Exception:lj}\"} {NewLine}", - - // "requestUri": "http://{{ logstash_url }}:{{ logstash_http }}", - // "textFormatter": "Serilog.Formatting.Elasticsearch.ElasticsearchJsonFormatter, Serilog.Formatting.Elasticsearch", - // "batchFormatter": "Serilog.Sinks.Http.BatchFormatters.ArrayBatchFormatter, Serilog.Sinks.Http" - // } - // } + } ] } }