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: ""