diff --git a/clusters/homelab/apps/sparkyfitness.yaml b/clusters/homelab/apps/sparkyfitness.yaml new file mode 100644 index 0000000..b9e18a6 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness.yaml @@ -0,0 +1,19 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: sparkyfitness + namespace: flux-system +spec: + interval: 10m + path: ./clusters/homelab/apps/sparkyfitness + prune: true + sourceRef: + kind: GitRepository + name: flux-system + decryption: + provider: sops + secretRef: + name: sops-age + dependsOn: + - name: cnpg + - name: infrastructure \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/cnpg-cluster.yaml b/clusters/homelab/apps/sparkyfitness/cnpg-cluster.yaml new file mode 100644 index 0000000..22df6f4 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/cnpg-cluster.yaml @@ -0,0 +1,35 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: sparkyfitness-db + namespace: sparkyfitness +spec: + instances: 1 + postgresql: + parameters: + shared_preload_libraries: "pg_stat_statements" + storage: + size: 8Gi + storageClass: longhorn + backup: + barmanObjectStore: + destinationPath: s3://cnpg-backups/sparkyfitness + endpointURL: http://192.168.2.107:9010 + s3Credentials: + accessKeyId: + name: minio-cnpg-credentials + key: ACCESS_KEY_ID + secretAccessKey: + name: minio-cnpg-credentials + key: ACCESS_SECRET_KEY + retentionPolicy: "30d" + bootstrap: + initdb: + database: sparkyfitness + owner: sparky + postInitSQL: + - CREATE EXTENSION IF NOT EXISTS "uuid-ossp" + - CREATE EXTENSION IF NOT EXISTS "pgcrypto" + - CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" + - ALTER USER sparky CREATEROLE + - GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO sparky WITH GRANT OPTION \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/cnpg-scheduledbackup.yaml b/clusters/homelab/apps/sparkyfitness/cnpg-scheduledbackup.yaml new file mode 100644 index 0000000..f98d477 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/cnpg-scheduledbackup.yaml @@ -0,0 +1,10 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: ScheduledBackup +metadata: + name: sparkyfitness-db-backup + namespace: sparkyfitness +spec: + schedule: "0 3 * * *" + backupOwnerReference: self + cluster: + name: sparkyfitness-db \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/helmrelease.yaml b/clusters/homelab/apps/sparkyfitness/helmrelease.yaml new file mode 100644 index 0000000..c1f29a1 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/helmrelease.yaml @@ -0,0 +1,76 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: sparkyfitness + namespace: sparkyfitness +spec: + interval: 1h + chart: + spec: + chart: sparkyfitness + version: ">=0.1.0" + sourceRef: + kind: HelmRepository + name: sparkyfitness + namespace: sparkyfitness + interval: 12h + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + postgresql: + enabled: false + + externalDatabase: + host: sparkyfitness-db-rw.sparkyfitness.svc.cluster.local + port: 5432 + database: sparkyfitness + auth: + existingSecret: sparkyfitness-db-secret + # keys: username, password + + server: + secrets: + existingSecret: sparkyfitness-app-secret + # keys: api_encryption_key, better_auth_secret + appDatabase: + existingSecret: sparkyfitness-appdb-secret + # keys: username, password + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + + frontend: + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + + config: + garmin: + enabled: false + + httpRoute: + enabled: true + hostname: sparkyfitness.net-scope.org # <-- anpassen + parentRef: + name: homelab-gateway # <-- ggf. anpassen + namespace: gateway + sectionName: https + + ingress: + enabled: false + + networkPolicy: + enabled: true \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/helmrepository.yaml b/clusters/homelab/apps/sparkyfitness/helmrepository.yaml new file mode 100644 index 0000000..e64497d --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/helmrepository.yaml @@ -0,0 +1,9 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: sparkyfitness + namespace: sparkyfitness +spec: + type: oci + url: oci://ghcr.io/codewithcj/charts + interval: 12h \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/kustomization.yaml b/clusters/homelab/apps/sparkyfitness/kustomization.yaml new file mode 100644 index 0000000..9549dcf --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - namespace.yaml + - minio-secret.sops.yaml + - secret.sops.yaml + - cnpg-cluster.yaml + - cnpg-scheduledbackup.yaml + - helmrepository.yaml + - helmrelease.yaml \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/minio-secret.sops.yaml b/clusters/homelab/apps/sparkyfitness/minio-secret.sops.yaml new file mode 100644 index 0000000..d1b4a56 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/minio-secret.sops.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Secret +metadata: + name: minio-cnpg-credentials + namespace: sparkyfitness +stringData: + ACCESS_KEY_ID: ENC[AES256_GCM,data:QTyLZleYbt4hi/2ACqe4zmzJ6qw=,iv:9CI7SEsiT/dhvtOFj4e98W/v1cF8emHKdM3aY9RyoaU=,tag:EAba86iYBS3grwwMhdDkEw==,type:str] + ACCESS_SECRET_KEY: ENC[AES256_GCM,data:MovnfHfBplTEDZpaCzkiChQLkJV5w7+GqhcTUvARvwzQlEXeBtCnkQ==,iv:AogRUGsM93KNEO+pN6nzdAug7jsfojjXXbML6C5/LrM=,tag:6Pns/29t8/JemQVZVHYB/A==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rydfcalt7pu4jnmh298lgjlasxyjldyaz3xyssk7v54lpu30fv0qna96ea + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQV3hYdm5DR0h1SjFBeGZR + RjhVdFFKTURBZkg2dW1JY2R4Zmw1Y2Q0SlM4Ck5EWWlRZkR4N3k5TGFvYXRZNTR5 + SFZnQ3BFOWsxSDFvVGpJQThZZ3BTYjgKLS0tIHoxVXM3dXFGbFFQSVZTVEpRaDNr + b29kUGo0Q2VwbTd6NkxPU2xoSStxWjgKO8ItEv2t2Zh/JHv0Nu4bR0EcpH2mErAq + 7E01pJzc5e8B4oHJofZ5QP7MiPbDVx4KCgD0LREmG+MSIwwP0yfZVA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-05-26T09:50:43Z" + mac: ENC[AES256_GCM,data:6oq9Y591KNzrrlaysijDtubKmUoHzVIGitFnzHAVcYq7e7BN6zNY5NhfST9YhJmMKVdrla5TqrgGDOBJQg2zQroGBbP4yD/gokenR+f1yPwVGdbcceEgN1TV8vzi1G3unREvhmV0QQWHQhIZPBIIYiUd/cI55ARAhx231NTbLXw=,iv:r7sjLEcJIZk2gCxEB5Q11LT37tw2ABuFbbmOY+ai938=,tag:Q1ZBhjmuskM2j8l/G76xUQ==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4 diff --git a/clusters/homelab/apps/sparkyfitness/namespace.yaml b/clusters/homelab/apps/sparkyfitness/namespace.yaml new file mode 100644 index 0000000..c9c1322 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: sparkyfitness \ No newline at end of file diff --git a/clusters/homelab/apps/sparkyfitness/secret.sops.yaml b/clusters/homelab/apps/sparkyfitness/secret.sops.yaml new file mode 100644 index 0000000..2d5fe28 --- /dev/null +++ b/clusters/homelab/apps/sparkyfitness/secret.sops.yaml @@ -0,0 +1,99 @@ +apiVersion: v1 +kind: Secret +metadata: + name: sparkyfitness-db-secret + namespace: sparkyfitness +stringData: + username: ENC[AES256_GCM,data:s5+BtLM=,iv:dTKvQbdYNNN4UlgJ7qDdooXGNWzBcrE6722LQR4S4b8=,tag:0HrGT2vIaY4GaQyNsSQSRA==,type:str] + password: ENC[AES256_GCM,data:0f8Q/Y/4DXc=,iv:QqQVUoOlNA+DtyrdkRrchvxgLH79CAAGVDcDRXJnYLY=,tag:eft8ZcpVGCRkD7qkN0fQEg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rydfcalt7pu4jnmh298lgjlasxyjldyaz3xyssk7v54lpu30fv0qna96ea + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aFJlM09ESFZSdmQyWHZN + NzlhVE80eDg3cFZJbzRJajAzOGtiNWhqeUVZCjAvaWh0ekZtcWNEcHZ5aHhnODRV + T3JPSFJxL3JKNk9oeDlGQnhQNFZrbzAKLS0tIHF2Rm9LVnhzYzRkVHRhd08zREdL + eEw0NzNiQWVhSXF1Q2xkZGRTOGhLalEKRu8XUE7qmaoyKOx/y+2h3/B4xzx2+toD + 2y3ZVV5YDb266EfDQ/TyH0JyuNczw9F4nzWCHHP0NeCFQVJMSfl0og== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-05-26T09:47:34Z" + mac: ENC[AES256_GCM,data:igQwMXuNacNSeVlsy1GmFA//a9s+fa+qBdwlLvdbw2U1lcw2akgTGhjxolg4ACKU+K9RpM3hOxvwp8DOdLwRk/duHwlvVranOlLq7+lky8D3Ec4z/YBHAnLnF5F7pyEtEA7/vKf2q47yoUkxvoZfPn4XEIV+zVUUTt8jdJzHuY4=,iv:UR3NYMFO5LmI4gqwe6QhL1EPlavp5N14Tk6ggWEDTKI=,tag:V9zOZlt64NXdce86PAfDRA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4 +--- +apiVersion: v1 +kind: Secret +metadata: + name: sparkyfitness-appdb-secret + namespace: sparkyfitness +stringData: + username: ENC[AES256_GCM,data:onGgewc=,iv:Nlf05QgJ3a3WiBbhz8RzYEs4J5SGGo6OXhZMq5+eFks=,tag:WHaCk2rS78ekJTXf4M7R0A==,type:str] + password: ENC[AES256_GCM,data:TnZcBesc7gI=,iv:YgDJ0LMgUgPgcXRagfMLdaeQIR7g7jy5pIS00fRUICM=,tag:hqkfmvev8UVOn8fBy0ocUA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rydfcalt7pu4jnmh298lgjlasxyjldyaz3xyssk7v54lpu30fv0qna96ea + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aFJlM09ESFZSdmQyWHZN + NzlhVE80eDg3cFZJbzRJajAzOGtiNWhqeUVZCjAvaWh0ekZtcWNEcHZ5aHhnODRV + T3JPSFJxL3JKNk9oeDlGQnhQNFZrbzAKLS0tIHF2Rm9LVnhzYzRkVHRhd08zREdL + eEw0NzNiQWVhSXF1Q2xkZGRTOGhLalEKRu8XUE7qmaoyKOx/y+2h3/B4xzx2+toD + 2y3ZVV5YDb266EfDQ/TyH0JyuNczw9F4nzWCHHP0NeCFQVJMSfl0og== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-05-26T09:47:34Z" + mac: ENC[AES256_GCM,data:igQwMXuNacNSeVlsy1GmFA//a9s+fa+qBdwlLvdbw2U1lcw2akgTGhjxolg4ACKU+K9RpM3hOxvwp8DOdLwRk/duHwlvVranOlLq7+lky8D3Ec4z/YBHAnLnF5F7pyEtEA7/vKf2q47yoUkxvoZfPn4XEIV+zVUUTt8jdJzHuY4=,iv:UR3NYMFO5LmI4gqwe6QhL1EPlavp5N14Tk6ggWEDTKI=,tag:V9zOZlt64NXdce86PAfDRA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4 +--- +apiVersion: v1 +kind: Secret +metadata: + name: sparkyfitness-app-secret + namespace: sparkyfitness +stringData: + api_encryption_key: ENC[AES256_GCM,data:Nu27yu/HVORcKHBaRGZ/f3TrliDDySrjKF7RiZHw9ruGebnV8Smtg8cpv570LDilcYr0zG3rXkgy7YHedQ6LkA==,iv:w482arFwsfqy99VxhaYn8FmL1/r5W41hQw7yfS41sas=,tag:oCGTkVohckPhXPvViEzoaA==,type:str] + better_auth_secret: ENC[AES256_GCM,data:YqFpjv+QMsEYtyDZQHEx4/cGPP5V1k2r9iynJqzeCMpnYeClMgUHUphlfUNumXJBBtDzMiG/uleViyXdka2qFQ==,iv:HP/zjHSjsx/i9SodTvTxtQP1t7u1sEyHlyVcn/RlVpY=,tag:fTAjB0JOj52/cHK8eLRnew==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rydfcalt7pu4jnmh298lgjlasxyjldyaz3xyssk7v54lpu30fv0qna96ea + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + -----END AGE ENCRYPTED FILE----- + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4 +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1rydfcalt7pu4jnmh298lgjlasxyjldyaz3xyssk7v54lpu30fv0qna96ea + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aFJlM09ESFZSdmQyWHZN + NzlhVE80eDg3cFZJbzRJajAzOGtiNWhqeUVZCjAvaWh0ekZtcWNEcHZ5aHhnODRV + T3JPSFJxL3JKNk9oeDlGQnhQNFZrbzAKLS0tIHF2Rm9LVnhzYzRkVHRhd08zREdL + eEw0NzNiQWVhSXF1Q2xkZGRTOGhLalEKRu8XUE7qmaoyKOx/y+2h3/B4xzx2+toD + 2y3ZVV5YDb266EfDQ/TyH0JyuNczw9F4nzWCHHP0NeCFQVJMSfl0og== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-05-26T09:47:34Z" + mac: ENC[AES256_GCM,data:igQwMXuNacNSeVlsy1GmFA//a9s+fa+qBdwlLvdbw2U1lcw2akgTGhjxolg4ACKU+K9RpM3hOxvwp8DOdLwRk/duHwlvVranOlLq7+lky8D3Ec4z/YBHAnLnF5F7pyEtEA7/vKf2q47yoUkxvoZfPn4XEIV+zVUUTt8jdJzHuY4=,iv:UR3NYMFO5LmI4gqwe6QhL1EPlavp5N14Tk6ggWEDTKI=,tag:V9zOZlt64NXdce86PAfDRA==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.9.4