Fresh cluster restore
This commit is contained in:
commit
bbba564dad
|
|
@ -0,0 +1,88 @@
|
|||
controller:
|
||||
replicas: 2
|
||||
strategy: RollingUpdate
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- blocky
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
|
||||
config: |
|
||||
upstream:
|
||||
default:
|
||||
- https://1.1.1.1/dns-query
|
||||
- https://8.8.8.8/dns-query
|
||||
|
||||
customDNS:
|
||||
customTTL: 1h
|
||||
mapping:
|
||||
needlestack.boo: 192.168.1.201
|
||||
"*.needlestack.boo": 192.168.1.201
|
||||
|
||||
blocking:
|
||||
denylists:
|
||||
ads:
|
||||
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||
clientGroupsBlock:
|
||||
default:
|
||||
- ads
|
||||
blockType: NXDOMAIN
|
||||
refreshPeriod: 4h
|
||||
|
||||
caching:
|
||||
minTime: 5m
|
||||
maxTime: 30m
|
||||
prefetching: true
|
||||
|
||||
ports:
|
||||
dns: 53
|
||||
http: 4000
|
||||
prometheus:
|
||||
enable: true
|
||||
path: /metrics
|
||||
|
||||
service:
|
||||
# The main service block MUST remain enabled on port 4000 for health checks and metrics
|
||||
main:
|
||||
enabled: true
|
||||
ports:
|
||||
http:
|
||||
port: 4000
|
||||
dns:
|
||||
enabled: true
|
||||
type: LoadBalancer
|
||||
# THE FIX: Allows Node 1 to proxy queries to your replicas on Node 2 & 3
|
||||
externalTrafficPolicy: Cluster
|
||||
annotations: {}
|
||||
ports:
|
||||
dns-udp:
|
||||
enabled: true
|
||||
port: 53
|
||||
protocol: UDP
|
||||
targetPort: 53
|
||||
dns-tcp:
|
||||
enabled: true
|
||||
port: 53
|
||||
protocol: TCP
|
||||
targetPort: 53
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
labels:
|
||||
release: kube-prometheus-stack
|
||||
jobLabel: ""
|
||||
targetLabels: []
|
||||
podTargetLabels: []
|
||||
prometheusRule:
|
||||
enabled: false
|
||||
labels: {}
|
||||
rules: []
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "3"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"bookstack-web","namespace":"bookstack-db"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"bookstack-web"}},"template":{"metadata":{"labels":{"app":"bookstack-web"}},"spec":{"containers":[{"env":[{"name":"PUID","value":"1000"},{"name":"PGID","value":"1000"},{"name":"TZ","value":"Europe/London"},{"name":"APP_URL","value":"https://wiki.needlestack.boo"},{"name":"APP_KEY","value":"base64:Jng4M2tkbXNleXBoYWRmZ2g0NTZqYm5tY3YxMjM0NTY="},{"name":"DB_HOST","value":"10.43.161.65"},{"name":"DB_PORT","value":"3306"},{"name":"DB_USER","value":"bookstack"},{"name":"DB_PASS","value":"Bar07ney!"},{"name":"DB_DATABASE","value":"bookstack"}],"image":"docker.io/linuxserver/bookstack:latest","name":"bookstack","ports":[{"containerPort":80,"name":"http"}],"volumeMounts":[{"mountPath":"/config","name":"bookstack-config"}]}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None","volumes":[{"name":"bookstack-config","persistentVolumeClaim":{"claimName":"bookstack-config-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-12T20:44:04Z"
|
||||
generation: 5
|
||||
name: bookstack-web
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "851484"
|
||||
uid: 714317b1-19be-4e10-ba0d-7fbf23bae864
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: bookstack-web
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "2026-09-12T21:36:57Z"
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: bookstack-web
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
- name: PGID
|
||||
value: "1000"
|
||||
- name: TZ
|
||||
value: Europe/London
|
||||
- name: APP_URL
|
||||
value: https://wiki.needlestack.boo
|
||||
- name: APP_KEY
|
||||
value: base64:Jng4M2tkbXNleXBoYWRmZ2g0NTZqYm5tY3YxMjM0NTY=
|
||||
- name: DB_HOST
|
||||
value: 10.43.161.65
|
||||
- name: DB_PORT
|
||||
value: "3306"
|
||||
- name: DB_USER
|
||||
value: bookstack
|
||||
- name: DB_PASS
|
||||
value: Bar07ney!
|
||||
- name: DB_DATABASE
|
||||
value: bookstack
|
||||
image: docker.io/linuxserver/bookstack:latest
|
||||
imagePullPolicy: Always
|
||||
name: bookstack
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /config
|
||||
name: bookstack-config
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: bookstack-config
|
||||
persistentVolumeClaim:
|
||||
claimName: bookstack-config-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-12T20:44:04Z"
|
||||
lastUpdateTime: "2026-09-12T21:39:25Z"
|
||||
message: ReplicaSet "bookstack-web-74b9c9c799" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
- lastTransitionTime: "2026-09-12T21:40:00Z"
|
||||
lastUpdateTime: "2026-09-12T21:40:00Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
observedGeneration: 5
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"mariadb","namespace":"bookstack-db"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"mariadb"}},"template":{"metadata":{"labels":{"app":"mariadb"}},"spec":{"containers":[{"env":[{"name":"MARIADB_ROOT_PASSWORD","value":"nstBar07ney!"},{"name":"MARIADB_DATABASE","value":"bookstack"},{"name":"MARIADB_USER","value":"bookstack"},{"name":"MARIADB_PASSWORD","value":"Bar07ney!"}],"image":"docker.io/library/mariadb:10.11","name":"mariadb","ports":[{"containerPort":3306,"name":"mysql"}],"volumeMounts":[{"mountPath":"/var/lib/mysql","name":"mariadb-storage"}]}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None","volumes":[{"name":"mariadb-storage","persistentVolumeClaim":{"claimName":"mariadb-data-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
generation: 1
|
||||
name: mariadb
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "834544"
|
||||
uid: 9a81a32b-2079-43ee-8394-643027df3986
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mariadb
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: mariadb
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: MARIADB_ROOT_PASSWORD
|
||||
value: nstBar07ney!
|
||||
- name: MARIADB_DATABASE
|
||||
value: bookstack
|
||||
- name: MARIADB_USER
|
||||
value: bookstack
|
||||
- name: MARIADB_PASSWORD
|
||||
value: Bar07ney!
|
||||
image: docker.io/library/mariadb:10.11
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: mariadb
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/mysql
|
||||
name: mariadb-storage
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: mariadb-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: mariadb-data-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-12T20:40:01Z"
|
||||
lastUpdateTime: "2026-09-12T20:40:01Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
- lastTransitionTime: "2026-09-12T20:39:27Z"
|
||||
lastUpdateTime: "2026-09-12T20:40:01Z"
|
||||
message: ReplicaSet "mariadb-6fcf465cc4" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"bookstack-config-pvc","namespace":"bookstack-db"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-12T20:44:04Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: bookstack-config-pvc
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "835762"
|
||||
uid: b9ed0926-9879-4ddd-885e-0948cd48ce3f
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-b9ed0926-9879-4ddd-885e-0948cd48ce3f
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"mariadb-data-pvc","namespace":"bookstack-db"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: mariadb-data-pvc
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "834328"
|
||||
uid: b87615cd-7e29-4522-995d-4e2cd1144a0a
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-b87615cd-7e29-4522-995d-4e2cd1144a0a
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"bookstack-web-service","namespace":"bookstack-db"},"spec":{"ports":[{"port":80,"targetPort":80}],"selector":{"app":"bookstack-web"}}}
|
||||
creationTimestamp: "2026-09-12T20:44:04Z"
|
||||
name: bookstack-web-service
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "835699"
|
||||
uid: 7df0e394-c2d0-482a-8212-be0a74bf20af
|
||||
spec:
|
||||
clusterIP: 10.43.136.41
|
||||
clusterIPs:
|
||||
- 10.43.136.41
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
selector:
|
||||
app: bookstack-web
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"mariadb-service","namespace":"bookstack-db"},"spec":{"ports":[{"port":3306}],"selector":{"app":"mariadb"}}}
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
name: mariadb-service
|
||||
namespace: bookstack-db
|
||||
resourceVersion: "834266"
|
||||
uid: 3ec5d3ac-c8a8-474a-a21a-2db1ced6c503
|
||||
spec:
|
||||
clusterIP: 10.43.161.65
|
||||
clusterIPs:
|
||||
- 10.43.161.65
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 3306
|
||||
protocol: TCP
|
||||
targetPort: 3306
|
||||
selector:
|
||||
app: mariadb
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: bookstack-local-ingress
|
||||
namespace: bookstack-db
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX how to bridge the internal pod connection protocol
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to mount the generated certificate
|
||||
tls:
|
||||
- secretName: bookstack-tls-secret
|
||||
hosts:
|
||||
- wiki.needlestack.boo
|
||||
rules:
|
||||
- host: wiki.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: bookstack-web-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-12T20:23:24Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
labels:
|
||||
app.kubernetes.io/component: primary
|
||||
app.kubernetes.io/instance: bookstack
|
||||
app.kubernetes.io/name: mariadb
|
||||
app.kubernetes.io/part-of: mariadb
|
||||
name: data-bookstack-mariadb-0
|
||||
namespace: bookstack
|
||||
resourceVersion: "829155"
|
||||
uid: 4faa1a16-2c11-4c8b-9c09-5d271c39ebf2
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-4faa1a16-2c11-4c8b-9c09-5d271c39ebf2
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
phase: Bound
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "4"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"cloudflared","namespace":"cloudflare"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"cloudflared"}},"template":{"metadata":{"labels":{"app":"cloudflared"}},"spec":{"containers":[{"args":["tunnel","--no-autoupdate","run"],"env":[{"name":"TUNNEL_TOKEN","value":"eyJhIjoiZGQzZGM4NzUyNWFlM2VhMjg4MjljY2QzN2IzM2IwNDUiLCJ0IjoiZjVkMzkwMmMtMWIzNS00MDg1LTk1MDctYTIxZGE0Njg0NzkzIiwicyI6Ik1tTmhZems0Tm1NdFkyUmhOQzAwTkdFMExUazFNV010TldRM00yWXhaalV4TlRJeiJ9"}],"image":"cloudflare/cloudflared:latest","name":"cloudflared"}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None"}}}}
|
||||
creationTimestamp: "2026-09-12T15:12:46Z"
|
||||
generation: 4
|
||||
name: cloudflared
|
||||
namespace: cloudflare
|
||||
resourceVersion: "5577092"
|
||||
uid: ded6d529-b685-4829-a7f6-7d16dcbf8598
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 2
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cloudflared
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "2026-09-24T20:27:50Z"
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: cloudflared
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- tunnel
|
||||
- --no-autoupdate
|
||||
- run
|
||||
env:
|
||||
- name: TUNNEL_TOKEN
|
||||
value: eyJhIjoiZGQzZGM4NzUyNWFlM2VhMjg4MjljY2QzN2IzM2IwNDUiLCJ0IjoiZjVkMzkwMmMtMWIzNS00MDg1LTk1MDctYTIxZGE0Njg0NzkzIiwicyI6Ik1tTmhZems0Tm1NdFkyUmhOQzAwTkdFMExUazFNV010TldRM00yWXhaalV4TlRJeiJ9
|
||||
image: cloudflare/cloudflared:latest
|
||||
imagePullPolicy: Always
|
||||
name: cloudflared
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 10.43.0.10
|
||||
searches:
|
||||
- svc.cluster.local
|
||||
- cluster.local
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
status:
|
||||
availableReplicas: 2
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-12T15:18:53Z"
|
||||
lastUpdateTime: "2026-09-12T15:18:53Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
- lastTransitionTime: "2026-09-12T15:12:46Z"
|
||||
lastUpdateTime: "2026-09-24T20:27:55Z"
|
||||
message: ReplicaSet "cloudflared-6b4f8bccfc" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 4
|
||||
readyReplicas: 2
|
||||
replicas: 2
|
||||
updatedReplicas: 2
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cobalt-downloader
|
||||
---
|
||||
# 1. THE BACKEND API (Processing Engine)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cobalt-api
|
||||
namespace: cobalt-downloader
|
||||
labels:
|
||||
app: cobalt-api
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cobalt-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cobalt-api
|
||||
spec:
|
||||
containers:
|
||||
- name: api
|
||||
image: ghcr.io/imputnet/cobalt:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 9000
|
||||
name: http-api
|
||||
env:
|
||||
# Identifies its own public API endpoint location
|
||||
- name: API_URL
|
||||
value: "https://cobalt-api.needlestack.boo"
|
||||
# Grants cross-origin clearance strictly to your web UI subdomain
|
||||
- name: CORS_ALLOWED_ORIGINS
|
||||
value: "https://cobalt.needlestack.boo"
|
||||
resources:
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "512Mi"
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cobalt-api-svc
|
||||
namespace: cobalt-downloader
|
||||
spec:
|
||||
selector:
|
||||
app: cobalt-api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 9000
|
||||
targetPort: 9000
|
||||
---
|
||||
# 2. THE WEB FRONTEND UI (Browser Dashboard)
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cobalt-web
|
||||
namespace: cobalt-downloader
|
||||
labels:
|
||||
app: cobalt-web
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cobalt-web
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cobalt-web
|
||||
spec:
|
||||
containers:
|
||||
- name: web
|
||||
# Swapped to a verified production container path that respects HTTPS parameters
|
||||
image: ghcr.io/notnite/cobalt-web:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http-web
|
||||
env:
|
||||
# This image expects API_URL to pass the backend routing location to browsers
|
||||
- name: API_URL
|
||||
value: "https://cobalt-api.needlestack.boo"
|
||||
resources:
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "512Mi"
|
||||
requests:
|
||||
cpu: "50m"
|
||||
memory: "128Mi"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cobalt-web-svc
|
||||
namespace: cobalt-downloader
|
||||
spec:
|
||||
selector:
|
||||
app: cobalt-web
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
# 3. NGINX INGRESS MAPPING (Dual Host Control)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: cobalt-ingress
|
||||
namespace: cobalt-downloader
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: cobalt-tls-secret
|
||||
hosts:
|
||||
- cobalt.needlestack.boo
|
||||
- cobalt-api.needlestack.boo
|
||||
rules:
|
||||
# Routes your primary browser landing screen traffic
|
||||
- host: cobalt.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: cobalt-web-svc
|
||||
port:
|
||||
number: 80
|
||||
# Routes underlying stream data traffic
|
||||
- host: cobalt-api.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: cobalt-api-svc
|
||||
port:
|
||||
number: 9000
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
controllers:
|
||||
main:
|
||||
type: deployment
|
||||
strategy: Recreate
|
||||
|
||||
containers:
|
||||
main:
|
||||
image:
|
||||
repository: ghcr.io/c4illin/convertx
|
||||
tag: latest
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# RELAX RESOURCE LIMITS TO PREVENT THREAD STALLS
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "6000m" # Allow full core utilization during deep video transcodes
|
||||
memory: 4Gi # Slightly higher ceiling for large video processing blocks
|
||||
|
||||
env:
|
||||
PUID: "1000"
|
||||
PGID: "1000"
|
||||
JWT_SECRET: "d173a64678b199b21c0bc52ef17da56cec31f3eedc3685e68b394b7bc119e38b"
|
||||
HTTP_ALLOWED: "true"
|
||||
ALLOW_UNAUTHENTICATED: "false"
|
||||
# APPLICATION LEVEL CONCURRENCY LIMIT
|
||||
MAX_CONVERT_PROCESS: "1" # Restricts the app to 1 conversion at a time to prevent CPU crowding
|
||||
|
||||
securityContext:
|
||||
privileged: true
|
||||
|
||||
service:
|
||||
main:
|
||||
controller: main
|
||||
type: NodePort
|
||||
ports:
|
||||
http:
|
||||
port: 3050
|
||||
targetPort: 3000
|
||||
nodePort: 32050
|
||||
|
||||
persistence:
|
||||
data:
|
||||
enabled: true
|
||||
type: persistentVolumeClaim
|
||||
storageClass: "longhorn"
|
||||
accessMode: ReadWriteOnce
|
||||
size: 10Gi
|
||||
globalMounts:
|
||||
- path: /app/data
|
||||
igpu:
|
||||
enabled: true
|
||||
type: hostPath
|
||||
hostPath: /dev/dri
|
||||
globalMounts:
|
||||
- path: /dev/dri
|
||||
# values.yaml
|
||||
ingress:
|
||||
main:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Bridges to the unencrypted pod port 3050 safely
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
hosts:
|
||||
- host: convertx.needlestack.boo
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
service:
|
||||
identifier: main
|
||||
port: 3050
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to store the secret
|
||||
tls:
|
||||
- secretName: convertx-tls-secret
|
||||
hosts:
|
||||
- convertx.needlestack.boo
|
||||
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: gitea
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: gitea-postgres-pvc
|
||||
namespace: gitea
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: longhorn
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: gitea-app-pvc
|
||||
namespace: gitea
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
storageClassName: longhorn
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitea-postgres-service
|
||||
namespace: gitea
|
||||
spec:
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
selector:
|
||||
app: gitea-postgres
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitea-service
|
||||
namespace: gitea
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 3000
|
||||
- name: ssh
|
||||
port: 2222
|
||||
targetPort: 2222
|
||||
selector:
|
||||
app: gitea-app
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gitea-postgres
|
||||
namespace: gitea
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea-postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gitea-postgres
|
||||
spec:
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:15-alpine
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
- name: POSTGRES_USER
|
||||
value: gitea_admin
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: NeedlestackCodeVault2026
|
||||
- name: POSTGRES_DB
|
||||
value: giteadb
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: dbport
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/postgresql/data
|
||||
name: db-data
|
||||
volumes:
|
||||
- name: db-data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-postgres-pvc
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gitea-app
|
||||
namespace: gitea
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gitea-app
|
||||
spec:
|
||||
securityContext: # <-- ADD THIS SECTION
|
||||
fsGroup: 1000 # <-- FORCES STORAGE VOLUMES TO BE OWNED BY USER 1000
|
||||
containers:
|
||||
- name: gitea
|
||||
image: gitea/gitea:1.21-rootless
|
||||
env:
|
||||
# Core Database Settings
|
||||
- name: GITEA__database__DB_TYPE
|
||||
value: postgres
|
||||
- name: GITEA__database__HOST
|
||||
value: gitea-postgres-service:5432
|
||||
- name: GITEA__database__NAME
|
||||
value: giteadb
|
||||
- name: GITEA__database__USER
|
||||
value: gitea_admin
|
||||
- name: GITEA__database__PASSWD
|
||||
value: NeedlestackCodeVault2026
|
||||
|
||||
# Rootless Paths Fixes (Maps configuration to persistent /data)
|
||||
- name: GITEA_APP_INI
|
||||
value: /data/gitea/conf/app.ini
|
||||
- name: GITEA_CUSTOM
|
||||
value: /data/gitea
|
||||
- name: GITEA_WORK_DIR
|
||||
value: /data/gitea
|
||||
|
||||
# The Security Fixes (Bypasses installer & disables public sign-ups)
|
||||
- name: GITEA__security__INSTALL_LOCK
|
||||
value: "true"
|
||||
- name: GITEA__service__DISABLE_REGISTRATION
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
- containerPort: 2222
|
||||
name: ssh
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: gitea-data
|
||||
volumes:
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-app-pvc
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gitea-local-ingress
|
||||
namespace: gitea
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: gitea-tls-secret
|
||||
hosts:
|
||||
- git.needlestack.boo
|
||||
rules:
|
||||
- host: git.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: gitea-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gitea-local-ingress
|
||||
namespace: gitea
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port 80
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to mount the generated certificate
|
||||
tls:
|
||||
- secretName: gitea-tls-secret
|
||||
hosts:
|
||||
- git.needlestack.boo
|
||||
rules:
|
||||
- host: git.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: gitea-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,397 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "3"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"gitea-app","namespace":"gitea"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"gitea-app"}},"template":{"metadata":{"labels":{"app":"gitea-app"}},"spec":{"containers":[{"env":[{"name":"GITEA__database__DB_TYPE","value":"postgres"},{"name":"GITEA__database__HOST","value":"gitea-postgres-service:5432"},{"name":"GITEA__database__NAME","value":"giteadb"},{"name":"GITEA__database__USER","value":"gitea_admin"},{"name":"GITEA__database__PASSWD","value":"NeedlestackCodeVault2026"}],"image":"gitea/gitea:1.21-rootless","name":"gitea","ports":[{"containerPort":3000,"name":"http"},{"containerPort":2222,"name":"ssh"}],"volumeMounts":[{"mountPath":"/data","name":"gitea-data"}]}],"volumes":[{"name":"gitea-data","persistentVolumeClaim":{"claimName":"gitea-app-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-21T21:51:38Z"
|
||||
generation: 5
|
||||
name: gitea-app
|
||||
namespace: gitea
|
||||
resourceVersion: "4415267"
|
||||
uid: 46e7fffd-bd04-4e55-a82a-001fb7f459f6
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea-app
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "2026-09-21T22:09:01Z"
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: gitea-app
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: GITEA__database__DB_TYPE
|
||||
value: postgres
|
||||
- name: GITEA__database__HOST
|
||||
value: gitea-postgres-service:5432
|
||||
- name: GITEA__database__NAME
|
||||
value: giteadb
|
||||
- name: GITEA__database__USER
|
||||
value: gitea_admin
|
||||
- name: GITEA__database__PASSWD
|
||||
value: NeedlestackCodeVault2026
|
||||
image: gitea/gitea:1.21-rootless
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: gitea
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2222
|
||||
name: ssh
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: gitea-data
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-app-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-21T21:51:38Z"
|
||||
lastUpdateTime: "2026-09-21T22:11:07Z"
|
||||
message: ReplicaSet "gitea-app-644f4c9577" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
- lastTransitionTime: "2026-09-21T22:11:36Z"
|
||||
lastUpdateTime: "2026-09-21T22:11:36Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
observedGeneration: 5
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "2"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"gitea-postgres","namespace":"gitea"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"gitea-postgres"}},"template":{"metadata":{"labels":{"app":"gitea-postgres"}},"spec":{"containers":[{"env":[{"name":"PGDATA","value":"/var/lib/postgresql/data/pgdata"},{"name":"POSTGRES_USER","value":"gitea_admin"},{"name":"POSTGRES_PASSWORD","value":"NeedlestackCodeVault2026"},{"name":"POSTGRES_DB","value":"giteadb"}],"image":"postgres:15-alpine","name":"postgres","ports":[{"containerPort":5432,"name":"dbport"}],"volumeMounts":[{"mountPath":"/var/lib/postgresql/data","name":"db-data"}]}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None","volumes":[{"name":"db-data","persistentVolumeClaim":{"claimName":"gitea-postgres-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
generation: 2
|
||||
name: gitea-postgres
|
||||
namespace: gitea
|
||||
resourceVersion: "4410146"
|
||||
uid: df85a488-1a17-46f3-ae75-e7911f61d110
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea-postgres
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: gitea-postgres
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
- name: POSTGRES_USER
|
||||
value: gitea_admin
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: NeedlestackCodeVault2026
|
||||
- name: POSTGRES_DB
|
||||
value: giteadb
|
||||
image: postgres:15-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: postgres
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: dbport
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/postgresql/data
|
||||
name: db-data
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: db-data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-postgres-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-21T21:53:43Z"
|
||||
lastUpdateTime: "2026-09-21T21:53:43Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
- lastTransitionTime: "2026-09-21T21:51:14Z"
|
||||
lastUpdateTime: "2026-09-21T21:53:43Z"
|
||||
message: ReplicaSet "gitea-postgres-5d7986b4b8" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 2
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"gitea-app-pvc","namespace":"gitea"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"20Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-21T21:51:38Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: gitea-app-pvc
|
||||
namespace: gitea
|
||||
resourceVersion: "4409403"
|
||||
uid: 509d3566-6a32-47e9-94f9-c9dc66cd00f3
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-509d3566-6a32-47e9-94f9-c9dc66cd00f3
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 20Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"gitea-postgres-pvc","namespace":"gitea"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: gitea-postgres-pvc
|
||||
namespace: gitea
|
||||
resourceVersion: "4409170"
|
||||
uid: 5da54bab-fc4d-4633-80bc-959c00115f46
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-5da54bab-fc4d-4633-80bc-959c00115f46
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gitea-postgres-service","namespace":"gitea"},"spec":{"ports":[{"port":5432,"targetPort":5432}],"selector":{"app":"gitea-postgres"}}}
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
name: gitea-postgres-service
|
||||
namespace: gitea
|
||||
resourceVersion: "4409101"
|
||||
uid: 826733f9-3f03-4289-921b-94f283f9e360
|
||||
spec:
|
||||
clusterIP: 10.43.238.230
|
||||
clusterIPs:
|
||||
- 10.43.238.230
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 5432
|
||||
protocol: TCP
|
||||
targetPort: 5432
|
||||
selector:
|
||||
app: gitea-postgres
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gitea-service","namespace":"gitea"},"spec":{"ports":[{"name":"http","port":80,"targetPort":3000},{"name":"ssh","port":2222,"targetPort":2222}],"selector":{"app":"gitea-app"}}}
|
||||
creationTimestamp: "2026-09-21T21:51:38Z"
|
||||
name: gitea-service
|
||||
namespace: gitea
|
||||
resourceVersion: "4409344"
|
||||
uid: e6ca70bd-1eeb-48e7-b800-6193a15fcb76
|
||||
spec:
|
||||
clusterIP: 10.43.6.10
|
||||
clusterIPs:
|
||||
- 10.43.6.10
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
- name: ssh
|
||||
port: 2222
|
||||
protocol: TCP
|
||||
targetPort: 2222
|
||||
selector:
|
||||
app: gitea-app
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"batch/v1","kind":"CronJob","metadata":{"annotations":{},"name":"cluster-yaml-backup","namespace":"gitea"},"spec":{"concurrencyPolicy":"Forbid","jobTemplate":{"spec":{"template":{"spec":{"containers":[{"command":["/bin/sh","-c","echo \"=== Starting Automated Cluster Backup ===\"\n\n# Configure local git repository tracking parameters\ngit config --global user.name \"Cluster Backup Engine\"\ngit config --global user.email \"backup@needlestack.boo\"\ngit config --global safe.directory '*'\n\n# Constructing authorized credentials paths using the 4-part internal IP\nTARGET_IP=\"10.43.6.10\"\nCLONE_URL=\"http://${GITEA_USER}:${GITEA_TOKEN}@${TARGET_IP}/${GITEA_USER}/${GITEA_REPO}.git\"\nPUSH_URL=\"http://${GITEA_USER}:${GITEA_TOKEN}@${TARGET_IP}/${GITEA_USER}/${GITEA_REPO}.git\"\n\n# Safely download the private repository shell using the injected token keys\ngit clone ${CLONE_URL} /tmp/backup\ncd /tmp/backup\n\n# Refresh backup layout data paths\nrm -rf manifests/\nmkdir -p manifests/\n\n# Extract clean YAML resource records across the namespaces\nfor ns in open-webui homepage mumble adguard; do\n echo \"Backing up namespace: ${ns}\"\n mkdir -p \"manifests/${ns}\"\n kubectl get deployment,pvc,svc,ingress,cronjob,namespace -n ${ns} -o yaml \u003e \"manifests/${ns}/resources.yaml\" 2\u003e/dev/null\ndone\n\n# Sync the layout changes back into the private vault logs\ngit add .\nif ! git diff-index --quiet HEAD --; then\n git commit -m \"Automated backup: $(date +'%Y-%m-%d %H:%M:%S')\"\n git push ${PUSH_URL} main\n echo \"=== Backup Pushed Successfully ===\"\nelse\n echo \"=== No changes detected. Skipping push ===\"\nfi\n"],"env":[{"name":"GITEA_USER","value":"needlestack"},{"name":"GITEA_REPO","value":"cluster-manifests"},{"name":"GITEA_TOKEN","value":"4a403fa7615feea2cbeb0c1f98fcacc48b84d95a"}],"image":"alpine/k8s:1.28.2","name":"backup-worker"}],"restartPolicy":"OnFailure","serviceAccountName":"default"}}}},"schedule":"0 0 * * *"}}
|
||||
creationTimestamp: "2026-09-21T22:38:26Z"
|
||||
generation: 10
|
||||
name: cluster-yaml-backup
|
||||
namespace: gitea
|
||||
resourceVersion: "7914165"
|
||||
uid: 8fde5768-6601-451d-885c-b919d3c9ae00
|
||||
spec:
|
||||
concurrencyPolicy: Forbid
|
||||
failedJobsHistoryLimit: 1
|
||||
jobTemplate:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
echo "=== Starting Automated Cluster Backup ==="
|
||||
|
||||
# Configure local git repository tracking parameters
|
||||
git config --global user.name "Cluster Backup Engine"
|
||||
git config --global user.email "backup@needlestack.boo"
|
||||
git config --global safe.directory '*'
|
||||
|
||||
# Constructing authorized credentials paths using the 4-part internal IP
|
||||
TARGET_IP="10.43.6.10"
|
||||
CLONE_URL="http://${GITEA_USER}:${GITEA_TOKEN}@${TARGET_IP}/${GITEA_USER}/${GITEA_REPO}.git"
|
||||
PUSH_URL="http://${GITEA_USER}:${GITEA_TOKEN}@${TARGET_IP}/${GITEA_USER}/${GITEA_REPO}.git"
|
||||
|
||||
# Safely download the private repository shell using the injected token keys
|
||||
git clone ${CLONE_URL} /tmp/backup
|
||||
cd /tmp/backup
|
||||
|
||||
# Refresh backup layout data paths
|
||||
rm -rf manifests/
|
||||
mkdir -p manifests/
|
||||
|
||||
# Extract clean YAML resource records across the namespaces
|
||||
for ns in open-webui homepage mumble adguard; do
|
||||
echo "Backing up namespace: ${ns}"
|
||||
mkdir -p "manifests/${ns}"
|
||||
kubectl get deployment,pvc,svc,ingress,cronjob,namespace -n ${ns} -o yaml > "manifests/${ns}/resources.yaml" 2>/dev/null
|
||||
done
|
||||
|
||||
# Sync the layout changes back into the private vault logs
|
||||
git add .
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
git commit -m "Automated backup: $(date +'%Y-%m-%d %H:%M:%S')"
|
||||
git push ${PUSH_URL} main
|
||||
echo "=== Backup Pushed Successfully ==="
|
||||
else
|
||||
echo "=== No changes detected. Skipping push ==="
|
||||
fi
|
||||
env:
|
||||
- name: GITEA_USER
|
||||
value: needlestack
|
||||
- name: GITEA_REPO
|
||||
value: cluster-manifests
|
||||
- name: GITEA_TOKEN
|
||||
value: 4a403fa7615feea2cbeb0c1f98fcacc48b84d95a
|
||||
image: alpine/k8s:1.28.2
|
||||
imagePullPolicy: Always
|
||||
name: backup-worker
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: OnFailure
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
serviceAccount: default
|
||||
serviceAccountName: default
|
||||
terminationGracePeriodSeconds: 30
|
||||
schedule: 0 0 * * *
|
||||
successfulJobsHistoryLimit: 3
|
||||
suspend: false
|
||||
status:
|
||||
lastScheduleTime: "2026-09-30T00:00:00Z"
|
||||
lastSuccessfulTime: "2026-09-30T00:00:05Z"
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: homepage
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: homepage-config-pvc
|
||||
namespace: homepage
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
storageClassName: longhorn
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: homepage
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: homepage
|
||||
spec:
|
||||
containers:
|
||||
- name: homepage
|
||||
image: ghcr.io/gethomepage/homepage:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: HOMEPAGE_ALLOWED_HOSTS
|
||||
value: needlestack.boo,localhost:3000
|
||||
volumeMounts:
|
||||
- mountPath: /app/config
|
||||
name: config-volume
|
||||
volumes:
|
||||
- name: config-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: homepage-config-pvc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: homepage-service
|
||||
namespace: homepage
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: homepage
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: homepage-local-ingress
|
||||
namespace: homepage
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port safely
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: homepage-tls-secret
|
||||
hosts:
|
||||
- needlestack.boo
|
||||
rules:
|
||||
- host: needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: homepage-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: homepage-local-ingress
|
||||
namespace: homepage
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX how to bridge the internal pod connection protocol
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to mount the generated certificate
|
||||
tls:
|
||||
- secretName: homepage-tls-secret
|
||||
hosts:
|
||||
- needlestack.boo
|
||||
rules:
|
||||
- host: needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: homepage-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,430 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "3"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"homepage","namespace":"homepage"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"homepage"}},"template":{"metadata":{"labels":{"app":"homepage"}},"spec":{"containers":[{"env":[{"name":"HOMEPAGE_ALLOWED_HOSTS","value":"needlestack.boo,localhost:3000"}],"image":"ghcr.io/gethomepage/homepage:latest","name":"homepage","ports":[{"containerPort":3000,"name":"http"}],"volumeMounts":[{"mountPath":"/app/config","name":"config-volume"}]}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None","volumes":[{"name":"config-volume","persistentVolumeClaim":{"claimName":"homepage-config-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
generation: 9
|
||||
name: homepage
|
||||
namespace: homepage
|
||||
resourceVersion: "3247538"
|
||||
uid: 30d404a3-fcc7-47df-bb80-e1dbb346e606
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: homepage
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/restartedAt: "2026-09-18T22:31:21Z"
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: homepage
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: HOMEPAGE_ALLOWED_HOSTS
|
||||
value: needlestack.boo,localhost:3000
|
||||
image: ghcr.io/gethomepage/homepage:latest
|
||||
imagePullPolicy: Always
|
||||
name: homepage
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /app/config
|
||||
name: config-volume
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: config-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: homepage-config-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-18T22:22:12Z"
|
||||
lastUpdateTime: "2026-09-18T22:37:08Z"
|
||||
message: ReplicaSet "homepage-58584558c7" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
- lastTransitionTime: "2026-09-18T23:14:50Z"
|
||||
lastUpdateTime: "2026-09-18T23:14:50Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
observedGeneration: 9
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"homepage-config-pvc","namespace":"homepage"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: homepage-config-pvc
|
||||
namespace: homepage
|
||||
resourceVersion: "3232764"
|
||||
uid: 2cd12c3c-0f79-46b5-94c6-c61d96a0b57a
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-2cd12c3c-0f79-46b5-94c6-c61d96a0b57a
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 5Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"homepage-service","namespace":"homepage"},"spec":{"ports":[{"port":80,"targetPort":3000}],"selector":{"app":"homepage"}}}
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
name: homepage-service
|
||||
namespace: homepage
|
||||
resourceVersion: "3232702"
|
||||
uid: 6c1eeb77-f148-40eb-be19-e567aaba7743
|
||||
spec:
|
||||
clusterIP: 10.43.18.81
|
||||
clusterIPs:
|
||||
- 10.43.18.81
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: homepage
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T21:33:05Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: adguard
|
||||
name: adguard
|
||||
name: adguard
|
||||
resourceVersion: "41653"
|
||||
uid: 6d812d6a-1921-4169-9805-7d1192073f46
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-12T20:23:24Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack
|
||||
name: bookstack
|
||||
name: bookstack
|
||||
resourceVersion: "829004"
|
||||
uid: e5c59011-b6b6-4f53-a655-a140b7363443
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"bookstack-db"}}
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack-db
|
||||
name: bookstack-db
|
||||
resourceVersion: "834254"
|
||||
uid: 9600ab15-9b1a-451b-af4e-13ff3b672331
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T22:46:31Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
name: cert-manager
|
||||
resourceVersion: "61514"
|
||||
uid: 05b40520-6a11-49af-96df-3d3289a9ed8f
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"cloudflare"}}
|
||||
creationTimestamp: "2026-09-12T15:12:46Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cloudflare
|
||||
name: cloudflare
|
||||
resourceVersion: "737700"
|
||||
uid: f294d89c-0348-444a-b2a8-57303311e45e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: default
|
||||
name: default
|
||||
resourceVersion: "266"
|
||||
uid: ae7a3d3e-3d08-43fe-8e2c-8f72ef066b9e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"gitea"}}
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: gitea
|
||||
name: gitea
|
||||
resourceVersion: "4409092"
|
||||
uid: 6398ba34-919b-4392-afbf-ef0054176a1b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"homepage"}}
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: homepage
|
||||
name: homepage
|
||||
resourceVersion: "3232692"
|
||||
uid: eaafb62a-9a9a-45f3-a7b4-7fa4d1e2ae6b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:46:49Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
resourceVersion: "12923"
|
||||
uid: 46118181-4db6-4c3c-9fdc-f8cc20f28323
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"intel-device-plugin"}}
|
||||
creationTimestamp: "2026-09-17T20:41:41Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: intel-device-plugin
|
||||
name: intel-device-plugin
|
||||
resourceVersion: "2809324"
|
||||
uid: b132d304-80cb-4bdc-88cd-2073a8239312
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-node-lease
|
||||
name: kube-node-lease
|
||||
resourceVersion: "267"
|
||||
uid: 81e945a2-a9f5-4ddc-83a8-2bc214a1559e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-public
|
||||
name: kube-public
|
||||
resourceVersion: "268"
|
||||
uid: 2142a69f-f0bd-45af-8738-563df7f99012
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
name: kube-system
|
||||
resourceVersion: "269"
|
||||
uid: 1b18f0bc-7131-46b4-9e4b-bb0af3d7d63e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:35:47Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: longhorn-system
|
||||
name: longhorn-system
|
||||
name: longhorn-system
|
||||
resourceVersion: "9213"
|
||||
uid: abd04167-9f4b-468e-a637-1649efff2bc7
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"mumble"}}
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: mumble
|
||||
name: mumble
|
||||
resourceVersion: "3560003"
|
||||
uid: cc88370b-9275-43f6-a1f9-2bb663600c48
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"nordvpn"}}
|
||||
creationTimestamp: "2026-09-11T20:23:38Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: nordvpn
|
||||
name: nordvpn
|
||||
resourceVersion: "417127"
|
||||
uid: 15f7c8a5-1b18-475f-84dc-90e5963814fa
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"open-webui"}}
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: open-webui
|
||||
name: open-webui
|
||||
resourceVersion: "2817739"
|
||||
uid: 74bf3bef-51bc-405e-8f79-ebc9f52281c6
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:56:57Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: portainer
|
||||
name: portainer
|
||||
name: portainer
|
||||
resourceVersion: "16301"
|
||||
uid: 17802103-8a9c-4b8f-aa42-03a0db58d2ae
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: immich-local-ingress
|
||||
namespace: immich
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port 2283
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
# THE UPLOAD FIX: Disables NGINX's default 1MB file size boundary block
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
# Optional but highly recommended: Stops NGINX from buffering heavy media uploads to local node drives first
|
||||
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to mount the generated certificate
|
||||
tls:
|
||||
- secretName: immich-tls-secret
|
||||
hosts:
|
||||
- photos.needlestack.boo
|
||||
rules:
|
||||
- host: photos.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: immich-server
|
||||
port:
|
||||
number: 2283
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
controllers:
|
||||
main:
|
||||
containers:
|
||||
main:
|
||||
env:
|
||||
DB_HOSTNAME: "immich-db-rw.immich.svc.cluster.local"
|
||||
DB_DATABASE_NAME: "app"
|
||||
DB_USERNAME: "app"
|
||||
DB_PASSWORD: "OJPYu0ilCbLAu7bqG2ydDbjCdl7DHHKapKoB89aiZ64UJwFnMJZ0t3ZPmtVbjVel"
|
||||
DB_PORT: "5432"
|
||||
REDIS_HOSTNAME: "immich-valkey"
|
||||
IMMICH_MACHINE_LEARNING_URL: "http://immich-machine-learning.immich.svc.cluster.local:2283"
|
||||
securityContext:
|
||||
privileged: true
|
||||
immich:
|
||||
persistence:
|
||||
library:
|
||||
existingClaim: "immich-photo-library-pvc"
|
||||
valkey:
|
||||
enabled: true
|
||||
service:
|
||||
main:
|
||||
type: NodePort
|
||||
ports:
|
||||
http:
|
||||
port: 2283
|
||||
persistence:
|
||||
devdri:
|
||||
enabled: true
|
||||
type: hostPath
|
||||
hostPath: /dev/dri
|
||||
globalMounts:
|
||||
- path: /dev/dri
|
||||
ingress:
|
||||
main:
|
||||
enabled: false
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# monitoring-values.yaml
|
||||
|
||||
prometheus:
|
||||
prometheusSpec:
|
||||
# Forces Prometheus to find ServiceMonitors cluster-wide (like blocky in kube-system)
|
||||
serviceMonitorSelectorNilUsesHelmValues: false
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port safely
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
hosts:
|
||||
- prometheus.needlestack.boo
|
||||
paths:
|
||||
- /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: prometheus-tls-secret
|
||||
hosts:
|
||||
- prometheus.needlestack.boo
|
||||
|
||||
grafana:
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port safely
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
hosts:
|
||||
- grafana.needlestack.boo
|
||||
# THE SCHEMA FIX: Wrapped as an explicit array object to match the chart constraints
|
||||
paths:
|
||||
- /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: grafana-tls-secret
|
||||
hosts:
|
||||
- grafana.needlestack.boo
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"mumble","namespace":"mumble"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"mumble"}},"template":{"metadata":{"labels":{"app":"mumble"}},"spec":{"containers":[{"image":"mumblevoip/mumble-server:latest","name":"murmur","ports":[{"containerPort":64738,"name":"mumble-tcp","protocol":"TCP"},{"containerPort":64738,"name":"mumble-udp","protocol":"UDP"}],"volumeMounts":[{"mountPath":"/data","name":"mumble-storage"}]}],"volumes":[{"name":"mumble-storage","persistentVolumeClaim":{"claimName":"mumble-data-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
generation: 1
|
||||
name: mumble
|
||||
namespace: mumble
|
||||
resourceVersion: "3560270"
|
||||
uid: 04f642f1-3525-4db7-88fe-4b09259c6264
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mumble
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: mumble
|
||||
spec:
|
||||
containers:
|
||||
- image: mumblevoip/mumble-server:latest
|
||||
imagePullPolicy: Always
|
||||
name: murmur
|
||||
ports:
|
||||
- containerPort: 64738
|
||||
name: mumble-tcp
|
||||
protocol: TCP
|
||||
- containerPort: 64738
|
||||
name: mumble-udp
|
||||
protocol: UDP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: mumble-storage
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: mumble-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: mumble-data-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-19T18:15:06Z"
|
||||
lastUpdateTime: "2026-09-19T18:15:06Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
- lastTransitionTime: "2026-09-19T18:14:35Z"
|
||||
lastUpdateTime: "2026-09-19T18:15:06Z"
|
||||
message: ReplicaSet "mumble-757c5c899d" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"mumble-data-pvc","namespace":"mumble"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"2Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: mumble-data-pvc
|
||||
namespace: mumble
|
||||
resourceVersion: "3560074"
|
||||
uid: 85fb334b-6399-4887-917c-09e703d2a0d5
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-85fb334b-6399-4887-917c-09e703d2a0d5
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 2Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"mumble-service","namespace":"mumble"},"spec":{"ports":[{"name":"mumble-tcp","nodePort":31738,"port":64738,"protocol":"TCP","targetPort":64738},{"name":"mumble-udp","nodePort":31738,"port":64738,"protocol":"UDP","targetPort":64738}],"selector":{"app":"mumble"},"type":"NodePort"}}
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
name: mumble-service
|
||||
namespace: mumble
|
||||
resourceVersion: "3560016"
|
||||
uid: c20b0b3a-5d1d-45e4-aec4-37659797bb49
|
||||
spec:
|
||||
clusterIP: 10.43.235.20
|
||||
clusterIPs:
|
||||
- 10.43.235.20
|
||||
externalTrafficPolicy: Cluster
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- name: mumble-tcp
|
||||
nodePort: 31738
|
||||
port: 64738
|
||||
protocol: TCP
|
||||
targetPort: 64738
|
||||
- name: mumble-udp
|
||||
nodePort: 31738
|
||||
port: 64738
|
||||
protocol: UDP
|
||||
targetPort: 64738
|
||||
selector:
|
||||
app: mumble
|
||||
sessionAffinity: None
|
||||
type: NodePort
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T21:33:05Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: adguard
|
||||
name: adguard
|
||||
name: adguard
|
||||
resourceVersion: "41653"
|
||||
uid: 6d812d6a-1921-4169-9805-7d1192073f46
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-12T20:23:24Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack
|
||||
name: bookstack
|
||||
name: bookstack
|
||||
resourceVersion: "829004"
|
||||
uid: e5c59011-b6b6-4f53-a655-a140b7363443
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"bookstack-db"}}
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack-db
|
||||
name: bookstack-db
|
||||
resourceVersion: "834254"
|
||||
uid: 9600ab15-9b1a-451b-af4e-13ff3b672331
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T22:46:31Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
name: cert-manager
|
||||
resourceVersion: "61514"
|
||||
uid: 05b40520-6a11-49af-96df-3d3289a9ed8f
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"cloudflare"}}
|
||||
creationTimestamp: "2026-09-12T15:12:46Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cloudflare
|
||||
name: cloudflare
|
||||
resourceVersion: "737700"
|
||||
uid: f294d89c-0348-444a-b2a8-57303311e45e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: default
|
||||
name: default
|
||||
resourceVersion: "266"
|
||||
uid: ae7a3d3e-3d08-43fe-8e2c-8f72ef066b9e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"gitea"}}
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: gitea
|
||||
name: gitea
|
||||
resourceVersion: "4409092"
|
||||
uid: 6398ba34-919b-4392-afbf-ef0054176a1b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"homepage"}}
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: homepage
|
||||
name: homepage
|
||||
resourceVersion: "3232692"
|
||||
uid: eaafb62a-9a9a-45f3-a7b4-7fa4d1e2ae6b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:46:49Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
resourceVersion: "12923"
|
||||
uid: 46118181-4db6-4c3c-9fdc-f8cc20f28323
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"intel-device-plugin"}}
|
||||
creationTimestamp: "2026-09-17T20:41:41Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: intel-device-plugin
|
||||
name: intel-device-plugin
|
||||
resourceVersion: "2809324"
|
||||
uid: b132d304-80cb-4bdc-88cd-2073a8239312
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-node-lease
|
||||
name: kube-node-lease
|
||||
resourceVersion: "267"
|
||||
uid: 81e945a2-a9f5-4ddc-83a8-2bc214a1559e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-public
|
||||
name: kube-public
|
||||
resourceVersion: "268"
|
||||
uid: 2142a69f-f0bd-45af-8738-563df7f99012
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
name: kube-system
|
||||
resourceVersion: "269"
|
||||
uid: 1b18f0bc-7131-46b4-9e4b-bb0af3d7d63e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:35:47Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: longhorn-system
|
||||
name: longhorn-system
|
||||
name: longhorn-system
|
||||
resourceVersion: "9213"
|
||||
uid: abd04167-9f4b-468e-a637-1649efff2bc7
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"mumble"}}
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: mumble
|
||||
name: mumble
|
||||
resourceVersion: "3560003"
|
||||
uid: cc88370b-9275-43f6-a1f9-2bb663600c48
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"nordvpn"}}
|
||||
creationTimestamp: "2026-09-11T20:23:38Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: nordvpn
|
||||
name: nordvpn
|
||||
resourceVersion: "417127"
|
||||
uid: 15f7c8a5-1b18-475f-84dc-90e5963814fa
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"open-webui"}}
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: open-webui
|
||||
name: open-webui
|
||||
resourceVersion: "2817739"
|
||||
uid: 74bf3bef-51bc-405e-8f79-ebc9f52281c6
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:56:57Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: portainer
|
||||
name: portainer
|
||||
name: portainer
|
||||
resourceVersion: "16301"
|
||||
uid: 17802103-8a9c-4b8f-aa42-03a0db58d2ae
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: openwebui-local-ingress
|
||||
namespace: open-webui
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Instructs NGINX to bridge to the unencrypted pod port 80
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
|
||||
# THE STREAMING FIX: Forces NGINX to instantly forward tokens to your browser
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "off"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to mount the generated certificate
|
||||
tls:
|
||||
- secretName: openwebui-tls-secret
|
||||
hosts:
|
||||
- ai.needlestack.boo
|
||||
rules:
|
||||
- host: ai.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: open-webui-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ollama-fallback
|
||||
namespace: open-webui
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ollama-fallback
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ollama-fallback
|
||||
spec:
|
||||
# Pin the pod strictly to Node 3
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: nst-node-3
|
||||
|
||||
containers:
|
||||
- name: ollama
|
||||
# THE BOOT FIX: Using a frozen tag allows local caching, bypassing the 8-minute pull
|
||||
image: ollama/ollama:0.5.4
|
||||
imagePullPolicy: IfNotPresent
|
||||
# THE FIX: Injects environment variables to pin the model in RAM permanently
|
||||
env:
|
||||
- name: OLLAMA_KEEP_ALIVE
|
||||
value: "-1"
|
||||
# THE SPEED FIX: Forces the calculations to fit perfectly onto your hardware threads
|
||||
- name: OLLAMA_NUM_THREADS
|
||||
value: "4"
|
||||
ports:
|
||||
- containerPort: 11434
|
||||
name: ollama-http
|
||||
resources:
|
||||
# Matching limits and requests perfectly eliminates CPU scheduling wait loops
|
||||
requests:
|
||||
memory: "2Gi"
|
||||
cpu: "4" # Guarantee 4 physical cores
|
||||
limits:
|
||||
memory: "4Gi"
|
||||
cpu: "4" # Perfectly matches the 4 execution threads above
|
||||
volumeMounts:
|
||||
- name: local-model-storage
|
||||
mountPath: /root/.ollama
|
||||
|
||||
volumes:
|
||||
# THE FIX: Bypasses Longhorn replication entirely
|
||||
- name: local-model-storage
|
||||
hostPath:
|
||||
path: /var/lib/ollama-models
|
||||
type: DirectoryOrCreate
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ollama-fallback-service
|
||||
namespace: open-webui
|
||||
spec:
|
||||
selector:
|
||||
app: ollama-fallback
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 11434
|
||||
targetPort: 11434
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: openwebui-db
|
||||
namespace: open-webui
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:16
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: openwebui
|
||||
owner: webui_admin
|
||||
storage:
|
||||
size: 10Gi
|
||||
storageClass: longhorn
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: open-webui
|
||||
namespace: open-webui
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 5
|
||||
selector:
|
||||
matchLabels:
|
||||
app: open-webui
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: open-webui
|
||||
spec:
|
||||
containers:
|
||||
- name: open-webui
|
||||
image: ghcr.io/open-webui/open-webui:main
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
protocol: TCP
|
||||
env:
|
||||
# THE POSTGRES ROUTE: Connects your Python app directly to the CNPG cluster
|
||||
- name: DATABASE_URL
|
||||
value: "postgresql://webui_admin:$(password)@openwebui-db-rw:5432/openwebui"
|
||||
# CORE CAPABILITIES: Kept completely stock to support your fallback and LM Studio
|
||||
- name: ENABLE_OLLAMA_API
|
||||
value: "True"
|
||||
- name: ENABLE_OPENAI_API
|
||||
value: "True"
|
||||
- name: WEBUI_SECRET_KEY
|
||||
value: "5e7fb9706cbd8137baf6299a6e6af6297ae03c6bfe4a6edb"
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: openwebui-db-app
|
||||
volumeMounts:
|
||||
- mountPath: /app/backend/data
|
||||
name: webui-data
|
||||
resources:
|
||||
requests:
|
||||
memory: "1Gi"
|
||||
cpu: "500m"
|
||||
limits:
|
||||
memory: "2Gi"
|
||||
cpu: "2"
|
||||
# THE FIXED DNS LOGIC: Allows the container to see internal cluster service maps natively
|
||||
dnsPolicy: ClusterFirst
|
||||
restartPolicy: Always
|
||||
volumes:
|
||||
- name: webui-data
|
||||
persistentVolumeClaim:
|
||||
claimName: open-webui-pvc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: open-webui-service
|
||||
namespace: open-webui
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: open-webui
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: openwebui-local-ingress
|
||||
namespace: open-webui
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: openwebui-tls-secret
|
||||
hosts:
|
||||
- ai.needlestack.boo
|
||||
rules:
|
||||
- host: ai.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: open-webui-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,430 @@
|
|||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
deployment.kubernetes.io/revision: "1"
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"open-webui","namespace":"open-webui"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"open-webui"}},"template":{"metadata":{"labels":{"app":"open-webui"}},"spec":{"containers":[{"env":[{"name":"ENABLE_OLLAMA_API","value":"False"},{"name":"ENABLE_OPENAI_API","value":"True"}],"image":"ghcr.io/open-webui/open-webui:main","name":"open-webui","ports":[{"containerPort":8080,"name":"http"}],"volumeMounts":[{"mountPath":"/app/backend/data","name":"webui-data"}]}],"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"dnsPolicy":"None","volumes":[{"name":"webui-data","persistentVolumeClaim":{"claimName":"open-webui-pvc"}}]}}}}
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
generation: 1
|
||||
name: open-webui
|
||||
namespace: open-webui
|
||||
resourceVersion: "2817943"
|
||||
uid: 507cd7bd-b252-4060-bf66-2259a42b1889
|
||||
spec:
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 10
|
||||
selector:
|
||||
matchLabels:
|
||||
app: open-webui
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: open-webui
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: ENABLE_OLLAMA_API
|
||||
value: "False"
|
||||
- name: ENABLE_OPENAI_API
|
||||
value: "True"
|
||||
image: ghcr.io/open-webui/open-webui:main
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: open-webui
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
protocol: TCP
|
||||
resources: {}
|
||||
terminationMessagePath: /dev/termination-log
|
||||
terminationMessagePolicy: File
|
||||
volumeMounts:
|
||||
- mountPath: /app/backend/data
|
||||
name: webui-data
|
||||
dnsConfig:
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
dnsPolicy: None
|
||||
restartPolicy: Always
|
||||
schedulerName: default-scheduler
|
||||
securityContext: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: webui-data
|
||||
persistentVolumeClaim:
|
||||
claimName: open-webui-pvc
|
||||
status:
|
||||
availableReplicas: 1
|
||||
conditions:
|
||||
- lastTransitionTime: "2026-09-17T21:10:13Z"
|
||||
lastUpdateTime: "2026-09-17T21:10:13Z"
|
||||
message: Deployment has minimum availability.
|
||||
reason: MinimumReplicasAvailable
|
||||
status: "True"
|
||||
type: Available
|
||||
- lastTransitionTime: "2026-09-17T21:09:55Z"
|
||||
lastUpdateTime: "2026-09-17T21:10:13Z"
|
||||
message: ReplicaSet "open-webui-7d9f677bcf" has successfully progressed.
|
||||
reason: NewReplicaSetAvailable
|
||||
status: "True"
|
||||
type: Progressing
|
||||
observedGeneration: 1
|
||||
readyReplicas: 1
|
||||
replicas: 1
|
||||
updatedReplicas: 1
|
||||
- apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"open-webui-pvc","namespace":"open-webui"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"15Gi"}},"storageClassName":"longhorn"}}
|
||||
pv.kubernetes.io/bind-completed: "yes"
|
||||
pv.kubernetes.io/bound-by-controller: "yes"
|
||||
volume.beta.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
volume.kubernetes.io/storage-provisioner: driver.longhorn.io
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
name: open-webui-pvc
|
||||
namespace: open-webui
|
||||
resourceVersion: "2817816"
|
||||
uid: 8dea60f9-fb9c-48b2-ae21-8a197033605a
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 15Gi
|
||||
storageClassName: longhorn
|
||||
volumeMode: Filesystem
|
||||
volumeName: pvc-8dea60f9-fb9c-48b2-ae21-8a197033605a
|
||||
status:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 15Gi
|
||||
phase: Bound
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"open-webui-service","namespace":"open-webui"},"spec":{"ports":[{"port":80,"targetPort":8080}],"selector":{"app":"open-webui"}}}
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
name: open-webui-service
|
||||
namespace: open-webui
|
||||
resourceVersion: "2817759"
|
||||
uid: 57ffee48-e58c-4639-9c4f-0ee49236e999
|
||||
spec:
|
||||
clusterIP: 10.43.66.33
|
||||
clusterIPs:
|
||||
- 10.43.66.33
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: open-webui
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
status:
|
||||
loadBalancer: {}
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T21:33:05Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: adguard
|
||||
name: adguard
|
||||
name: adguard
|
||||
resourceVersion: "41653"
|
||||
uid: 6d812d6a-1921-4169-9805-7d1192073f46
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-12T20:23:24Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack
|
||||
name: bookstack
|
||||
name: bookstack
|
||||
resourceVersion: "829004"
|
||||
uid: e5c59011-b6b6-4f53-a655-a140b7363443
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"bookstack-db"}}
|
||||
creationTimestamp: "2026-09-12T20:39:27Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: bookstack-db
|
||||
name: bookstack-db
|
||||
resourceVersion: "834254"
|
||||
uid: 9600ab15-9b1a-451b-af4e-13ff3b672331
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T22:46:31Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
name: cert-manager
|
||||
resourceVersion: "61514"
|
||||
uid: 05b40520-6a11-49af-96df-3d3289a9ed8f
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"cloudflare"}}
|
||||
creationTimestamp: "2026-09-12T15:12:46Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cloudflare
|
||||
name: cloudflare
|
||||
resourceVersion: "737700"
|
||||
uid: f294d89c-0348-444a-b2a8-57303311e45e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: default
|
||||
name: default
|
||||
resourceVersion: "266"
|
||||
uid: ae7a3d3e-3d08-43fe-8e2c-8f72ef066b9e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"gitea"}}
|
||||
creationTimestamp: "2026-09-21T21:51:14Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: gitea
|
||||
name: gitea
|
||||
resourceVersion: "4409092"
|
||||
uid: 6398ba34-919b-4392-afbf-ef0054176a1b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"homepage"}}
|
||||
creationTimestamp: "2026-09-18T22:22:12Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: homepage
|
||||
name: homepage
|
||||
resourceVersion: "3232692"
|
||||
uid: eaafb62a-9a9a-45f3-a7b4-7fa4d1e2ae6b
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:46:49Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
name: ingress-nginx
|
||||
resourceVersion: "12923"
|
||||
uid: 46118181-4db6-4c3c-9fdc-f8cc20f28323
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"intel-device-plugin"}}
|
||||
creationTimestamp: "2026-09-17T20:41:41Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: intel-device-plugin
|
||||
name: intel-device-plugin
|
||||
resourceVersion: "2809324"
|
||||
uid: b132d304-80cb-4bdc-88cd-2073a8239312
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-node-lease
|
||||
name: kube-node-lease
|
||||
resourceVersion: "267"
|
||||
uid: 81e945a2-a9f5-4ddc-83a8-2bc214a1559e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-public
|
||||
name: kube-public
|
||||
resourceVersion: "268"
|
||||
uid: 2142a69f-f0bd-45af-8738-563df7f99012
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-07-30T20:57:34Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
name: kube-system
|
||||
resourceVersion: "269"
|
||||
uid: 1b18f0bc-7131-46b4-9e4b-bb0af3d7d63e
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:35:47Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: longhorn-system
|
||||
name: longhorn-system
|
||||
name: longhorn-system
|
||||
resourceVersion: "9213"
|
||||
uid: abd04167-9f4b-468e-a637-1649efff2bc7
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"mumble"}}
|
||||
creationTimestamp: "2026-09-19T18:14:35Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: mumble
|
||||
name: mumble
|
||||
resourceVersion: "3560003"
|
||||
uid: cc88370b-9275-43f6-a1f9-2bb663600c48
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"nordvpn"}}
|
||||
creationTimestamp: "2026-09-11T20:23:38Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: nordvpn
|
||||
name: nordvpn
|
||||
resourceVersion: "417127"
|
||||
uid: 15f7c8a5-1b18-475f-84dc-90e5963814fa
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
kubectl.kubernetes.io/last-applied-configuration: |
|
||||
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"open-webui"}}
|
||||
creationTimestamp: "2026-09-17T21:09:55Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: open-webui
|
||||
name: open-webui
|
||||
resourceVersion: "2817739"
|
||||
uid: 74bf3bef-51bc-405e-8f79-ebc9f52281c6
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
- apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
creationTimestamp: "2026-09-10T19:56:57Z"
|
||||
labels:
|
||||
kubernetes.io/metadata.name: portainer
|
||||
name: portainer
|
||||
name: portainer
|
||||
resourceVersion: "16301"
|
||||
uid: 17802103-8a9c-4b8f-aa42-03a0db58d2ae
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
status:
|
||||
phase: Active
|
||||
kind: List
|
||||
metadata:
|
||||
resourceVersion: ""
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# values.yaml
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
# AUTOMATED TLS FIX: Triggers cert-manager to provision the certificate
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
# THE 502 FIX: Bridges to Portainer's unencrypted HTTP web port cleanly
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
hosts:
|
||||
- host: portainer.needlestack.boo
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
# AUTOMATED TLS FIX: Instructs NGINX where to store the secret
|
||||
tls:
|
||||
- secretName: portainer-tls-secret
|
||||
hosts:
|
||||
- portainer.needlestack.boo
|
||||
service:
|
||||
type: ClusterIP
|
||||
tls:
|
||||
# Leave this false inside the values block so the pod doesn't look for custom internal certs
|
||||
force: false
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: qr-generator
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: qr-generator-ui
|
||||
namespace: qr-generator
|
||||
labels:
|
||||
app: qr-generator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: qr-generator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: qr-generator
|
||||
spec:
|
||||
containers:
|
||||
- name: generator
|
||||
image: kavehbc/qrcode-barcode:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8501
|
||||
resources:
|
||||
limits:
|
||||
memory: "256Mi"
|
||||
cpu: "500m"
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: qr-generator-svc
|
||||
namespace: qr-generator
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8501
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: qr-generator
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: qr-generator-ingress
|
||||
namespace: qr-generator
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: qr-generator-tls-secret
|
||||
hosts:
|
||||
- qr.needlestack.boo
|
||||
rules:
|
||||
- host: qr.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: qr-generator-svc
|
||||
port:
|
||||
number: 80
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: searxng
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: searxng
|
||||
namespace: searxng
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: searxng
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: searxng
|
||||
spec:
|
||||
containers:
|
||||
- name: searxng
|
||||
image: searxng/searxng:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
env:
|
||||
# THE ANONYMITY BASE: Points SearXNG to your local LAN domain routing
|
||||
- name: SEARXNG_BASE_URL
|
||||
value: "https://needlestack.boo"
|
||||
# SECURITY CRITICAL: Paste your unique openssl output string right here
|
||||
- name: SEARXNG_SECRET_KEY
|
||||
value: "0f73d2a5cb68e8ad5827d7584508c78276ebfcf391a9fb74deada8cc04fcaa71"
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: searxng-service
|
||||
namespace: searxng
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: searxng
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: searxng-local-ingress
|
||||
namespace: searxng
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-production"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: searxng-tls-secret
|
||||
hosts:
|
||||
- search.needlestack.boo
|
||||
rules:
|
||||
- host: search.needlestack.boo
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: searxng-service
|
||||
port:
|
||||
number: 80
|
||||
Loading…
Reference in New Issue