feat(streamystats): add chart (#48778)

**Description**

⚒️ Fixes  #

**⚙️ Type of change**

- [x] ⚙️ Feature/App addition
- [ ] 🪛 Bugfix
- [ ] ⚠️ Breaking change
- [ ] 🔃 Refactor of current code
- [ ] 📜 Documentation Changes

**🧪 How Has This Been Tested?**

Tested on a personal Talos/k8s 1.35.4 cluster, deployed directly with
`helm install`. Both Deployments reach `Ready`, CNPG primary reaches
`Ready`, the `vector` extension is enabled by the job-server's startup
migrations, HTTP probes pass, external HTTPS through nginx-ingress +
cert-manager returns the StreamyStats UI.

**📃 Notes:**

New chart for StreamyStats
(https://github.com/fredrikburmester/streamystats) — watch-history
aggregator for Jellyfin, Emby and Plex.

Two workloads sharing one CNPG cluster:
- `main` — Next.js front-end on port 3000
- `job-server` — sync engine on port 3005 that runs the database
migrations on startup (per upstream v2.18.0 release notes)

Pinned to `appVersion: 2.18.0` with specific digests for both images.

The chart is published as OCI; no test cluster is required to pull
dependencies.

**✔️ Checklist:**

- [x] ⚖️ My code follows the style guidelines of this project
- [x] 👀 I have performed a self-review of my own code
- [x] #️⃣ I have commented my code, particularly in hard-to-understand
areas
- [x] 📄 I have made changes to the documentation
- [x] 🧪 I have added tests to this description that prove my fix is
effective or that my feature works
- [x] ⬆️ I increased versions for any altered app according to semantic
versioning
- [x] I made sure the title starts with `feat(chart-name):`,
`fix(chart-name):`, `chore(chart-name):`, `docs(chart-name):` or
`fix(docs):`

**➕ App addition**

- [x] 🖼️ I have added an icon in the Chart's root directory called
`icon.webp`
---

---------

Signed-off-by: Brioche <niah-niah@hotmail.fr>
Signed-off-by: Alfred Göppel <43101280+alfi0812@users.noreply.github.com>
Co-authored-by: n0PainNoBrioche <22093195+n0PainNoBrioche@users.noreply.github.com>
Co-authored-by: Alfred Göppel <43101280+alfi0812@users.noreply.github.com>
This commit is contained in:
Brioche
2026-06-10 15:13:20 +02:00
committed by GitHub
co-authored by n0PainNoBrioche Alfred Göppel
parent af23595271
commit 1ce64d3567
8 changed files with 183 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
# OWNERS file for Kubernetes
OWNERS
# helm-docs templates
*.gotmpl
# docs folder
/docs
# icon
icon.png
icon.webp
icon-small.webp
+42
View File
@@ -0,0 +1,42 @@
annotations:
artifacthub.io/links: |-
- name: support
url: https://discord.com/invite/tVsPTHWTtr
truecharts.org/train: incubator
trueforge.org/category: media
trueforge.org/max_helm_version: "4.1"
trueforge.org/max_kubernetes_version: 1.35.0
trueforge.org/min_helm_version: "3.14"
trueforge.org/train: incubator
apiVersion: v2
appVersion: 2.18.0
dependencies:
- name: common
version: 29.3.4
repository: oci://oci.trueforge.org/truecharts
condition: ""
alias: ""
tags: []
import-values: []
deprecated: false
description: Streamystats aggregates and visualizes watch history from Jellyfin, Emby and Plex.
home: https://truecharts.org/charts/stable/streamystats
icon: https://truecharts.org/img/hotlink-ok/chart-icons/streamystats.webp
keywords:
- streamystats
- jellyfin
- emby
- plex
- stats
kubeVersion: '>=1.33.0-0'
maintainers:
- name: TrueCharts
email: info@truecharts.org
url: https://truecharts.org
name: streamystats
sources:
- https://github.com/fredrikburmester/streamystats
- https://github.com/trueforge-org/truecharts/tree/master/charts/stable/streamystats
- https://ghcr.io/fredrikburmester/streamystats-nextjs
type: application
version: 0.1.0
+3
View File
@@ -0,0 +1,3 @@
---
title: README
---
Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -0,0 +1 @@
{{- include "tc.v1.common.lib.chart.notes" $ -}}
@@ -0,0 +1 @@
{{ include "tc.v1.common.loader.all" . }}
+104
View File
@@ -0,0 +1,104 @@
# yaml-language-server: $schema=./values.schema.json
image:
repository: ghcr.io/fredrikburmester/streamystats-nextjs
pullPolicy: IfNotPresent
tag: 2.18.0@sha256:2057cfd30ebcc614119eecbfff40fd7d5f19e8411db528eb6f48b222ae077bbf
jobServerImage:
repository: ghcr.io/fredrikburmester/streamystats-job-server
pullPolicy: IfNotPresent
tag: 2.18.0@sha256:669037d3a9726e51bd9a10056badd200becd980b5023f01edb9b3a0007646264
securityContext:
container:
runAsNonRoot: false
runAsUser: 0
runAsGroup: 0
readOnlyRootFilesystem: false
streamystats:
# SESSION_SECRET used to sign session cookies. The chart refuses to start without one. openssl rand -base64 48
sessionSecret: "change-me"
service:
main:
ports:
main:
port: 3000
protocol: http
jobserver:
enabled: true
targetSelector: jobserver
ports:
main:
enabled: true
port: 3005
protocol: http
workload:
main:
enabled: true
type: Deployment
podSpec:
containers:
main:
enabled: true
primary: true
env:
NODE_ENV: production
HOSTNAME: "0.0.0.0"
PORT: "{{ .Values.service.main.ports.main.port }}"
DATABASE_URL: '{{ printf "postgresql://%s:%s@%s:5432/%s" .Values.cnpg.main.user (urlquery .Values.cnpg.main.creds.password) (.Values.cnpg.main.creds.host | trimAll "\"") .Values.cnpg.main.database }}'
JOB_SERVER_URL: "http://{{ printf \"%s-%s\" .Release.Name \"jobserver\" }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.jobserver.ports.main.port }}"
SESSION_SECRET: "{{ .Values.streamystats.sessionSecret }}"
probes:
liveness:
path: /api/health
readiness:
path: /api/health
startup:
path: /api/health
jobserver:
enabled: true
type: Deployment
podSpec:
containers:
jobserver:
enabled: true
primary: true
imageSelector: jobServerImage
env:
NODE_ENV: production
PORT: "{{ .Values.service.jobserver.ports.main.port }}"
HOST: "0.0.0.0"
DATABASE_URL: '{{ printf "postgresql://%s:%s@%s:5432/%s" .Values.cnpg.main.user (urlquery .Values.cnpg.main.creds.password) (.Values.cnpg.main.creds.host | trimAll "\"") .Values.cnpg.main.database }}'
SESSION_SECRET: "{{ .Values.streamystats.sessionSecret }}"
SESSION_POLL_INTERVAL_MS: "5000"
CRON_ACTIVITY_SYNC: "*/1 * * * *"
CRON_RECENT_ITEMS_SYNC: "*/1 * * * *"
CRON_USER_SYNC: "*/1 * * * *"
CRON_PEOPLE_SYNC: "*/15 * * * *"
CRON_EMBEDDINGS_SYNC: "*/15 * * * *"
CRON_GEOLOCATION_SYNC: "*/5 * * * *"
CRON_FINGERPRINT_SYNC: "0 4 * * *"
CRON_JOB_CLEANUP: "*/1 * * * *"
CRON_OLD_JOB_CLEANUP: "0 3 * * *"
CRON_FULL_SYNC: "0 2 * * *"
CRON_DELETED_ITEMS_CLEANUP: "0 * * * *"
SKIP_STARTUP_FULL_SYNC: "false"
probes:
liveness:
port: "{{ .Values.service.jobserver.ports.main.port }}"
path: /health
readiness:
port: "{{ .Values.service.jobserver.ports.main.port }}"
path: /health
startup:
port: "{{ .Values.service.jobserver.ports.main.port }}"
path: /health
cnpg:
main:
enabled: true
user: postgres
database: streamystats