Compare commits

...
2 Commits
Author SHA1 Message Date
Aleksandr BogomiakovandClaude ff4e87aca0 NG: furumi player pinned to the music node
Update Kubernetes Services Wiki / Generate and Update K8s Wiki (push) Successful in 1m19s
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-06 16:18:36 +01:00
Aleksandr BogomiakovandClaude 01561ea2cd NG: furumi database in main PostgreSQL cluster
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-06 16:18:36 +01:00
8 changed files with 234 additions and 0 deletions

No files matched your search

+5
View File
@@ -53,6 +53,11 @@ apps:
namespace: keycloak
wave: 3
skipDryRunOnMissingResource: true # ExternalSecret/Certificate CRDs come from earlier waves
- name: furumi
path: k8s-ng/core/furumi
namespace: furumi
wave: 5 # pinned to the music node; must not hold back the other waves
skipDryRunOnMissingResource: true
- name: secret-stores
path: k8s-ng/core/secret-stores
namespace: external-secrets
+50
View File
@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: furumi-player
labels:
app: furumi-player
spec:
replicas: 1
strategy:
type: Recreate # the library is a hostPath on a single node
selector:
matchLabels:
app: furumi-player
template:
metadata:
labels:
app: furumi-player
annotations:
reloader.stakater.com/auto: "true"
spec:
# The music library lives on this node's /data (LVM raid, not replicated).
nodeSelector:
kubernetes.io/hostname: music
containers:
- name: furumi-player
image: ultradesu/furumusic:latest
imagePullPolicy: Always
env:
- name: FURU_DATABASE_URL
valueFrom:
secretKeyRef:
name: furumi-creds
key: PG_STRING
ports:
- name: http
containerPort: 8000
volumeMounts:
- name: library
mountPath: /media
- name: inbox
mountPath: /inbox
volumes:
- name: library
hostPath:
path: /data/furumi/library
type: Directory
- name: inbox
hostPath:
path: /data/furumi/inbox
type: Directory
+24
View File
@@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: furumi
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
rules:
- host: music.hexor.cy
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: furumi-player
port:
number: 8000
tls:
- secretName: furumi-tls
hosts:
- music.hexor.cy
+8
View File
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- secrets.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
+47
View File
@@ -0,0 +1,47 @@
# Read-only access to the furumi-db Secret in the psql namespace
# (see postgresql/databases/furumi.yaml for the other half).
apiVersion: v1
kind: ServiceAccount
metadata:
name: db-credentials-reader
---
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: psql-credentials
spec:
provider:
kubernetes:
remoteNamespace: psql
server:
caProvider:
type: ConfigMap
name: kube-root-ca.crt
key: ca.crt
auth:
serviceAccount:
name: db-credentials-reader
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: furumi-creds
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: psql-credentials
target:
name: furumi-creds
template:
data:
PG_STRING: "postgresql://{{ .username }}:{{ .password }}@main-rw.psql.svc:5432/furumi"
data:
- secretKey: username
remoteRef:
key: furumi-db
property: username
- secretKey: password
remoteRef:
key: furumi-db
property: password
+16
View File
@@ -0,0 +1,16 @@
---
apiVersion: v1
kind: Service
metadata:
name: furumi-player
labels:
app: furumi-player
spec:
type: ClusterIP
selector:
app: furumi-player
ports:
- name: http
protocol: TCP
port: 8000
targetPort: 8000
@@ -0,0 +1,83 @@
# Database "furumi": password, role, database and read access for the app.
# To add another database copy this file and replace the name.
# Generated once; the role and the application both read this Secret.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: furumi-db
namespace: psql
spec:
refreshPolicy: CreatedOnce
target:
name: furumi-db
template:
type: kubernetes.io/basic-auth
metadata:
labels:
cnpg.io/reload: "true"
data:
username: furumi
password: "{{ .password }}"
dataFrom:
- sourceRef:
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: Password
name: db-password
---
apiVersion: postgresql.cnpg.io/v1
kind: DatabaseRole
metadata:
name: main-furumi
namespace: psql
spec:
cluster:
name: main
name: furumi
login: true
passwordSecret:
name: furumi-db
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: main-furumi
namespace: psql
spec:
cluster:
name: main
name: furumi
owner: furumi
extensions:
- name: pg_trgm
databaseReclaimPolicy: retain
---
# Lets the furumi namespace read only its own credentials Secret.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: furumi-db-reader
namespace: psql
rules:
- apiGroups: [""]
resources: [secrets]
resourceNames: [furumi-db]
verbs: [get, list, watch]
- apiGroups: [authorization.k8s.io]
resources: [selfsubjectrulesreviews]
verbs: [create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: furumi-db-reader
namespace: psql
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: furumi-db-reader
subjects:
- kind: ServiceAccount
name: db-credentials-reader
namespace: furumi
@@ -6,3 +6,4 @@ resources:
- password-generator.yaml
- databases/vaultwarden.yaml
- databases/keycloak.yaml
- databases/furumi.yaml