diff --git a/ansible/roles/nfs-server/tasks/main.yaml b/ansible/roles/nfs-server/tasks/main.yaml index 7867071..2435c82 100644 --- a/ansible/roles/nfs-server/tasks/main.yaml +++ b/ansible/roles/nfs-server/tasks/main.yaml @@ -23,4 +23,13 @@ name: nfs-kernel-server state: started enabled: true + become: true + +- name: Ensure backup directory exists with correct ownership + ansible.builtin.file: + path: /home/nik/backups/gitea + state: directory + owner: "1001" + group: "1001" + mode: "0755" become: true \ No newline at end of file diff --git a/ansible/roles/nfs-server/templates/exports.j2 b/ansible/roles/nfs-server/templates/exports.j2 index a553ad9..cd6f31b 100644 --- a/ansible/roles/nfs-server/templates/exports.j2 +++ b/ansible/roles/nfs-server/templates/exports.j2 @@ -1,4 +1,5 @@ # /etc/exports - managed by Ansible # NFS exports for K3s cluster -/mnt/storage 192.168.7.77(ro,sync,no_subtree_check,no_root_squash,fsid=1) \ No newline at end of file +/mnt/storage 192.168.7.77(ro,sync,no_subtree_check,no_root_squash,fsid=1) +/home/nik/backups 192.168.7.77(rw,sync,no_subtree_check,no_root_squash,fsid=2) \ No newline at end of file diff --git a/manifests/ddns-cronjob.yaml b/manifests/ddns-cronjob.yaml index 5fc1fcb..f626016 100644 --- a/manifests/ddns-cronjob.yaml +++ b/manifests/ddns-cronjob.yaml @@ -13,6 +13,8 @@ metadata: namespace: ddns spec: schedule: "*/5 * * * *" + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 1 jobTemplate: spec: template: diff --git a/manifests/gitea-backup.yaml b/manifests/gitea-backup.yaml new file mode 100644 index 0000000..0ff455e --- /dev/null +++ b/manifests/gitea-backup.yaml @@ -0,0 +1,106 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: gitea-backup + namespace: gitea-backup +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gitea-backup +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gitea-backup +subjects: + - kind: ServiceAccount + name: gitea-backup + namespace: gitea-backup +roleRef: + kind: ClusterRole + name: gitea-backup + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: gitea-backup + namespace: gitea-backup +spec: + schedule: "0 3 */7 * *" + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + spec: + serviceAccountName: gitea-backup + restartPolicy: OnFailure + nodeSelector: + node-role: primary + containers: + - name: backup + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + set -e + echo "Finding Gitea pod..." + GITEA_POD=$(kubectl get pod -n gitea -l app=gitea -o jsonpath='{.items[0].metadata.name}') + echo "Running gitea dump in pod $GITEA_POD..." + kubectl exec -n gitea $GITEA_POD -- rm -f /tmp/gitea-backup.zip + kubectl exec -n gitea $GITEA_POD -- gitea dump \ + --config /data/gitea/conf/app.ini \ + --file /tmp/gitea-backup.zip \ + --type zip + echo "Copying backup to NFS..." + rm -f /backup/gitea-backup.zip + kubectl cp gitea/$GITEA_POD:/tmp/gitea-backup.zip /backup/gitea-backup.zip + echo "Cleaning up temp file..." + kubectl exec -n gitea $GITEA_POD -- rm /tmp/gitea-backup.zip + echo "Backup complete: /backup/gitea-backup.zip" + volumeMounts: + - name: backup + mountPath: /backup + volumes: + - name: backup + persistentVolumeClaim: + claimName: gitea-backup-pvc +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: gitea-backup-pv +spec: + capacity: + storage: 50Gi + accessModes: + - ReadWriteMany + nfs: + server: 192.168.7.183 + path: /home/nik/backups/gitea + persistentVolumeReclaimPolicy: Retain +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: gitea-backup-pvc + namespace: gitea-backup +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 50Gi + volumeName: gitea-backup-pv + storageClassName: ""