├── .github └── workflows │ └── flux-diff.yaml ├── .gitignore ├── .sops.pub.asc ├── .sops.yaml ├── apps ├── actual │ ├── actual-boet │ │ ├── backup-secret.yaml │ │ ├── backup.yaml │ │ ├── helmrelease.yaml │ │ └── volume.yaml │ ├── actual-nathalie │ │ ├── backup-secret.yaml │ │ ├── backup.yaml │ │ ├── helmrelease.yaml │ │ └── volume.yaml │ └── actual-shared │ │ ├── backup-secret.yaml │ │ ├── backup.yaml │ │ ├── helmrelease.yaml │ │ └── volume.yaml ├── angel-backups.yaml ├── changedetection.yaml ├── dawarich │ ├── database.yaml │ ├── dawarich.yaml │ ├── dawarkitty-secret.yaml │ ├── dawarkitty.yaml │ ├── helm-repo.yaml │ └── namespace.yaml ├── db-static.yaml ├── esphome │ ├── esphome.yaml │ └── volume.yaml ├── helm-repository.yaml ├── homepage │ ├── deployment.yaml │ ├── secret.yaml │ └── service.yaml ├── imagebot │ ├── backup │ │ ├── backup.yaml │ │ └── secret.yaml │ ├── deployment.yaml │ ├── pvc.yaml │ └── secret.yaml ├── immich │ ├── backup │ │ ├── backup.yaml │ │ └── secret.yaml │ ├── database.yaml │ ├── helm-repo.yaml │ ├── immich.yaml │ ├── ml-cache.yaml │ ├── namespace.yaml │ └── photo-library.yaml ├── kobotools.yaml ├── libreddit.yaml ├── minecraft.yaml ├── miniflux │ ├── database.yaml │ ├── miniflux.yaml │ └── secret.yaml ├── namespace.yaml ├── paperless │ ├── backup-secret.yaml │ ├── backup.yaml │ ├── database.yaml │ ├── helmrelease.yaml │ ├── secret.yaml │ └── volume.yaml ├── proxy │ └── camera.yaml ├── radio │ ├── acars.yaml │ ├── helm-repository.yaml │ └── namespace.yaml ├── social │ ├── database.yaml │ ├── gotosocial.yaml │ ├── helm-repository.yaml │ ├── namespace.yaml │ ├── oidc-secret.yaml │ ├── phanpy.yaml │ └── volume.yaml ├── spoolman │ ├── database.yaml │ └── helmrelease.yaml ├── stirling-pdf.yaml ├── tiddlywiki-boet │ ├── backup │ │ ├── backup.yaml │ │ └── secret.yaml │ ├── credentials.yaml │ ├── deployment.yaml │ ├── service.yaml │ └── volume.yaml ├── tiddlywiki │ ├── backup │ │ ├── backup.yaml │ │ └── secret.yaml │ ├── credentials.yaml │ ├── deployment.yaml │ ├── service.yaml │ └── volume.yaml ├── vaultwarden │ ├── backup-secret.yaml │ ├── backup.yaml │ ├── database.yaml │ ├── helmrelease.yaml │ └── volume.yaml └── zipline │ ├── database.yaml │ ├── secret.yaml │ ├── volume.yaml │ └── zipline.yaml ├── automation ├── archiveteam.yaml ├── emqx │ ├── helm-repo.yaml │ ├── helmrelease.yaml │ └── secret.yaml ├── machinekamer.yaml ├── namespace.yaml └── zigbee2mqtt │ ├── bjw-s-repo.yaml │ ├── exporter.yaml │ ├── helmrelease.yaml │ └── volume.yaml ├── database ├── app-db.yaml ├── backblaze-secret.yaml ├── cnpg-operator.yaml ├── ext-postgres-operator │ ├── crds.yaml │ ├── operator.yaml │ └── rbac.yaml ├── minio │ ├── backup │ │ ├── backup.yaml │ │ └── secret.yaml │ ├── minio-secret.yaml │ └── minio.yaml └── namespace.yaml ├── flux-system ├── cluster-secrets.yaml ├── gotk-components.yaml ├── gotk-sync.yaml ├── ingress.yaml ├── kustomization.yaml ├── webhook-secret.yaml └── webhook.yaml ├── infrastructure ├── auth │ ├── authentik.yaml │ ├── database.yaml │ ├── namespace.yaml │ ├── repo.yaml │ └── secret.yaml ├── dns │ ├── cert-manager.yaml │ ├── cloudflare-api-token.yaml │ ├── cloudflare-issuer.yaml │ ├── external-dns.yaml │ └── namespace.yaml ├── goldilocks │ ├── goldilocks.yaml │ ├── namespace.yaml │ ├── repo.yaml │ └── vpa.yaml ├── ingress │ ├── ingress-nginx.yaml │ └── namespace.yaml ├── kyverno │ ├── kyverno.yaml │ ├── namespace.yaml │ ├── policies │ │ └── apply-ingress-auth-annotations.yaml │ └── repo.yaml ├── metallb.yaml ├── monitoring │ ├── kube-prometheus-stack.yaml │ ├── namespace.yaml │ ├── repo.yaml │ ├── shelly-exporter.yaml │ └── snmp-exporter.yaml ├── storage │ ├── democratic-csi.yaml │ ├── namespace.yaml │ ├── snapshot-controller.yaml │ ├── volsync.yaml │ └── zfs-generic-iscsi-config.yaml └── system │ ├── generic-device-plugin │ ├── config.yaml │ ├── hr.yaml │ └── kustomization.yaml │ ├── helm-repository.yaml │ └── namespace.yaml ├── media ├── bazarr.yaml ├── bjw-s-repo.yaml ├── emby.yaml ├── media-library.yaml ├── namespace.yaml ├── ombi.yaml ├── prowlarr.yaml ├── qbittorrent.yaml ├── radarr.yaml ├── sonarr.yaml └── twitch-dl.yaml └── renovate.json /.github/workflows/flux-diff.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Flux Diff" 3 | 4 | on: 5 | pull_request: 6 | branches: ["main"] 7 | 8 | jobs: 9 | flux-diff: 10 | name: Flux Diff 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | pull-requests: write 15 | strategy: 16 | matrix: 17 | resource: ["helmrelease", "kustomization"] 18 | steps: 19 | - name: Diff Resources 20 | uses: allenporter/flux-local/action/diff@19bfc6920e8964a479363bc230e6c329120ead02 # 3.2.0 21 | id: diff 22 | with: 23 | path: "./" 24 | resource: "${{ matrix.resource }}" 25 | 26 | - if: ${{ steps.diff.outputs.diff != '' }} 27 | name: Add comment 28 | uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2 29 | with: 30 | message-id: "${{ github.event.pull_request.number }}/${{ matrix.path }}/${{ matrix.resource }}" 31 | message-failure: Diff was not successful 32 | message: | 33 | ```diff 34 | ${{ steps.diff.outputs.diff }} 35 | ``` 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /.sops.pub.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | 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 61 | l7qfvs3yUzkz271KPGlQvlAifnyw2SozawsCRIE= 62 | =rl+I 63 | -----END PGP PUBLIC KEY BLOCK----- 64 | -------------------------------------------------------------------------------- /.sops.yaml: -------------------------------------------------------------------------------- 1 | creation_rules: 2 | - path_regex: .*.yaml 3 | encrypted_regex: ^(data|stringData)$ 4 | pgp: DB3395B20E82DA5501D7B353AF52965D73D119F7 5 | -------------------------------------------------------------------------------- /apps/actual/actual-boet/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: actual-boet-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/actual-boet" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/actual/actual-boet/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: actual-boet-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: actual-boet-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: actual-boet-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/actual/actual-boet/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2beta2.schema.json 3 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 4 | kind: HelmRelease 5 | metadata: 6 | name: actual-boet 7 | namespace: applications 8 | spec: 9 | interval: 30m 10 | chart: 11 | spec: 12 | chart: app-template 13 | version: 3.1.0 14 | interval: 30m 15 | sourceRef: 16 | kind: HelmRepository 17 | name: bjw-s-charts 18 | namespace: applications 19 | values: 20 | controllers: 21 | actual: 22 | containers: 23 | app: 24 | image: 25 | repository: ghcr.io/actualbudget/actual-server 26 | tag: 25.5.0 27 | probes: 28 | liveness: 29 | enabled: true 30 | readiness: 31 | enabled: true 32 | startup: 33 | enabled: true 34 | spec: 35 | failureThreshold: 30 36 | periodSeconds: 5 37 | resources: 38 | requests: 39 | cpu: 12m 40 | memory: 128M 41 | limits: 42 | memory: 512M 43 | 44 | service: 45 | app: 46 | controller: actual 47 | ports: 48 | http: 49 | port: 5006 50 | 51 | ingress: 52 | app: 53 | annotations: 54 | kubernetes.io/ingress.class: nginx-internal 55 | cert-manager.io/cluster-issuer: letsencrypt-prod 56 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 57 | hosts: 58 | - host: &hostName actual-boet.bo0tzz.me 59 | paths: 60 | - path: / 61 | service: 62 | identifier: app 63 | port: http 64 | tls: 65 | - hosts: 66 | - *hostName 67 | secretName: actual-boet-tls 68 | 69 | persistence: 70 | data: 71 | existingClaim: actual-boet-data 72 | advancedMounts: 73 | actual: 74 | app: 75 | - path: /data -------------------------------------------------------------------------------- /apps/actual/actual-boet/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: actual-boet-data 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 10Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/actual/actual-nathalie/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: actual-nathalie-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/actual-nathalie" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/actual/actual-nathalie/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: actual-nathalie-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: actual-nathalie-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: actual-nathalie-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/actual/actual-nathalie/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2beta2.schema.json 3 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 4 | kind: HelmRelease 5 | metadata: 6 | name: actual-nathalie 7 | namespace: applications 8 | spec: 9 | interval: 30m 10 | chart: 11 | spec: 12 | chart: app-template 13 | version: 3.1.0 14 | interval: 30m 15 | sourceRef: 16 | kind: HelmRepository 17 | name: bjw-s-charts 18 | namespace: applications 19 | values: 20 | controllers: 21 | actual: 22 | containers: 23 | app: 24 | image: 25 | repository: ghcr.io/actualbudget/actual-server 26 | tag: 25.5.0 27 | probes: 28 | liveness: 29 | enabled: true 30 | readiness: 31 | enabled: true 32 | startup: 33 | enabled: true 34 | spec: 35 | failureThreshold: 30 36 | periodSeconds: 5 37 | resources: 38 | requests: 39 | cpu: 12m 40 | memory: 128M 41 | limits: 42 | memory: 512M 43 | 44 | service: 45 | app: 46 | controller: actual 47 | ports: 48 | http: 49 | port: 5006 50 | 51 | ingress: 52 | app: 53 | annotations: 54 | kubernetes.io/ingress.class: nginx-internal 55 | cert-manager.io/cluster-issuer: letsencrypt-prod 56 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 57 | hosts: 58 | - host: &hostName actual-nathalie.bo0tzz.me 59 | paths: 60 | - path: / 61 | service: 62 | identifier: app 63 | port: http 64 | tls: 65 | - hosts: 66 | - *hostName 67 | secretName: actual-nathalie-tls 68 | 69 | persistence: 70 | data: 71 | existingClaim: actual-nathalie-data 72 | advancedMounts: 73 | actual: 74 | app: 75 | - path: /data -------------------------------------------------------------------------------- /apps/actual/actual-nathalie/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: actual-nathalie-data 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 10Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/actual/actual-shared/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: actual-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/actual" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/actual/actual-shared/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: actual-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: actual-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: actual-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/actual/actual-shared/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2beta2.schema.json 3 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 4 | kind: HelmRelease 5 | metadata: 6 | name: actual 7 | namespace: applications 8 | spec: 9 | interval: 30m 10 | chart: 11 | spec: 12 | chart: app-template 13 | version: 3.1.0 14 | interval: 30m 15 | sourceRef: 16 | kind: HelmRepository 17 | name: bjw-s-charts 18 | namespace: applications 19 | values: 20 | controllers: 21 | actual: 22 | containers: 23 | app: 24 | image: 25 | repository: ghcr.io/actualbudget/actual-server 26 | tag: 25.5.0 27 | probes: 28 | liveness: 29 | enabled: true 30 | readiness: 31 | enabled: true 32 | startup: 33 | enabled: true 34 | spec: 35 | failureThreshold: 30 36 | periodSeconds: 5 37 | resources: 38 | requests: 39 | cpu: 12m 40 | memory: 128M 41 | limits: 42 | memory: 512M 43 | 44 | service: 45 | app: 46 | controller: actual 47 | ports: 48 | http: 49 | port: 5006 50 | 51 | ingress: 52 | app: 53 | annotations: 54 | kubernetes.io/ingress.class: nginx-internal 55 | cert-manager.io/cluster-issuer: letsencrypt-prod 56 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 57 | hosts: 58 | - host: &hostName actual.bo0tzz.me 59 | paths: 60 | - path: / 61 | service: 62 | identifier: app 63 | port: http 64 | tls: 65 | - hosts: 66 | - *hostName 67 | secretName: actual-tls 68 | 69 | persistence: 70 | data: 71 | existingClaim: actual-data 72 | advancedMounts: 73 | actual: 74 | app: 75 | - path: /data -------------------------------------------------------------------------------- /apps/actual/actual-shared/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: actual-data 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 10Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/angel-backups.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: angel-backups-conf 5 | namespace: applications 6 | data: 7 | nginx.conf: | 8 | server { 9 | listen 80; 10 | listen [::]:80; 11 | server_name localhost; 12 | 13 | root /data; 14 | autoindex on; 15 | 16 | error_page 500 502 503 504 /50x.html; 17 | location = /50x.html { 18 | root /usr/share/nginx/html; 19 | } 20 | } 21 | --- 22 | apiVersion: v1 23 | kind: PersistentVolumeClaim 24 | metadata: 25 | name: angel-backups 26 | namespace: applications 27 | spec: 28 | storageClassName: zfs-iscsi 29 | accessModes: 30 | - ReadWriteOnce 31 | resources: 32 | requests: 33 | storage: 100G 34 | --- 35 | apiVersion: apps/v1 36 | kind: Deployment 37 | metadata: 38 | name: angel-backups 39 | namespace: applications 40 | spec: 41 | strategy: 42 | type: Recreate 43 | selector: 44 | matchLabels: 45 | app: angel-backups 46 | replicas: 1 47 | template: 48 | metadata: 49 | labels: 50 | app: angel-backups 51 | spec: 52 | containers: 53 | - name: angel-backups 54 | image: nginx:1.28.0 55 | ports: 56 | - containerPort: 80 57 | volumeMounts: 58 | - mountPath: /etc/nginx/conf.d 59 | name: angel-backups-conf 60 | readOnly: true 61 | - mountPath: /data 62 | name: angel-backups-files 63 | volumes: 64 | - name: angel-backups-conf 65 | configMap: 66 | name: angel-backups-conf 67 | - name: angel-backups-files 68 | persistentVolumeClaim: 69 | claimName: angel-backups 70 | --- 71 | apiVersion: v1 72 | kind: Service 73 | metadata: 74 | labels: 75 | service: angel-backups-web 76 | name: angel-backups 77 | namespace: applications 78 | spec: 79 | ports: 80 | - name: "http" 81 | port: 80 82 | targetPort: 80 83 | selector: 84 | app: angel-backups 85 | --- 86 | apiVersion: networking.k8s.io/v1 87 | kind: Ingress 88 | metadata: 89 | name: angel-backups-web 90 | namespace: applications 91 | annotations: 92 | auth.kube.bo0tzz.me/enabled: "true" 93 | kubernetes.io/ingress.class: nginx-internal 94 | cert-manager.io/cluster-issuer: letsencrypt-prod 95 | spec: 96 | tls: 97 | - hosts: 98 | - angel-backups.bo0tzz.me 99 | secretName: angel-backups-web-tls 100 | rules: 101 | - host: angel-backups.bo0tzz.me 102 | http: 103 | paths: 104 | - path: / 105 | pathType: Prefix 106 | backend: 107 | service: 108 | name: angel-backups 109 | port: 110 | name: http 111 | -------------------------------------------------------------------------------- /apps/changedetection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: &app changedetection 5 | namespace: applications 6 | spec: 7 | interval: 15m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: "3.6.1" 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | values: 17 | controllers: 18 | *app : 19 | containers: 20 | *app : 21 | image: 22 | repository: ghcr.io/dgtlmoon/changedetection.io 23 | tag: "0.49.18" 24 | env: 25 | PORT: &port 5000 26 | PLAYWRIGHT_DRIVER_URL: ws://localhost:3000 27 | 28 | browser: 29 | image: 30 | pullPolicy: Always 31 | repository: docker.io/browserless/chrome 32 | tag: "1-chrome-stable" 33 | env: 34 | - name: SCREEN_WIDTH 35 | value: "1920" 36 | - name: SCREEN_HEIGHT 37 | value: "1024" 38 | - name: SCREEN_DEPTH 39 | value: "16" 40 | - name: ENABLE_DEBUGGER 41 | value: "false" 42 | - name: PREBOOT_CHROME 43 | value: "true" 44 | - name: CONNECTION_TIMEOUT 45 | value: "300000" 46 | - name: MAX_CONCURRENT_SESSIONS 47 | value: "10" 48 | - name: CHROME_REFRESH_TIME 49 | value: "600000" 50 | - name: DEFAULT_BLOCK_ADS 51 | value: "true" 52 | - name: DEFAULT_STEALTH 53 | value: "true" 54 | 55 | persistence: 56 | datastore: 57 | enabled: true 58 | storageClass: zfs-iscsi 59 | size: 20Gi 60 | accessMode: ReadWriteOnce 61 | 62 | service: 63 | main: 64 | controller: *app 65 | ports: 66 | http: 67 | port: *port 68 | 69 | ingress: 70 | main: 71 | annotations: 72 | kubernetes.io/ingress.class: nginx-internal 73 | cert-manager.io/cluster-issuer: letsencrypt-prod 74 | hosts: 75 | - host: &host "cd.bo0tzz.me" 76 | paths: 77 | - path: / 78 | pathType: Prefix 79 | service: 80 | identifier: main 81 | tls: 82 | - hosts: 83 | - *host 84 | secretName: *host 85 | -------------------------------------------------------------------------------- /apps/dawarich/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: dawarich-db 5 | namespace: dawarich 6 | spec: 7 | database: dawarich 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: dawarich-user 13 | namespace: dawarich 14 | spec: 15 | role: dawarich 16 | database: dawarich-db 17 | secretName: database 18 | privileges: OWNER -------------------------------------------------------------------------------- /apps/dawarich/dawarich.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 3 | kind: HelmRelease 4 | metadata: 5 | name: &app dawarich 6 | namespace: dawarich 7 | spec: 8 | interval: 30m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: 3.6.1 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: dawarich 17 | maxHistory: 2 18 | install: 19 | createNamespace: true 20 | remediation: 21 | retries: 3 22 | upgrade: 23 | cleanupOnFail: true 24 | remediation: 25 | retries: 3 26 | uninstall: 27 | keepHistory: false 28 | values: 29 | controllers: 30 | dawarich: 31 | containers: 32 | app: &bapp 33 | image: 34 | repository: ghcr.io/bo0tzz/dawarich 35 | tag: main@sha256:2a1884eec71649367364f1458685874d0bdd1ed0786b4fe5f6d3ef39923013e3 36 | env: 37 | REDIS_URL: redis://localhost:6379 38 | APPLICATION_HOSTS: "dawarich.bo0tzz.me,dawarich:3000" 39 | DATABASE_HOST: 40 | valueFrom: 41 | secretKeyRef: 42 | name: database-dawarich-user 43 | key: HOST 44 | DATABASE_USERNAME: 45 | valueFrom: 46 | secretKeyRef: 47 | name: database-dawarich-user 48 | key: LOGIN 49 | DATABASE_PASSWORD: 50 | valueFrom: 51 | secretKeyRef: 52 | name: database-dawarich-user 53 | key: PASSWORD 54 | DATABASE_NAME: 55 | valueFrom: 56 | secretKeyRef: 57 | name: database-dawarich-user 58 | key: DATABASE_NAME 59 | resources: 60 | requests: 61 | memory: "1Gi" 62 | cpu: "250m" 63 | command: 64 | - "web-entrypoint.sh" 65 | args: 66 | - "bin/rails server -p 3000 -b 0.0.0.0" 67 | sidekick: 68 | <<: *bapp 69 | command: 70 | - "sidekiq-entrypoint.sh" 71 | args: 72 | - "bundle exec sidekiq" 73 | resources: 74 | requests: 75 | memory: "1Gi" 76 | cpu: "250m" 77 | valkey: 78 | image: 79 | repository: docker.io/valkey/valkey 80 | tag: 8.1.1 81 | service: 82 | app: 83 | controller: *app 84 | ports: 85 | http: 86 | port: 3000 87 | ingress: 88 | app: 89 | annotations: 90 | kubernetes.io/ingress.class: nginx-internal 91 | cert-manager.io/cluster-issuer: letsencrypt-prod 92 | hosts: 93 | - host: &hostname dawarich.bo0tzz.me 94 | paths: 95 | - path: / 96 | service: 97 | identifier: app 98 | port: http 99 | tls: 100 | - hosts: 101 | - *hostname 102 | secretName: dawarich-tls 103 | -------------------------------------------------------------------------------- /apps/dawarich/dawarkitty-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: dawarkitty-secret 5 | namespace: dawarich 6 | stringData: 7 | DAWARICH_HOST: ENC[AES256_GCM,data:1GdGOv92QL/XeFWh92N2ksDzd/s=,iv:uU8IRXjjCcTOdkHa/wA/zl4JCga7OVy9R1EEh/pHm8Q=,tag:B4jWJxRlf6c82LX+Fzw7Vg==,type:str] 8 | DAWARICH_API_KEY: ENC[AES256_GCM,data:C8c1f3MkPSDOVreOi7L27MgyFUirGnb356klN3LlFgg=,iv:5aIX1i3eumCmIoZ8UijLRnTfhxxCbOSAA7A8y1eOLYo=,tag:f1mCATYlA3qrgvmYAKvYtw==,type:str] 9 | TRACTIVE_EMAIL: ENC[AES256_GCM,data:YMAC1sOIM0DHRdDYGzmgAw9vq7ESfw==,iv:yGFU5uFgNY7bpDYbApeBZMY0QAUl+65sxRAw8TxoL3M=,tag:5VgZD0GBo1d5F2JPmFuA8Q==,type:str] 10 | TRACTIVE_PASSWORD: ENC[AES256_GCM,data:hl5L5SHoa57orYnIBMmMB87ZWyH21JNJk/M4W6xKj1MpcRX93YY9fg==,iv:nIgrFWSBD7prDWoTjA0Pw6UZMw4kTZ4T9xiS88OcPyQ=,tag:0GsX5WyB/wjlKJyGczmwDA==,type:str] 11 | sops: 12 | kms: [] 13 | gcp_kms: [] 14 | azure_kv: [] 15 | hc_vault: [] 16 | age: [] 17 | lastmodified: "2025-01-28T19:05:41Z" 18 | mac: ENC[AES256_GCM,data:xae9FlqdkmwbW93nt6ksJtoUNax8bE3eTVCLXbFSVpwkM88T4D6TeDHnXPHnkBXp4sQkL3+G2NGF2hzoj3VgIIqqtnxOpxCzYxP8XDlJD4g0vP9uWB/vufDpzi5kebMJ0pE2qYUYJoMv5FlUXVWBtfGzEc/NdFjKG13ubDWmJfM=,iv:7fnOpYfAOZZAtzCC3c2clUwD0tDi2NCrC2Kf9d5CL0k=,tag:a5wlPGZPLFIHSS5VRI47gA==,type:str] 19 | pgp: 20 | - created_at: "2025-01-28T17:34:16Z" 21 | enc: |- 22 | -----BEGIN PGP MESSAGE----- 23 | 24 | hQIMA2YE/I5Bjk+6ARAAitTSX6TpPqHmYRndUbpflEiWbTkzUgTMVTbw9w31p9D2 25 | I0HoFrjPnc35FhdH2z7Khgjk1/oR7nEAOb6/oq3/zmDjles03DI+DNqkw4hO9vpC 26 | ODfshgL9EV/mKHDXIW4pphJeJazPs7W1uR6FyvRifCXPlGHl5jxsC4+9cRDwovdk 27 | xaC+IphIJMIL9OFLoh1zC8f8sz45Iq50Ik3wxwIQJR+tdtRdQ8VcNALSL8V3wBEn 28 | sltFmCL01LGPuogf6Zp7BT7rv723evnFkqTvCPno9CxT7CuSw+5iVUXkTWRWx/NU 29 | hHENn6B8ppDPBXmxY1ZawvNVOLddjQeSR+X5mMNDZzFemA/Q0dYkzw4WEtvntsIz 30 | +Sjufdul6KG76e2DqHPyodNfpbRTyKR0oRoBuEAcbhfAHf5yUbOyov4CK8uUlTxk 31 | y6duFkf1bzJ9/xcugkyWe4ddTwjWrc89wVjkXG4wXhlQkMRmIgIDv46SGpZYDQ/L 32 | copE1JgmMrN+UsqvDC0HISLdVvCSJ7Llhlq9AjHkLoag/fqlvqzHViZNkGLya0Dh 33 | bdMj0CprMVGXxI6FksuTus2JyZsLVA1cWEInxMnwvP5wniV4l9GEOPrGg/PDNwVK 34 | 9rJfexbJBIYUAtEBAHljWeylpj3nhy7b+V3A7C3LGQZVg71Yx1WU+2YlooRspSrU 35 | aAEJAhDm1VU5rgRCS1fqhaM5WFk9qnkb2TtjHLY5eNzSnrwbv7XvVRjHus4Exe2t 36 | BVUCxxHmc9/9kGf9r0+o3oJ3wmGrtfz8bnJSIdnjA2b6QPPddC+kcHYhcodm/2QV 37 | PphvREg9QooH 38 | =y90y 39 | -----END PGP MESSAGE----- 40 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 41 | encrypted_regex: ^(data|stringData)$ 42 | version: 3.9.1 43 | -------------------------------------------------------------------------------- /apps/dawarich/dawarkitty.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 3 | kind: HelmRelease 4 | metadata: 5 | name: dawarkitty 6 | namespace: dawarich 7 | spec: 8 | interval: 30m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: 3.6.1 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: dawarich 17 | maxHistory: 2 18 | install: 19 | createNamespace: true 20 | remediation: 21 | retries: 3 22 | upgrade: 23 | cleanupOnFail: true 24 | remediation: 25 | retries: 3 26 | uninstall: 27 | keepHistory: false 28 | values: 29 | controllers: 30 | dawarich: 31 | containers: 32 | app: 33 | image: 34 | repository: ghcr.io/bo0tzz/dawarkitty 35 | tag: 0.1.4 36 | env: 37 | RUST_LOG: trace 38 | RUST_BACKTRACE: full 39 | envFrom: 40 | - secret: dawarkitty-secret -------------------------------------------------------------------------------- /apps/dawarich/helm-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s-charts 5 | namespace: dawarich 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /apps/dawarich/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: dawarich 5 | -------------------------------------------------------------------------------- /apps/db-static.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: db-static-conf 5 | namespace: applications 6 | data: 7 | nginx.conf: | 8 | server { 9 | listen 80; 10 | listen [::]:80; 11 | server_name localhost; 12 | 13 | root /var/www/public_files; 14 | 15 | error_page 500 502 503 504 /50x.html; 16 | location = /50x.html { 17 | root /usr/share/nginx/html; 18 | } 19 | } 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: db-static-files 25 | namespace: applications 26 | data: 27 | index.html: | 28 | 29 | 30 | 31 | DB 32 | 33 | 34 | 35 | 36 |

Plakplaatsen Leiden

37 |

Kolokaart NL

38 | 39 | 40 | 41 | plakplaatsen.html: | 42 | 43 | 44 | 45 | Plakplaatsen Leiden 46 | 48 | 50 | 51 | 52 | 53 | 54 |

Vrije plakplaatsen in Leiden

55 | 56 |
57 | 97 | 98 | 99 | 100 | kolokaart.html: | 101 | 102 | 103 | 104 | Kolokaart NL 105 | 107 | 109 | 110 | 111 | 112 | 113 |

Kolokaart NL

114 |
115 | 182 | 183 | 184 | 185 | 186 | --- 187 | apiVersion: apps/v1 188 | kind: Deployment 189 | metadata: 190 | name: db-static 191 | namespace: applications 192 | spec: 193 | selector: 194 | matchLabels: 195 | app: db-static 196 | replicas: 1 197 | template: 198 | metadata: 199 | labels: 200 | app: db-static 201 | spec: 202 | containers: 203 | - name: db-static 204 | image: nginx:1.28.0 205 | ports: 206 | - containerPort: 80 207 | volumeMounts: 208 | - mountPath: /etc/nginx/conf.d 209 | name: db-static-conf 210 | readOnly: true 211 | - mountPath: /var/www/public_files 212 | name: db-static-files 213 | readOnly: true 214 | volumes: 215 | - name: db-static-conf 216 | configMap: 217 | name: db-static-conf 218 | - name: db-static-files 219 | configMap: 220 | name: db-static-files 221 | --- 222 | apiVersion: v1 223 | kind: Service 224 | metadata: 225 | labels: 226 | service: db-static-web 227 | name: db-static-web 228 | namespace: applications 229 | spec: 230 | ports: 231 | - name: "http" 232 | port: 80 233 | targetPort: 80 234 | selector: 235 | app: db-static 236 | --- 237 | apiVersion: networking.k8s.io/v1 238 | kind: Ingress 239 | metadata: 240 | name: db-static-web 241 | namespace: applications 242 | annotations: 243 | kubernetes.io/ingress.class: nginx 244 | cert-manager.io/cluster-issuer: letsencrypt-prod 245 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 246 | spec: 247 | tls: 248 | - hosts: 249 | - db.bo0tzz.me 250 | secretName: db-web-tls 251 | rules: 252 | - host: db.bo0tzz.me 253 | http: 254 | paths: 255 | - path: / 256 | pathType: Prefix 257 | backend: 258 | service: 259 | name: db-static-web 260 | port: 261 | name: http 262 | -------------------------------------------------------------------------------- /apps/esphome/esphome.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 3 | kind: HelmRelease 4 | metadata: 5 | name: esphome 6 | namespace: applications 7 | spec: 8 | interval: 30m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: 1.3.1 13 | interval: 30m 14 | sourceRef: 15 | kind: HelmRepository 16 | name: bjw-s-charts 17 | namespace: applications 18 | values: 19 | image: 20 | repository: esphome/esphome 21 | tag: 2025.5.0 22 | 23 | # App needs to run as root because of this: https://github.com/esphome/issues/issues/2752 24 | securityContext: 25 | runAsNonRoot: false 26 | readOnlyRootFilesystem: false 27 | privileged: true 28 | allowPrivilegeEscalation: true 29 | 30 | env: 31 | ESPHOME_DASHBOARD_USE_PING: true 32 | 33 | service: 34 | main: 35 | ports: 36 | http: 37 | port: 6052 38 | 39 | ingress: 40 | main: 41 | enabled: true 42 | annotations: 43 | kubernetes.io/ingress.class: nginx-internal 44 | cert-manager.io/cluster-issuer: letsencrypt-prod 45 | hosts: 46 | - host: esphome.bo0tzz.me 47 | paths: 48 | - path: / 49 | pathType: Prefix 50 | tls: 51 | - hosts: 52 | - esphome.bo0tzz.me 53 | secretName: esphome-web-tls 54 | 55 | persistence: 56 | config: 57 | enabled: true 58 | existingClaim: esphome-config 59 | -------------------------------------------------------------------------------- /apps/esphome/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: esphome-config 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 1Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: jitsi 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | url: https://jitsi-contrib.github.io/jitsi-helm/ 9 | --- 10 | apiVersion: source.toolkit.fluxcd.io/v1beta1 11 | kind: HelmRepository 12 | metadata: 13 | name: minecraft 14 | namespace: applications 15 | spec: 16 | interval: 1h 17 | url: https://itzg.github.io/minecraft-server-charts/ 18 | --- 19 | apiVersion: source.toolkit.fluxcd.io/v1beta2 20 | kind: HelmRepository 21 | metadata: 22 | name: bjw-s-charts 23 | namespace: applications 24 | spec: 25 | interval: 1h 26 | url: https://bjw-s-labs.github.io/helm-charts/ 27 | --- 28 | apiVersion: source.toolkit.fluxcd.io/v1beta2 29 | kind: HelmRepository 30 | metadata: 31 | name: gabe565 32 | namespace: applications 33 | spec: 34 | interval: 1h 35 | url: https://charts.gabe565.com 36 | -------------------------------------------------------------------------------- /apps/homepage/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: homepage 5 | namespace: applications 6 | labels: 7 | app: homepage 8 | spec: 9 | strategy: 10 | type: Recreate 11 | selector: 12 | matchLabels: 13 | app: homepage 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | app: homepage 19 | spec: 20 | containers: 21 | - name: homepage 22 | image: ghcr.io/bo0tzz/homepage:main@sha256:c9b670faf8e86f1f126b66be2c6e6a2921e31072e24447bd8a93e15d863569ff 23 | imagePullPolicy: Always 24 | ports: 25 | - containerPort: 4000 26 | envFrom: 27 | - secretRef: 28 | name: homepage-secret 29 | resources: 30 | requests: 31 | cpu: 20m 32 | memory: 200M 33 | -------------------------------------------------------------------------------- /apps/homepage/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | data: 4 | SECRET_KEY_BASE: ENC[AES256_GCM,data:rZYQFv3JL7SPh6cuZgYh7gOAYqP99cXv/0/B+40MYXJJrm7rPbsZ92uklA08XoT41ENEr1AfVnyt4RjAmpPnDfB2UMBLjwF9xC65iDy+52OPF3Ou+luGC+rjbvthwa+5P/mymUwWooHO80GC,iv:KN+8TgB3bPlbH6J0vY4REL0+0KR5pugx0riLUVf6RJQ=,tag:xtXBA2Am2CWaFWDHiyDmIQ==,type:str] 5 | metadata: 6 | name: homepage-secret 7 | namespace: applications 8 | sops: 9 | kms: [] 10 | gcp_kms: [] 11 | azure_kv: [] 12 | hc_vault: [] 13 | age: [] 14 | lastmodified: "2022-06-21T12:30:57Z" 15 | mac: ENC[AES256_GCM,data:zgjlFlyLTnLACV7/oRrsbrDdcJA4/J9cf8nL0inSYFQ2fLUZ3+Elz5HUtMXyosPRRyeS9Jr3GCZ7iHQe3JeR/IvfMQVbmg2vtgUBUOT/aMh40Jyk3TxaiMdzoW8k+/fOWMsSNdZ5wGZgfD2n6GTA8FHATOlCzEnnQX8/qyuBxZo=,iv:IAf/zNqq+FXdTX+7QwisB9XTi3eeO+UgZzGh4HXqoJQ=,tag:ASlzcAEGB/y715vciKfcHQ==,type:str] 16 | pgp: 17 | - created_at: "2022-06-21T12:30:56Z" 18 | enc: | 19 | -----BEGIN PGP MESSAGE----- 20 | 21 | hQIMA2YE/I5Bjk+6AQ/+KF3Qd6i12G0Usb2PfnafVjSvNFuMdtbioan//EtnHUlU 22 | Wyo6V9FW1SK8ioxzCCqfJV+hZx1luUxmpL/yCWXqckSxyBbfDXPi4hh/Z5hMozc3 23 | JsMl2kN1UmvhHlrcexPgfWlL/3A7B1zMIYYc5XivtSU2thuBTM8xMFinJ9xKTrE3 24 | 5gkK3Ur2551rm/APs2+p8YZPN3tL/+U54cY0QnesTXWtW5yuHjHXGgYqEckCq8YU 25 | M9x+n0DbcYD0A6sPc3UKSu05HG1iIlaM+5SLUvjdvFsiF7cwY6z1QauYVDG3y4F6 26 | MWS8Py/tfFpBPV1ZANQCemGc/Cf1uS/6PrBxclgw8Gy6qblwCQGvDVK4CCDxbyi1 27 | 0YqxWOctkl64isK8Mleh7HSa9GE9J/BNMOOsOOlwbuTHdDnqfc1d+2xjBnax8ntX 28 | Om10ZZrImr0dUU6DgeYW+8UJWd5wSVUQkqeSjiBd0jNMUZRJSbQpudZAhp0s2dLO 29 | ZXCxl9TlK6frd113UdgmU7yFWbk9BohR4JMlE/zQOz1vJD/mNu1mOxjfJpt3iEpl 30 | CNV/z22f7KIWZkhmGqwXBIVb6vxErSnD3+/cbijiRXiCmWENrhO+9W3jw+tL0zex 31 | 88Y846f2lQAzdydcNdEhno8sArTULuwL+XHHvu8mE3F1Q/jAqKbdsWMW+y6nWsvU 32 | aAEJAhBO/GAvxRQzYENCNEZyFfg+G5ykPqnLSnvaBtR1mdi6ZmPpO7U5P7inDDJ5 33 | i5hSWvZRQevw+8CDG05BHQhmm7V2fs9PrGoqpFZoFZM9e5Pitq9EfQS4XIf0p6ka 34 | fZJLi5nMWKcD 35 | =fqGJ 36 | -----END PGP MESSAGE----- 37 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 38 | encrypted_regex: ^(data|stringData)$ 39 | version: 3.7.3 40 | -------------------------------------------------------------------------------- /apps/homepage/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | service: homepage 6 | name: homepage 7 | namespace: applications 8 | spec: 9 | ports: 10 | - name: "http" 11 | port: 80 12 | targetPort: 4000 13 | selector: 14 | app: homepage 15 | --- 16 | apiVersion: networking.k8s.io/v1 17 | kind: Ingress 18 | metadata: 19 | name: homepage 20 | namespace: applications 21 | annotations: 22 | kubernetes.io/ingress.class: nginx 23 | cert-manager.io/cluster-issuer: letsencrypt-prod 24 | external-dns.alpha.kubernetes.io/target: zijlein.de 25 | spec: 26 | tls: 27 | - hosts: 28 | - bo0tzz.me 29 | secretName: homepage-web-tls 30 | rules: 31 | - host: bo0tzz.me 32 | http: 33 | paths: 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: homepage 39 | port: 40 | name: http 41 | -------------------------------------------------------------------------------- /apps/imagebot/backup/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: imagebot-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: imagebot-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: imagebot-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/imagebot/backup/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: imagebot-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/imagebot" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/imagebot/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: imagebot 5 | namespace: applications 6 | labels: 7 | app: imagebot 8 | spec: 9 | strategy: 10 | type: Recreate 11 | selector: 12 | matchLabels: 13 | app: imagebot 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | app: imagebot 19 | spec: 20 | securityContext: 21 | runAsUser: 65534 22 | runAsGroup: 65534 23 | fsGroup: 65534 24 | fsGroupChangePolicy: "OnRootMismatch" 25 | volumes: 26 | - name: data 27 | persistentVolumeClaim: 28 | claimName: imagebot-data 29 | dnsConfig: 30 | options: 31 | - name: ndots 32 | value: "1" 33 | containers: 34 | - name: imagebot 35 | image: ghcr.io/bo0tzz/image_bot:main 36 | imagePullPolicy: Always 37 | envFrom: 38 | - secretRef: 39 | name: imagebot-token 40 | env: 41 | - name: KEY_DB_PATH 42 | value: "/data/keys.db" 43 | volumeMounts: 44 | - name: data 45 | mountPath: /data 46 | resources: 47 | requests: 48 | cpu: 20m 49 | memory: 200M 50 | -------------------------------------------------------------------------------- /apps/imagebot/pvc.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: imagebot-data 5 | namespace: applications 6 | spec: 7 | storageClassName: zfs-iscsi 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 512Mi -------------------------------------------------------------------------------- /apps/imagebot/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: imagebot-token 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | BOT_TOKEN: ENC[AES256_GCM,data:Io1rn8587Hhv3ew/2U65PYbSdr2+KN6qr+z11DwydwQtC2gqs62i5FYJuDG7,iv:Pkn/kwylNt8Rc9zgAQwqLo5ZoH3jQHJ3nyCZrMkzTOw=,tag:sWAe+J6Z4jmvg1aKmC3Djg==,type:str] 9 | sops: 10 | kms: [] 11 | gcp_kms: [] 12 | azure_kv: [] 13 | hc_vault: [] 14 | age: [] 15 | lastmodified: "2022-06-23T13:53:26Z" 16 | mac: ENC[AES256_GCM,data:oMAQG9TEYZOjFzNnGUsCzjnBfOmkNkk7IUYwTR9OJ/I1gVzzKz4hbWwIpxTUpAtOOqUsIMYVAvaQog2xNOnHPOi0HISPO0zAS1BCZChRHgtYKzb1BzTfMoE/wV1cJfj9uStlXii6DOaYu8rUed5vs9tZRCVqGjrkrl8OmWeiR80=,iv:uQQ6pscriTC56E3l8oy+QwUcy+ABn+p7nXsKeG4EdFA=,tag:gagQp405pDEn8a+Al/pyWA==,type:str] 17 | pgp: 18 | - created_at: "2022-06-23T13:53:25Z" 19 | enc: | 20 | -----BEGIN PGP MESSAGE----- 21 | 22 | hQIMA2YE/I5Bjk+6AQ//T94GDBITaEYJGg6RNeLBnx+4D263h5JUpR48ZsN4AgLn 23 | zkZOOEpGOosvIHDHgdohkOFl0d5AIRPZpoyTQv0KSYMYMjsDennry+hPb08lIfe8 24 | jLX7TR6VaHt+TdW6qhbLeC4BolTMnBAa+cw9KA/Ka2OJeu1sn2Xl00C/mAPpgD98 25 | yK5BnsMPc8qcMOtIGCklHvf5k4w0pBFA1NexHhYKU9wuwhGsSlewJiC4g7dXs7df 26 | nE6JscyHpZK9iGrjOyVlwXvTaE7o37SJYDSjUZJRLRNYXWtYTC8VEnCaD1Px+QCf 27 | vCIC93G2d/mDNc7Oj9BG4/5IeTxto5U+iBhWXvGKZFoN6ri36QsX9zuEm5Nddv9V 28 | Uaf3QRgh0JKId1dd3TntKEK6pFjUDWJ2bLv98u59XzNrL1YcSjno01KDQBYZ7roj 29 | 3agv1qojnToiMOSYrGSG939prDoyMBFeWwTkgJpbZE1Vw/RNRNADVXxDZRYuj9of 30 | ZSzvWXH9aqEDIkSOsMFdFEUuIdeGLSlJ3QUVlaOfyReuCMMpeRyDJ/2hPZZtdFmk 31 | yC2hSR8bjo1sKQPi0j1MhTpstjY50hMWfNZOoHvgP4O2D/KXKwAk5tm7s9EYLwFa 32 | zGijFXgAwS+4bmJIQ8ZX1qjgeKA6s9s1u5mI0YNIq1TqTrdO7amB5Yeg9xIZrv/U 33 | aAEJAhDDWbPqfUuSy0mYgL/UnBEBsRlro6QBrfsiyhGciCJTcRjOqCnsJlC/rfdt 34 | 5S7I4PNgSDcpKG+BMLJcBGecRBho9SdXWq2dAotBlnJwse5VqaG3rtuboWkvMcDc 35 | fh/DHy4nL/bt 36 | =byp9 37 | -----END PGP MESSAGE----- 38 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.7.3 41 | -------------------------------------------------------------------------------- /apps/immich/backup/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: immich-backup 5 | namespace: immich 6 | spec: 7 | sourcePVC: photo-library 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: immich-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 2 17 | copyMethod: Direct 18 | cacheStorageClassName: zfs-iscsi 19 | cacheAccessModes: ["ReadWriteOnce"] 20 | -------------------------------------------------------------------------------- /apps/immich/backup/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: immich-restic-secret 5 | namespace: immich 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/immich" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/immich/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: immich-db 5 | namespace: immich 6 | spec: 7 | database: immich 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: immich-user 13 | namespace: immich 14 | spec: 15 | role: immich 16 | database: immich-db 17 | secretName: database 18 | privileges: OWNER -------------------------------------------------------------------------------- /apps/immich/helm-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: immich-charts 5 | namespace: immich 6 | spec: 7 | interval: 1h 8 | url: https://immich-app.github.io/immich-charts 9 | -------------------------------------------------------------------------------- /apps/immich/immich.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: immich 5 | namespace: immich 6 | spec: 7 | interval: 5m 8 | chart: 9 | spec: 10 | chart: immich 11 | version: 0.9.3 12 | sourceRef: 13 | kind: HelmRepository 14 | name: immich-charts 15 | namespace: immich 16 | interval: 1m 17 | upgrade: 18 | remediation: 19 | retries: 3 20 | values: 21 | postgres: 22 | enabled: false 23 | 24 | redis: 25 | enabled: true 26 | 27 | immich: 28 | metrics: 29 | enabled: true 30 | persistence: 31 | library: 32 | existingClaim: photo-library 33 | 34 | env: 35 | MACHINE_LEARNING_PRELOAD__CLIP: "ViT-H-14-378-quickgelu__dfn5b" 36 | DB_HOSTNAME: 37 | valueFrom: 38 | secretKeyRef: 39 | name: database-immich-user 40 | key: HOST 41 | DB_USERNAME: 42 | valueFrom: 43 | secretKeyRef: 44 | name: database-immich-user 45 | key: LOGIN 46 | DB_PASSWORD: 47 | valueFrom: 48 | secretKeyRef: 49 | name: database-immich-user 50 | key: PASSWORD 51 | DB_DATABASE_NAME: 52 | valueFrom: 53 | secretKeyRef: 54 | name: database-immich-user 55 | key: DATABASE_NAME 56 | LOG_LEVEL: verbose 57 | TZ: Europe/Amsterdam 58 | 59 | image: 60 | # renovate: datasource=github-releases depName=immich-app/immich 61 | tag: "v1.134.0" 62 | 63 | server: 64 | resources: 65 | requests: 66 | cpu: 1500m 67 | memory: 2048M 68 | ingress: 69 | main: 70 | enabled: true 71 | annotations: 72 | kubernetes.io/ingress.class: nginx 73 | cert-manager.io/cluster-issuer: letsencrypt-prod 74 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 75 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 76 | hosts: 77 | - host: photos.bo0tzz.me 78 | paths: 79 | - path: / 80 | pathType: Prefix 81 | tls: 82 | - hosts: 83 | - photos.bo0tzz.me 84 | secretName: immich-web-tls 85 | 86 | machine-learning: 87 | resources: 88 | requests: 89 | cpu: 500m 90 | memory: 4096M 91 | persistence: 92 | cache: 93 | type: pvc 94 | existingClaim: immich-machine-learning-cache 95 | -------------------------------------------------------------------------------- /apps/immich/ml-cache.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: immich-machine-learning-cache 5 | namespace: immich 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 10Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/immich/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: immich 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /apps/immich/photo-library.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: photo-library 5 | namespace: immich 6 | spec: 7 | storageClassName: manual 8 | capacity: 9 | storage: 1T 10 | accessModes: 11 | - ReadWriteMany 12 | nfs: 13 | server: 192.168.2.1 14 | path: "/rpool/media/photos/library" 15 | --- 16 | apiVersion: v1 17 | kind: PersistentVolumeClaim 18 | metadata: 19 | name: photo-library 20 | namespace: immich 21 | spec: 22 | storageClassName: manual 23 | volumeName: photo-library 24 | accessModes: 25 | - ReadWriteMany 26 | resources: 27 | requests: 28 | storage: 1T -------------------------------------------------------------------------------- /apps/kobotools.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: &app kobotools 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 1.2.0 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | values: 17 | controller: 18 | replicas: 1 19 | strategy: RollingUpdate 20 | 21 | image: 22 | repository: ghcr.io/bo0tzz/kobo-tools 23 | tag: main 24 | pullPolicy: Always 25 | service: 26 | main: 27 | ports: 28 | http: 29 | port: &port 3000 30 | 31 | ingress: 32 | main: 33 | enabled: true 34 | annotations: 35 | kubernetes.io/ingress.class: nginx 36 | cert-manager.io/cluster-issuer: letsencrypt-prod 37 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 38 | hosts: 39 | - host: &host kobo-tools.bo0tzz.me 40 | paths: 41 | - path: / 42 | pathType: Prefix 43 | tls: 44 | - hosts: 45 | - *host 46 | secretName: kobo-tools-web-tls 47 | -------------------------------------------------------------------------------- /apps/libreddit.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: &app libreddit 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 1.2.0 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | values: 17 | controller: 18 | replicas: 1 19 | strategy: RollingUpdate 20 | 21 | image: 22 | repository: quay.io/redlib/redlib 23 | tag: latest@sha256:8c6c56472380188edc8dcd15b1a8e6741281635446b95c6ef1222f9940a96d93 24 | 25 | dnsConfig: 26 | options: 27 | - name: ndots 28 | value: "1" 29 | service: 30 | main: 31 | ports: 32 | http: 33 | port: &port 8080 34 | 35 | ingress: 36 | main: 37 | enabled: true 38 | annotations: 39 | kubernetes.io/ingress.class: nginx-internal 40 | cert-manager.io/cluster-issuer: letsencrypt-prod 41 | hosts: 42 | - host: &host libreddit.bo0tzz.me 43 | paths: 44 | - path: / 45 | pathType: Prefix 46 | tls: 47 | - hosts: 48 | - *host 49 | secretName: libreddit-web-tls 50 | 51 | probes: 52 | liveness: &probes 53 | enabled: true 54 | custom: true 55 | spec: 56 | httpGet: 57 | path: /settings 58 | port: *port 59 | initialDelaySeconds: 0 60 | periodSeconds: 10 61 | timeoutSeconds: 1 62 | failureThreshold: 3 63 | readiness: *probes 64 | startup: 65 | enabled: false 66 | 67 | resources: 68 | requests: 69 | cpu: 5m 70 | memory: 50Mi 71 | -------------------------------------------------------------------------------- /apps/minecraft.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: minecraft 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: minecraft 11 | version: '4.26.3' 12 | sourceRef: 13 | kind: HelmRepository 14 | name: minecraft 15 | namespace: applications 16 | interval: 1h 17 | values: 18 | fullnameOverride: minecraft-minecraft 19 | image: 20 | pullPolicy: Always 21 | resources: 22 | requests: 23 | cpu: 1 24 | memory: 4G 25 | limits: 26 | memory: 4G 27 | minecraftServer: 28 | eula: "TRUE" 29 | version: "1.21.4" 30 | whitelist: Dylan_rengers,bo0tzz 31 | ops: Dylan_rengers,bo0tzz 32 | maxWorldSize: 29999984 33 | spawnProtection: 0 34 | pvp: true 35 | memory: 3000M 36 | serviceType: LoadBalancer 37 | loadBalancerIP: 192.168.4.103 38 | rcon: 39 | enabled: true 40 | type: "FABRIC" 41 | modrinth: 42 | projects: ["worldedit"] 43 | persistence: 44 | dataDir: 45 | enabled: true 46 | storageClass: zfs-iscsi 47 | Size: 5G 48 | -------------------------------------------------------------------------------- /apps/miniflux/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: miniflux-db 5 | namespace: applications 6 | spec: 7 | database: miniflux 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: miniflux-user 13 | namespace: applications 14 | spec: 15 | role: miniflux 16 | database: miniflux-db 17 | secretName: database 18 | privileges: OWNER 19 | -------------------------------------------------------------------------------- /apps/miniflux/miniflux.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: miniflux 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 1.3.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | interval: 1h 17 | values: 18 | image: 19 | repository: ghcr.io/miniflux/miniflux 20 | tag: 2.2.9 21 | service: 22 | main: 23 | ports: 24 | http: 25 | port: 8080 26 | envFrom: 27 | - secretRef: 28 | name: miniflux-secret 29 | env: 30 | BASE_URL: https://feed.bo0tzz.me 31 | POLLING_PARSING_ERROR_LIMIT: 0 32 | POLLING_SCHEDULER: entry_frequency 33 | RUN_MIGRATIONS: 1 34 | CREATE_ADMIN: 1 35 | ADMIN_USERNAME: boet 36 | OAUTH2_PROVIDER: oidc 37 | OAUTH2_REDIRECT_URL: https://feed.bo0tzz.me/oauth2/oidc/callback 38 | OAUTH2_OIDC_DISCOVERY_ENDPOINT: https://auth.bo0tzz.me/application/o/miniflux/ 39 | OAUTH2_USER_CREATION: 1 40 | DATABASE_URL: 41 | valueFrom: 42 | secretKeyRef: 43 | name: database-miniflux-user 44 | key: POSTGRES_URL 45 | ingress: 46 | main: 47 | enabled: true 48 | annotations: 49 | kubernetes.io/ingress.class: nginx 50 | cert-manager.io/cluster-issuer: letsencrypt-prod 51 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 52 | hosts: 53 | - host: feed.bo0tzz.me 54 | paths: 55 | - path: / 56 | pathType: Prefix 57 | tls: 58 | - hosts: 59 | - feed.bo0tzz.me 60 | secretName: miniflux-web-tls 61 | resources: 62 | requests: 63 | cpu: 200m 64 | memory: 150M 65 | -------------------------------------------------------------------------------- /apps/miniflux/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | ADMIN_PASSWORD: ENC[AES256_GCM,data:BnbEXjpHkTdFcXaQWTrELKV+QM0tqRDrAK+5x8oYmNuw0CCmXmOCAyvBlGQ=,iv:vK7Gtx0i/MOCX8QZXZV3ar8mcOKHMpi70mVQQwMrO8E=,tag:CsCMBPB0MAG0rhLBImci+g==,type:str] 4 | OAUTH2_CLIENT_ID: ENC[AES256_GCM,data:4NuHTxjP4BVX3b0N/Q9yOen8OPbBBrIijK+FssDr4F4hiIrFSI6yI5nz6GqcBsC9r5l0Yi8Rggk=,iv:ypwePEldemWZRWRyJnWml8MYJvJXCH/0I+DH3aiQrHY=,tag:dhOsqjfkhlh/2rvK5j6SoA==,type:str] 5 | OAUTH2_CLIENT_SECRET: ENC[AES256_GCM,data:zj6v1GyNxeESThgN3O6AGqrViQqeg4uzNvd6ryOGlEEMjmbO3JmujeJVtmj4hUJ4xlfjXzO0qRJBAY7oa7I4ux0MhViXVJDhJbSjE5Vb4ckopDKECTbjac1O1zsHb9YfF19m0kCgMT2/DiKLbAq1gWhowz0T7btuoPVeojZ3BOqnbT2pqFQt8NA0RJgBimgaHeMUAhtuNzDZNNUnavrGlCzJJZFZ/2Kf7w3M6w==,iv:XkvyjjDxpb+k9qpLO1uGHjrY/sow0ipvidcMKS+XVZ4=,tag:rA0x+6vZuGedQTjG0cz7IQ==,type:str] 6 | kind: Secret 7 | metadata: 8 | creationTimestamp: null 9 | name: miniflux-secret 10 | namespace: applications 11 | sops: 12 | kms: [] 13 | gcp_kms: [] 14 | azure_kv: [] 15 | hc_vault: [] 16 | age: [] 17 | lastmodified: "2023-09-16T18:53:29Z" 18 | mac: ENC[AES256_GCM,data:AGLVBIRc4AjDHb8dLAJiCVMmxw8XfRm94M8jo4ruls/enocXqgNHHy0D67BPlkn3g7PRLHUWcIiwwf/q/S1dnd1/A7otzMxy1tkhfmJHLOeBVqR9JOAaIc2Y7fNpkR4dyiLT28UcN9MPPuy1Uk7NcODBoZwPkp4KFh+uf58h06Y=,iv:uj6E6L054Vbt8tt9yp/KlaE+AJ/vh/6Z8b1q7pgz3p0=,tag:sve7OF9ef5e7GWEkgadJ4g==,type:str] 19 | pgp: 20 | - created_at: "2022-06-12T13:12:52Z" 21 | enc: | 22 | -----BEGIN PGP MESSAGE----- 23 | 24 | hQIMA2YE/I5Bjk+6AQ//fSmjf/apK7yWa71RLSOJT9+HIPvinA09jxVX/aWKM+My 25 | CoWgVq/3CvkSdxzUq3UnxtwOQson0yIgE/6jmIkslVJv6T87AmNGO8GZ5yvCtxCD 26 | h1Dd6vth/G+jeYgFNXWUqrL2dEsPV8L0xF5ArMIsu99HDMVXvTia0lHEvwKSzt9d 27 | G14gryqr1aukFz7ieKMI4oHEs4huXXNPH4br6IMLhD5Y61G5FdGSHZ6ziL0roikr 28 | jgrB5ry0Vw075mRPCM2kkREhlxl+6WEs3GU7BzFunZ2311zKbLFIgSt4Zuqciqti 29 | u0iXMnmWfirSucuK2PRIGojvlgKYa7pYOPI6FcPc/G1VkBQ3mwNFTn6pC89HzUF3 30 | NGVHE30+EP7tyFLBA+nSYYtLgmgNTp0imDid1TUIFjjzDHW9dRqWaXVg2Ro2wdBr 31 | oazwhFaqJtK54H3QfRyHJ0vc2JFevwrcthNuEJZ1DEQkB0S3QGYoqPUAf4Mw3q6b 32 | hwgoXhsYpRt6R8oVpKGCsqbTF2gejIlrwMMHDoDgnLRoJatenQi94FNZ+mUsrD7I 33 | u1hRmiOjUqS+rU9cht6/P+cbU0Dr4Lp5UZCfr5pFsNUwOzAECxmNJwSKpOxeVfTc 34 | lHYcSM43FFhxE+cQH6xlgkieeuk+wIJYNQNFfIEnP2gscmOf7dyYj7yZSqhVY83U 35 | aAEJAhCK36B8s+/v2m8dbtXqspn8V7UcnT5OJJIiEC0reIeM1fHFr3vICFFQxaX+ 36 | 1ZSGAsalEyzPFP0ZpfgNCGBGTfCyvzYgJh4foENIV2wuv1hFx+tPS2K58H8I4Yhh 37 | uw2Ru9QRASiI 38 | =v6J6 39 | -----END PGP MESSAGE----- 40 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 41 | encrypted_regex: ^(data|stringData)$ 42 | version: 3.7.3 43 | -------------------------------------------------------------------------------- /apps/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: applications 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /apps/paperless/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: paperless-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/paperless" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/paperless/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: paperless-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: paperless-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: paperless-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/paperless/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: paperless-db 5 | namespace: applications 6 | spec: 7 | database: paperless 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: paperless-user 13 | namespace: applications 14 | spec: 15 | role: paperless 16 | database: paperless-db 17 | secretName: database 18 | privileges: OWNER -------------------------------------------------------------------------------- /apps/paperless/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: paperless 5 | namespace: applications 6 | spec: 7 | interval: 30m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.2.1 12 | interval: 30m 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: applications 17 | 18 | values: 19 | controllers: 20 | paperless: 21 | containers: 22 | app: 23 | image: 24 | repository: ghcr.io/paperless-ngx/paperless-ngx 25 | tag: 2.16.2 26 | env: 27 | PAPERLESS_URL: https://paperless.bo0tzz.me 28 | PAPERLESS_TIME_ZONE: "Europe/Amsterdam" 29 | PAPERLESS_APPS: allauth.socialaccount.providers.openid_connect 30 | PAPERLESS_ACCOUNT_EMAIL_VERIFICATION: none 31 | PAPERLESS_SOCIAL_AUTO_SIGNUP: true 32 | PAPERLESS_OCR_USER_ARGS: '{"invalidate_digital_signatures": true}' 33 | # Database 34 | PAPERLESS_DBENGINE: postgresql 35 | PAPERLESS_DBHOST: 36 | valueFrom: 37 | secretKeyRef: 38 | name: database-paperless-user 39 | key: HOST 40 | PAPERLESS_DBNAME: 41 | valueFrom: 42 | secretKeyRef: 43 | name: database-paperless-user 44 | key: DATABASE_NAME 45 | PAPERLESS_DBUSER: 46 | valueFrom: 47 | secretKeyRef: 48 | name: database-paperless-user 49 | key: LOGIN 50 | PAPERLESS_DBPASS: 51 | valueFrom: 52 | secretKeyRef: 53 | name: database-paperless-user 54 | key: PASSWORD 55 | # Configure folders 56 | PAPERLESS_CONSUMPTION_DIR: /data/incoming 57 | PAPERLESS_DATA_DIR: /data/data 58 | PAPERLESS_EXPORT_DIR: /data/export 59 | PAPERLESS_MEDIA_ROOT: /data/media 60 | # Configure OCR 61 | PAPERLESS_OCR_LANGUAGES: nld 62 | PAPERLESS_OCR_LANGUAGE: nld 63 | # Configure redis integration 64 | PAPERLESS_REDIS: redis://paperless-redis.applications.svc.cluster.local:6379 65 | envFrom: 66 | - secret: paperless-secret 67 | probes: 68 | liveness: 69 | enabled: true 70 | readiness: 71 | enabled: true 72 | startup: 73 | enabled: true 74 | spec: 75 | failureThreshold: 30 76 | periodSeconds: 5 77 | resources: 78 | requests: 79 | cpu: 25m 80 | memory: 2Gi 81 | 82 | redis: 83 | containers: 84 | redis: 85 | image: 86 | repository: docker.io/valkey/valkey 87 | tag: 8.1.1 88 | resources: 89 | requests: 90 | cpu: 5m 91 | memory: 32Mi 92 | 93 | service: 94 | app: 95 | controller: paperless 96 | ports: 97 | http: 98 | port: 8000 99 | redis: 100 | controller: redis 101 | ports: 102 | http: 103 | port: 6379 104 | 105 | ingress: 106 | app: 107 | annotations: 108 | kubernetes.io/ingress.class: nginx-internal 109 | cert-manager.io/cluster-issuer: letsencrypt-prod 110 | nginx.ingress.kubernetes.io/proxy-body-size: "50m" 111 | hosts: 112 | - host: &hostname paperless.bo0tzz.me 113 | paths: 114 | - path: / 115 | service: 116 | identifier: app 117 | port: http 118 | tls: 119 | - hosts: 120 | - *hostname 121 | secretName: paperless-tls 122 | 123 | persistence: 124 | data: 125 | existingClaim: paperless-data 126 | advancedMounts: 127 | paperless: 128 | app: 129 | - path: /data 130 | -------------------------------------------------------------------------------- /apps/paperless/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: paperless-secret 5 | namespace: applications 6 | stringData: 7 | PAPERLESS_SECRET_KEY: ENC[AES256_GCM,data:FFU93CGtsmTXLNxF37ymz0InCTOFcOlCAmtT9EAaAbeuNMDOjJ2kec8fKQ4=,iv:XHeyqwNfs9rVs1VpCTVeWEKHPOH/S7RfM0u1sSPhHQI=,tag:lvwD8OGXwDMuBeuOtjzF6w==,type:str] 8 | PAPERLESS_ADMIN_USER: ENC[AES256_GCM,data:kHwfr8g=,iv:M4zEhBEMhg0AnwNkNB8fYqssfnGuw3MI0WpJbdOS5ug=,tag:BoV+KLpzYA1mP/2j50BXeg==,type:str] 9 | PAPERLESS_ADMIN_PASSWORD: ENC[AES256_GCM,data:x5/OZv2+TJ27C2d0CDcQVQ==,iv:FGTNhPmwWI334jfh9C/K+hlMVHx5FDSFw7HLVd2dMM8=,tag:FU43VqXm5rQWYG74iInSzA==,type:str] 10 | PAPERLESS_SOCIALACCOUNT_PROVIDERS: ENC[AES256_GCM,data:Vr8EyjSqVoPzlGKj0eZ+UmEFBIKUHYGHZk0i5vy1t+7tSWis9hy7ZIeUyqMfcXDPDR1Y+2GRZhAss9XcwGqp504OR5ICQ49BcUjUsd6TxYYTw4P12gAmRsZGwXOUlPKq19KnFg2fmD+xKnWhZhyZj+34ry9gwfFs76zka9WmHp32q1R7Rnb2MVeNK0IifkSM0d2eHkq0DGwYMUL7QsJyYTWCJgtEwCNArDRWQAAmu3zQnAVeoCqNdMrySxjKdCJs91e2GRvQu9y2yT2u9zQmxmIW9/oes7Y5lsjU/9UiJVgbSl3FjQoZKxNz06yx5SoD8xXB9yvvvafimVIS9BPn2bK2lBmpeTgORyT4+aLXOmrj6IDaYSupfdMKk7lojkSGGOc22ZYJsHExeHIizkQwnt5Zq/zWERkS/bpc7kvKgWAbwGP40+vgpbEzMPlBwiejhl0Ge+XLqjzukwv0hiqOz3DXNXAKHogHemf6TDmbswq2An0/qAiAxhdlI+Q8T4HsHEeYiIIDP6g4dDdosWwnAAQnBbvwLuGnc97LZJkCMkanBG2NwFKpI4NL7HS+fC8raF1PULDNtZiFMKxsw+UoYrLTXY3rAKFglxc+gDi0fucrWSsm192yMDegQ/wAXlW5pVOJYcw3YboZ/j1Ghho=,iv:S38KAneVAEP+ai+6ap4UmUAUMr0OBsPr5PMzL5Sln3M=,tag:Mc1uM8qy3OXkSIEmNC8zfw==,type:str] 11 | sops: 12 | kms: [] 13 | gcp_kms: [] 14 | azure_kv: [] 15 | hc_vault: [] 16 | age: [] 17 | lastmodified: "2024-07-07T12:25:21Z" 18 | mac: ENC[AES256_GCM,data:awqw5XkpuNImK4YY3ntEncK6xa6jcKiQsLNcGbYOKAyqPhs295l3krZcZ1wF2MnhpUvBWPYGc4SX2WqBaDgzPH2BpR3EDdm6sEpnIbEss85vdTBF8nn+AEDAs7zVZeHQ4xsRBR8cZx5+SNq2tr8K1/ZCNcY4bbi2ierLlbLQ/7o=,iv:3vyY+j5Tw6vUgWHV1kQM5fQ8HM9JQVzyRMjjueo1x1U=,tag:MSFy0NUqq7OA5btir8I2tA==,type:str] 19 | pgp: 20 | - created_at: "2024-07-07T12:25:21Z" 21 | enc: |- 22 | -----BEGIN PGP MESSAGE----- 23 | 24 | hQIMA2YE/I5Bjk+6AQ/9GPe1KwCp5snFrFmEATHcUfqyM0EOndwnQZaxqtJ6G0Vc 25 | u/fV/0GFujLUKmna8+0mmE+mKIfXJuCUySrsMbInly6Kz36HQr0k94hCsZEmQEXW 26 | arl0I4HEXkdJE0ocsPHcM8qGd8+SV7wo4jm4gbtUC1SGx9jl5rSdPq57Bkpl8H5/ 27 | Z1tx4vXj7jLSHppiYr5/dlH2vjKPjnXC6ryNtnH+9HXbyihGpJ42JGxyHRWzXnLN 28 | a0yxh9OwxYRk1XxRGRvZtP9FRSamJl6HET9FgeN6HKCa0yRVzkAuscIuEg2sTt1U 29 | rTjxY+/a264H5ggyki9h3l0PwId/BYj+3YWyPB46PFPnokjg92nfkBbANnV/LRBu 30 | Fw7Nlyjd2Q++gSWHaJhCHP7abJWlK8g/qFh7Mzyh0BnGF9FUdPVK1ub9I/xnsE0P 31 | pRiYGRlBcO5FwKljaKBmAHqWmcbyrVpGFbNxIESZaosV8C0Fc5gpWiJ6t3BsyCja 32 | Nixo78V7i2rQvI2RH6UVjUqpz5r9yN25rqBdgNZU0zaBfyMs4FmbEYWRvZYAX8Fu 33 | fmg89FOvgib3WHQCZJDwe+/Jom6MbG3t4heJmSYHFjf3S0Emf4qXbRJfgo8jh5f3 34 | C7eaJxPgQuMpfDUGw3taoMuaO0quZemDaZXAMVQ2hrYE0A4HscqoXWrLAu22zinU 35 | ZgEJAhDJA/xhwUSJpCMauB8qXMpxflvbIV5hH72lzQXLD4wdq5Yrte7yPZaVAzep 36 | G6i52o6gtrRDDI3ApdlY+L2DtbnPy5K2nKOFXT7xdzREVJoTBgKeR9G9Wvyr0iPp 37 | Ua+XMgV1RA== 38 | =8Yte 39 | -----END PGP MESSAGE----- 40 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 41 | encrypted_regex: ^(data|stringData)$ 42 | version: 3.8.1 43 | -------------------------------------------------------------------------------- /apps/paperless/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: paperless-data 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 50Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/proxy/camera.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: camera 5 | namespace: applications 6 | spec: 7 | ports: 8 | - name: "http" 9 | protocol: TCP 10 | port: 80 11 | targetPort: 8765 12 | --- 13 | kind: Endpoints 14 | apiVersion: v1 15 | metadata: 16 | name: camera 17 | namespace: applications 18 | subsets: 19 | - addresses: 20 | - ip: 192.168.178.2 21 | ports: 22 | - port: 8765 23 | --- 24 | apiVersion: networking.k8s.io/v1 25 | kind: Ingress 26 | metadata: 27 | name: camera 28 | namespace: applications 29 | annotations: 30 | kubernetes.io/ingress.class: nginx 31 | cert-manager.io/cluster-issuer: letsencrypt-prod 32 | external-dns.alpha.kubernetes.io/exclude: true 33 | spec: 34 | tls: 35 | - hosts: 36 | - camera.zijlein.de 37 | secretName: camera-web-tls 38 | rules: 39 | - host: camera.zijlein.de 40 | http: 41 | paths: 42 | - path: / 43 | pathType: Prefix 44 | backend: 45 | service: 46 | name: camera 47 | port: 48 | name: http 49 | -------------------------------------------------------------------------------- /apps/radio/acars.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: acars 5 | namespace: radio 6 | spec: 7 | interval: 15m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: "3.7.0" 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: radio 16 | values: 17 | 18 | controllers: 19 | acarsdec: 20 | replicas: 0 21 | containers: 22 | acarsdec: 23 | image: 24 | repository: ghcr.io/sdr-enthusiasts/docker-acarsdec 25 | tag: latest-build-412 26 | env: 27 | FEED_ID: BO0TZZ-ACARS-1 28 | TZ: Europe/Amsterdam 29 | SOAPYSDR: driver=rtlsdr 30 | # FREQUENCIES: "131.550;131.725" 31 | # Enabling all frequencies to determine which are actually used 32 | # RTL-SDR can only scan 2MHz range 33 | # See https://app.airframes.io/about 34 | FREQUENCIES: >- 35 | 130.025;130.425;130.450;130.825;130.850;131.125;131.425; 36 | 131.450;131.475;131.525;131.550;131.725;131.825;131.850 37 | OUTPUT_SERVER: acars-acarsrouter 38 | OUTPUT_SERVER_PORT: "5550" 39 | OUTPUT_SERVER_MODE: tcp 40 | resources: 41 | requests: 42 | cpu: 150m 43 | memory: 128Mi 44 | limits: 45 | memory: 256Mi 46 | squat.ai/rtlsdr: 1 47 | 48 | dumpvdl2: 49 | replicas: 1 50 | containers: 51 | dumpvdl2: 52 | securityContext: 53 | privileged: true 54 | image: 55 | repository: ghcr.io/sdr-enthusiasts/docker-dumpvdl2 56 | tag: latest-build-348 57 | env: 58 | FEED_ID: BO0TZZ-VDL2-1 59 | TZ: Etc/UTC 60 | SOAPYSDR: driver=rtlsdr 61 | FREQUENCIES: "136.675;136.725;136.775;136.825;136.875;136.975" 62 | ZMQ_MODE: server 63 | ZMQ_ENDPOINT: tcp://0.0.0.0:45555 64 | resources: 65 | requests: 66 | cpu: 10m 67 | memory: 128Mi 68 | limits: 69 | memory: 256Mi 70 | squat.ai/rtlsdr: 1 71 | 72 | acarsrouter: 73 | replicas: 1 74 | containers: 75 | acarsrouter: 76 | image: 77 | repository: ghcr.io/sdr-enthusiasts/acars_router 78 | tag: 1.3.1_linux_amd64 79 | env: 80 | TZ: Etc/UTC 81 | AR_SEND_UDP_ACARS: acars-acarshub:5550;feedthe.acarsdrama.com:5550 82 | AR_SEND_UDP_VDLM2: acars-acarshub:5555;feedthe.acarsdrama.com:5555 83 | AR_RECV_ZMQ_VDLM2: acars-dumpvdl2:45555 84 | resources: 85 | requests: 86 | cpu: 10m 87 | memory: 128Mi 88 | limits: 89 | memory: 256Mi 90 | 91 | acarshub: 92 | replicas: 1 93 | type: statefulset 94 | containers: 95 | acarshub: 96 | image: 97 | repository: ghcr.io/sdr-enthusiasts/docker-acarshub 98 | tag: v3.8.0Build1379_nohealthcheck 99 | env: 100 | TZ: Europe/Amsterdam 101 | ENABLE_ADSB: "false" 102 | # ENABLE_ACARS: external 103 | ENABLE_VDLM: external 104 | QUIET_MESSAGES: "false" # This logs the messages themselves 105 | resources: 106 | requests: 107 | cpu: 10m 108 | memory: 128Mi 109 | limits: 110 | memory: 512Mi 111 | 112 | persistence: 113 | acarshub: 114 | enabled: true 115 | storageClass: zfs-iscsi 116 | size: 2Gi 117 | accessMode: ReadWriteOnce 118 | advancedMounts: 119 | acarshub: 120 | acarshub: 121 | - path: /run/acars 122 | service: 123 | acarsrouter: 124 | controller: acarsrouter 125 | type: ClusterIP 126 | ports: 127 | router: 128 | port: 5550 129 | dumpvdl2: 130 | controller: dumpvdl2 131 | type: ClusterIP 132 | ports: 133 | vdl: 134 | port: 45555 135 | acarshub: 136 | controller: acarshub 137 | type: ClusterIP 138 | ports: 139 | http: 140 | port: 80 141 | acarsinput: 142 | port: 5550 143 | protocol: UDP 144 | vdslinput: 145 | port: 5555 146 | protocol: UDP 147 | acarsoutput: 148 | port: 15550 149 | vdsloutput: 150 | port: 15555 151 | 152 | ingress: 153 | acarshub: 154 | annotations: 155 | kubernetes.io/ingress.class: nginx 156 | cert-manager.io/cluster-issuer: letsencrypt-prod 157 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 158 | hosts: 159 | - host: &host "acars.bo0tzz.me" 160 | paths: 161 | - path: / 162 | pathType: Prefix 163 | service: 164 | identifier: acarshub 165 | port: 80 166 | tls: 167 | - hosts: 168 | - *host 169 | secretName: *host 170 | -------------------------------------------------------------------------------- /apps/radio/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s-charts 5 | namespace: radio 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /apps/radio/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: radio -------------------------------------------------------------------------------- /apps/social/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: gotosocial-db 5 | namespace: social 6 | spec: 7 | database: gotosocial 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: gotosocial-user 13 | namespace: social 14 | spec: 15 | role: gotosocial 16 | database: gotosocial-db 17 | secretName: database 18 | privileges: OWNER 19 | -------------------------------------------------------------------------------- /apps/social/gotosocial.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: gotosocial 5 | namespace: social 6 | spec: 7 | timeout: 5m 8 | interval: 2m0s 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: "3.7.3" 13 | sourceRef: 14 | name: bjw-s 15 | kind: HelmRepository 16 | namespace: social 17 | values: 18 | controllers: 19 | gts: 20 | replicas: 1 21 | type: deployment 22 | pod: 23 | securityContext: 24 | fsGroup: 568 25 | containers: 26 | gts: 27 | image: 28 | repository: docker.io/superseriousbusiness/gotosocial 29 | tag: "0.19.1" 30 | envFrom: 31 | - secret: gts-oidc 32 | env: 33 | TZ: Europe/Amsterdam 34 | GTS_HOST: gts.bo0.tz 35 | GTS_ACCOUNT_DOMAIN: bo0.tz 36 | GTS_ADVANCED_RATE_LIMIT_REQUESTS: 0 37 | GTS_STORAGE_LOCAL_BASE_PATH: /storage 38 | GTS_SEMAPHORE_URL: https://phanpy.bo0.tz 39 | GTS_LANDING_PAGE_USER: "me" 40 | GTS_OIDC_ENABLED: "true" 41 | GTS_OIDC_IDP_NAME: "Authentik" 42 | GTS_DB_TYPE: postgres 43 | GTS_DB_POSTGRES_CONNECTION_STRING: 44 | valueFrom: 45 | secretKeyRef: 46 | name: database-gotosocial-user 47 | key: POSTGRES_URL 48 | resources: 49 | requests: 50 | cpu: 10m 51 | limits: 52 | memory: 1024Mi 53 | 54 | persistence: 55 | storage: 56 | existingClaim: gotosocial-data 57 | 58 | service: 59 | main: 60 | controller: gts 61 | ports: 62 | http: 63 | port: 8080 64 | 65 | ingress: 66 | main: 67 | annotations: 68 | kubernetes.io/ingress.class: nginx 69 | cert-manager.io/cluster-issuer: letsencrypt-prod 70 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 71 | nginx.ingress.kubernetes.io/cors-allow-origin: "https://phanpy.bo0.tz" 72 | nginx.ingress.kubernetes.io/cors-allow-methods: "POST, GET, OPTIONS" 73 | nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type, Authorization, Cache-Control" 74 | nginx.ingress.kubernetes.io/cors-allow-credentials: "true" 75 | nginx.ingress.kubernetes.io/enable-cors: "true" 76 | nginx.ingress.kubernetes.io/proxy-body-size: "10m" 77 | hosts: 78 | - host: gts.bo0.tz 79 | paths: 80 | - path: / 81 | pathType: Prefix 82 | service: 83 | identifier: main 84 | tls: 85 | - hosts: 86 | - gts.bo0.tz 87 | secretName: gts-web-tls 88 | wellknown: 89 | annotations: 90 | kubernetes.io/ingress.class: nginx 91 | cert-manager.io/cluster-issuer: letsencrypt-prod 92 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 93 | hosts: 94 | - host: bo0.tz 95 | paths: 96 | - path: /.well-known/ 97 | pathType: ImplementationSpecific 98 | service: 99 | identifier: main 100 | tls: 101 | - hosts: 102 | - bo0.tz 103 | secretName: gts-wk-web-tls 104 | -------------------------------------------------------------------------------- /apps/social/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s 5 | namespace: social 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /apps/social/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: social 5 | -------------------------------------------------------------------------------- /apps/social/oidc-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: gts-oidc 5 | namespace: social 6 | type: Opaque 7 | stringData: 8 | GTS_OIDC_ISSUER: ENC[AES256_GCM,data:VEYwJWSE41ZUfVjiuvbXJM6ysZteMWABWpDbBdUDKnSXCfRhbGWDK+c=,iv:oJMWugqc5wPSHkxcgWV4wVb58kB33bOJWqgkFsa8Ryw=,tag:BvySBDg9SmNqiW+sixbJuQ==,type:str] 9 | GTS_OIDC_CLIENT_ID: ENC[AES256_GCM,data:6a0Wm9gZdx8MtoXd9xtpTqYr0Zj8U2nW2LmM95OggN7uO05KRI7PAg==,iv:r2hYWBcOpP6TAi97iItAXEvZ5FfK6EE4zjiiEVHSggo=,tag:/oEpHS7AqmOwr0/pnD/Psw==,type:str] 10 | GTS_OIDC_CLIENT_SECRET: ENC[AES256_GCM,data:xSyNS0lMnaXLF7BMsAqBozZpHpBqeG8zzX0X1MYmLgOP+zpBrYrh0BBFBbhlHpCsekq6g92OKYLKWRO/wfyEc79RGsf/RbMDhfzdVsvkMHE48OLObOCm75553HWhD39fiX73/mi0W7keTfMCZYR5g6Tm6HV1hgEWUyw2c4fcmU8=,iv:0HxEtjN7a9iaep70NT0475mSfnDwN25JQzduxbIWwlE=,tag:i9Ve8C76XE3r/yxqKVhGaA==,type:str] 11 | sops: 12 | lastmodified: "2025-04-26T10:04:33Z" 13 | mac: ENC[AES256_GCM,data:ubqHrL9Ni7mij7EDp5j/sQXaXHDZWYLhFwSJzmS2b0CzoCkIBymQX1KWLo/DC+lzPAVPysiA648xudMxqQmQng8+S0Cb6YjpvuoBiCY6UeT2Rk4d94g2FWOjA86Ohh+v+h6qByD60xdQ2COwgzRzHNNqikhOc1mzUXGGh3OctP8=,iv:KaEjTOqALzkCQDNN34skjF1ZzEtZyszvTSIoeN/dR6w=,tag:Rn2NYk0ahE6S5GBXbZXJjQ==,type:str] 14 | pgp: 15 | - created_at: "2025-04-26T10:04:33Z" 16 | enc: |- 17 | -----BEGIN PGP MESSAGE----- 18 | 19 | hQIMA2YE/I5Bjk+6AQ//fb5DfNaSkxPBdnGOI4Ol4WpXSxtcIoUzJYTMZH8QeWHH 20 | cNJQkuAiaScSafZAl6BXpm5dv3WasqOxuo3czNbWZtdna+a+RoUfzXME2Ma3ppY5 21 | BbgWy8fi6L825wn94GRikjmo4/pZn3oP1JMW7YT8qTlEsHMtiDEFhGQOYC0prjT4 22 | gxUZ2pHPpOfUbE64sXDjNgKIyZO7oztKPMmz+g9yRmJb1pBT1lOjavHAIniWXao/ 23 | +99Q3NowXOb+o/WT02XTnnx3y/bXbJDOAQoyFg41q94Lwte93Uzg6xkDJNmYRhBL 24 | f7sjfYeOpWfHe/NXHVTELdZ1PW4EsKzlV1Iozvf2+UeZ3WFTkBrrWIvSouj7WW4d 25 | Sx/C9R50FxzKhB9MOdiHRtxaPGsLyyiHGMzGUXjJjIpphZhx7iUM1uPqbRRSi44W 26 | RCqor6gfUus4u6TiKSdAoIUtVgqffUNp90b78Wnf1zRxAkOQ+voCY/I75+JQnF8G 27 | 5aF4zpyYWYA3oGshTIXMGeIvCGnJIeJPnUBbMX7GtFICNY7zWBZ2DiTTWA20iVt3 28 | EMqUyCvs9gqKpRJK98GoKEBHVGu2hfVVwldXwMflUvWUJFIplbl2vEUG365/YX4o 29 | RIoem/6BKvSiGDr+85VA4i1/sNMjSVO0wkJ526ZTWSS0PGAbClEnpfnYhWA9x8PU 30 | aAEJAhBc1VcGW7wLZZdH8tB+fptgJZq8LTq8bAKicysfUJ7Wvczg0ckeDGURyoeT 31 | 2txnBFkpNGJewaqM/yqlrLJK/EFQY36FOtPjIHlrVoWBHIxDcKiY3Q1TXr6R7Xc1 32 | makhTgF4yPRX 33 | =kOW0 34 | -----END PGP MESSAGE----- 35 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 36 | encrypted_regex: ^(data|stringData)$ 37 | version: 3.10.1 38 | -------------------------------------------------------------------------------- /apps/social/phanpy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: phanpy 5 | namespace: social 6 | spec: 7 | timeout: 5m 8 | interval: 2m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: "3.7.3" 13 | sourceRef: 14 | name: bjw-s 15 | kind: HelmRepository 16 | namespace: social 17 | values: 18 | controllers: 19 | main: 20 | replicas: 1 21 | type: deployment 22 | 23 | containers: 24 | main: 25 | image: 26 | repository: "ghcr.io/jjgadgets/phanpy" 27 | tag: 2025.01.26.24f03f5 28 | resources: 29 | requests: 30 | cpu: 10m 31 | limits: 32 | memory: 512Mi 33 | env: 34 | PHANPY_WEBSITE: "phanpy.bo0.tz" 35 | PHANPY_DEFAULT_INSTANCE: "gts.bo0.tz" 36 | service: 37 | main: 38 | controller: main 39 | ports: 40 | http: 41 | port: 8080 42 | 43 | ingress: 44 | main: 45 | annotations: 46 | kubernetes.io/ingress.class: nginx 47 | cert-manager.io/cluster-issuer: letsencrypt-prod 48 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 49 | hosts: 50 | - host: phanpy.bo0.tz 51 | paths: 52 | - path: / 53 | pathType: Prefix 54 | service: 55 | identifier: main 56 | tls: 57 | - hosts: 58 | - phanpy.bo0.tz 59 | secretName: phanpy-web-tls -------------------------------------------------------------------------------- /apps/social/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: gotosocial-data 5 | namespace: social 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 100Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/spoolman/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: spoolman-db 5 | namespace: applications 6 | spec: 7 | database: spoolman 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: spoolman-user 13 | namespace: applications 14 | spec: 15 | role: spoolman 16 | database: spoolman-db 17 | secretName: database 18 | privileges: OWNER -------------------------------------------------------------------------------- /apps/spoolman/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: spoolman 5 | namespace: applications 6 | spec: 7 | interval: 30m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.2.1 12 | interval: 30m 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: applications 17 | 18 | values: 19 | controllers: 20 | spoolman: 21 | containers: 22 | app: 23 | image: 24 | repository: ghcr.io/donkie/spoolman 25 | tag: 0.22.1 26 | env: 27 | SPOOLMAN_DB_TYPE: postgres 28 | SPOOLMAN_DB_HOST: 29 | valueFrom: 30 | secretKeyRef: 31 | name: database-spoolman-user 32 | key: HOST 33 | SPOOLMAN_DB_NAME: 34 | valueFrom: 35 | secretKeyRef: 36 | name: database-spoolman-user 37 | key: DATABASE_NAME 38 | SPOOLMAN_DB_USERNAME: 39 | valueFrom: 40 | secretKeyRef: 41 | name: database-spoolman-user 42 | key: LOGIN 43 | SPOOLMAN_DB_PASSWORD: 44 | valueFrom: 45 | secretKeyRef: 46 | name: database-spoolman-user 47 | key: PASSWORD 48 | probes: 49 | liveness: 50 | enabled: true 51 | readiness: 52 | enabled: true 53 | startup: 54 | enabled: true 55 | spec: 56 | failureThreshold: 30 57 | periodSeconds: 5 58 | resources: 59 | requests: 60 | cpu: 25m 61 | memory: 500M 62 | 63 | service: 64 | app: 65 | controller: spoolman 66 | ports: 67 | http: 68 | port: 8000 69 | 70 | ingress: 71 | app: 72 | annotations: 73 | kubernetes.io/ingress.class: nginx-internal 74 | cert-manager.io/cluster-issuer: letsencrypt-prod 75 | hosts: 76 | - host: &hostname spoolman.bo0tzz.me 77 | paths: 78 | - path: / 79 | service: 80 | identifier: app 81 | port: http 82 | tls: 83 | - hosts: 84 | - *hostname 85 | secretName: spoolman-tls 86 | -------------------------------------------------------------------------------- /apps/stirling-pdf.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: stirling-pdf 5 | namespace: applications 6 | spec: 7 | interval: 15m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.6.1 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | maxHistory: 3 17 | install: 18 | createNamespace: true 19 | remediation: 20 | retries: 3 21 | upgrade: 22 | cleanupOnFail: true 23 | remediation: 24 | retries: 3 25 | uninstall: 26 | keepHistory: false 27 | values: 28 | controllers: 29 | main: 30 | strategy: RollingUpdate 31 | rollingUpdate: 32 | unavailable: 0 33 | containers: 34 | main: 35 | image: 36 | repository: ghcr.io/stirling-tools/s-pdf 37 | tag: 0.46.2 38 | env: 39 | SYSTEM_ENABLEANALYTICS: false 40 | service: 41 | main: 42 | controller: main 43 | ports: 44 | http: 45 | port: 8080 46 | ingress: 47 | main: 48 | annotations: 49 | kubernetes.io/ingress.class: nginx-internal 50 | cert-manager.io/cluster-issuer: letsencrypt-prod 51 | nginx.ingress.kubernetes.io/proxy-body-size: "500m" 52 | hosts: 53 | - host: &host "pdf.bo0tzz.me" 54 | paths: 55 | - path: / 56 | pathType: Prefix 57 | service: 58 | identifier: main 59 | tls: 60 | - hosts: 61 | - *host 62 | secretName: *host 63 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/backup/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: tiddly-boet-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: tiddlywiki-boet-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: tiddly-boet-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/backup/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tiddly-boet-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/tiddlywiki/boet" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/credentials.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tiddlywiki-boet-credentials 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | TW_USERNAME: ENC[AES256_GCM,data:g5IICA==,iv:mc7vEd0yIZU0CHlHQSn4930OqJttCqiOjld27ocJ95Y=,tag:JSbZhx4A0FB6K5IXGVQQOA==,type:str] 9 | sops: 10 | kms: [] 11 | gcp_kms: [] 12 | azure_kv: [] 13 | hc_vault: [] 14 | age: [] 15 | lastmodified: "2023-01-10T10:02:13Z" 16 | mac: ENC[AES256_GCM,data:tteIxe2d/W85HoEbBktUr1VIPM3eUT/9vLUEJOAfL3hlTJNJH/N5uJ2S1LEBJqEhi+YChlJGfV7mnR/1uOjwlxkyJEZzpkng0oRlbDRGyxPWKW4APLoo5k3vdo1qOQTO3960herPHMZbK7AFuwr7R6M3mGG6XytMhK1qAJt29Us=,iv:RL2QdVyi98yjl011VdKeGVr96jRjWQ6xuUILvNTizZw=,tag:5YKCK4R/zVMRPMr3uwcaDQ==,type:str] 17 | pgp: 18 | - created_at: "2022-06-23T13:09:12Z" 19 | enc: | 20 | -----BEGIN PGP MESSAGE----- 21 | 22 | hQIMA2YE/I5Bjk+6AQ/+LE9FWw6UASS2a5ua2JHgGYhX8BbtmNbnOeLF/11pyPMC 23 | kSUIZHlpeNFI8m0D6+zGsg63frjplrJy03SQI5eHlOBJ5T2Ihw08m+WfWsPCs5UY 24 | 99Q7fmmA4dtMBR1ogUijoqQo2G26yKRoR0TgMYeJgouP4mGwOhAKtw1A3Kv76im7 25 | jtvgoervX/zHYdmtjQQDy4HZGowQNC61HnMHhAiRA0nAYmiSFUNfhUTPcf1zlPfr 26 | jv/jFOLfXu75OvSzOcH2DkEkJXbtfoUHvxSdGZecH6kFfv+L3m8X0P18pYt+mItU 27 | XB/wzqYoINakcbzoYh+fQ9K0UhQz6nVFVuxxycIJEqvY29esspzGx2KwWdkuFlpB 28 | IIydH03JB+beUqEvSBRZDQJ4A6H5WfRwwslPSXNJYHZEScMd2ocaZ5l4/LbPDOoF 29 | kRCYt+nwKPvzi6YJ6Ijd1LMY1BAJ5/CiOHY8Sy0JsmssLPEpCKjIzBSPpXy2unrN 30 | T9Lb4sq/WNnk3dIu+sAJY960vrbiILRD3uxddLptcspmSunVUQ4dJGm91bdWVQP0 31 | loT0K/DuDq/PjCR4M+DCwJyBVyKbJOitMBHnJip/6X0sRQGUD2WeEyVvZopGu/WG 32 | AmCA51GoTYpPJi7ml9KoSxaIWdFYa3PUSl/m4lHKDtQXAxnI6vaw5jlR7Me3a0LU 33 | aAEJAhB+8UI+2iAJbpbb9eLFK2yA8Fb70qNTKYIL4HsSjPMxPqTENRIykJxfZtWf 34 | a1Q9XSxTGOgLgQc+uiQ9HVFotM89DLWSSc/dr9batMB+BB9r4D74y3Kgs/kz6nOw 35 | WCW6vXWXywU9 36 | =47ch 37 | -----END PGP MESSAGE----- 38 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.7.3 41 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: tiddlywiki-boet 5 | namespace: applications 6 | labels: 7 | app: tiddlywiki-boet 8 | spec: 9 | strategy: 10 | type: Recreate 11 | selector: 12 | matchLabels: 13 | app: tiddlywiki-boet 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | app: tiddlywiki-boet 19 | spec: 20 | securityContext: 21 | runAsUser: 65534 22 | runAsGroup: 65534 23 | fsGroup: 65534 24 | fsGroupChangePolicy: "OnRootMismatch" 25 | volumes: 26 | - name: data 27 | persistentVolumeClaim: 28 | claimName: tiddlywiki-boet-data 29 | containers: 30 | - name: tiddlywiki-boet 31 | image: nicolaw/tiddlywiki:5.3.6 32 | imagePullPolicy: Always 33 | ports: 34 | - containerPort: 8080 35 | env: 36 | - name: TIDDLYWIKI_PLUGIN_PATH 37 | value: /var/lib/tiddlywiki/plugins 38 | envFrom: 39 | - secretRef: 40 | name: tiddlywiki-boet-credentials 41 | volumeMounts: 42 | - name: data 43 | mountPath: /var/lib/tiddlywiki 44 | resources: 45 | requests: 46 | cpu: 20m 47 | memory: 128M 48 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | service: tiddlywiki-boet 6 | name: tiddlywiki-boet 7 | namespace: applications 8 | spec: 9 | ports: 10 | - name: "http" 11 | port: 80 12 | targetPort: 8080 13 | selector: 14 | app: tiddlywiki-boet 15 | --- 16 | apiVersion: networking.k8s.io/v1 17 | kind: Ingress 18 | metadata: 19 | name: tiddlywiki-boet 20 | namespace: applications 21 | annotations: 22 | auth.kube.bo0tzz.me/enabled: "true" 23 | kubernetes.io/ingress.class: nginx 24 | cert-manager.io/cluster-issuer: letsencrypt-prod 25 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 26 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 27 | spec: 28 | tls: 29 | - hosts: 30 | - tiddlywiki.bo0tzz.me 31 | secretName: tiddlywiki-web-tls 32 | rules: 33 | - host: tiddlywiki.bo0tzz.me 34 | http: 35 | paths: 36 | - path: / 37 | pathType: Prefix 38 | backend: 39 | service: 40 | name: tiddlywiki-boet 41 | port: 42 | name: http 43 | -------------------------------------------------------------------------------- /apps/tiddlywiki-boet/volume.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: tiddlywiki-boet-data 5 | namespace: applications 6 | spec: 7 | storageClassName: zfs-iscsi 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 512Mi -------------------------------------------------------------------------------- /apps/tiddlywiki/backup/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: tiddly-angel-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: tiddlywiki-data 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: tiddly-angel-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/tiddlywiki/backup/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tiddly-angel-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/tiddlywiki/angel" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/tiddlywiki/credentials.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tiddlywiki-credentials 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | TW_USERNAME: ENC[AES256_GCM,data:XUxQNSc=,iv:Qf2oXzqkuGZWMaSmhsmxLydqUgFKpY/dKr1B87aG5eg=,tag:xWbbm4dyd+m/yz0ERNMXxA==,type:str] 9 | sops: 10 | kms: [] 11 | gcp_kms: [] 12 | azure_kv: [] 13 | hc_vault: [] 14 | age: [] 15 | lastmodified: "2023-01-10T11:30:00Z" 16 | mac: ENC[AES256_GCM,data:hWZ9aYF9sq4TuAQTlg8yXAD0x9ser5x1f8+2PuLSdgSNKUMYSp7DxAq5Mgf1LGxlpOPoeGacWV8F9X/cqs43YRR/QsxlpSPcgM/loi8gDEKrCoCSadCZpLvyKNSEhealEihIsI/w832nx4xsdnU0iAxGHVA877InvY7pn3OfDp8=,iv:I/AV/3STVETpSyxikoK82qISAtUsZtZ7dPTazy9Kefg=,tag:mIFyCFimqe1VlcMsEHa9mw==,type:str] 17 | pgp: 18 | - created_at: "2022-06-23T13:09:12Z" 19 | enc: | 20 | -----BEGIN PGP MESSAGE----- 21 | 22 | hQIMA2YE/I5Bjk+6AQ/+LE9FWw6UASS2a5ua2JHgGYhX8BbtmNbnOeLF/11pyPMC 23 | kSUIZHlpeNFI8m0D6+zGsg63frjplrJy03SQI5eHlOBJ5T2Ihw08m+WfWsPCs5UY 24 | 99Q7fmmA4dtMBR1ogUijoqQo2G26yKRoR0TgMYeJgouP4mGwOhAKtw1A3Kv76im7 25 | jtvgoervX/zHYdmtjQQDy4HZGowQNC61HnMHhAiRA0nAYmiSFUNfhUTPcf1zlPfr 26 | jv/jFOLfXu75OvSzOcH2DkEkJXbtfoUHvxSdGZecH6kFfv+L3m8X0P18pYt+mItU 27 | XB/wzqYoINakcbzoYh+fQ9K0UhQz6nVFVuxxycIJEqvY29esspzGx2KwWdkuFlpB 28 | IIydH03JB+beUqEvSBRZDQJ4A6H5WfRwwslPSXNJYHZEScMd2ocaZ5l4/LbPDOoF 29 | kRCYt+nwKPvzi6YJ6Ijd1LMY1BAJ5/CiOHY8Sy0JsmssLPEpCKjIzBSPpXy2unrN 30 | T9Lb4sq/WNnk3dIu+sAJY960vrbiILRD3uxddLptcspmSunVUQ4dJGm91bdWVQP0 31 | loT0K/DuDq/PjCR4M+DCwJyBVyKbJOitMBHnJip/6X0sRQGUD2WeEyVvZopGu/WG 32 | AmCA51GoTYpPJi7ml9KoSxaIWdFYa3PUSl/m4lHKDtQXAxnI6vaw5jlR7Me3a0LU 33 | aAEJAhB+8UI+2iAJbpbb9eLFK2yA8Fb70qNTKYIL4HsSjPMxPqTENRIykJxfZtWf 34 | a1Q9XSxTGOgLgQc+uiQ9HVFotM89DLWSSc/dr9batMB+BB9r4D74y3Kgs/kz6nOw 35 | WCW6vXWXywU9 36 | =47ch 37 | -----END PGP MESSAGE----- 38 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.7.3 41 | -------------------------------------------------------------------------------- /apps/tiddlywiki/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: tiddlywiki 5 | namespace: applications 6 | labels: 7 | app: tiddlywiki 8 | spec: 9 | strategy: 10 | type: Recreate 11 | selector: 12 | matchLabels: 13 | app: tiddlywiki 14 | replicas: 1 15 | template: 16 | metadata: 17 | labels: 18 | app: tiddlywiki 19 | spec: 20 | securityContext: 21 | runAsUser: 65534 22 | runAsGroup: 65534 23 | fsGroup: 65534 24 | fsGroupChangePolicy: "OnRootMismatch" 25 | volumes: 26 | - name: data 27 | persistentVolumeClaim: 28 | claimName: tiddlywiki-data 29 | containers: 30 | - name: tiddlywiki 31 | image: nicolaw/tiddlywiki:5.3.6 32 | imagePullPolicy: Always 33 | ports: 34 | - containerPort: 8080 35 | env: 36 | - name: TIDDLYWIKI_PLUGIN_PATH 37 | value: /var/lib/tiddlywiki/plugins 38 | envFrom: 39 | - secretRef: 40 | name: tiddlywiki-credentials 41 | volumeMounts: 42 | - name: data 43 | mountPath: /var/lib/tiddlywiki 44 | resources: 45 | requests: 46 | cpu: 20m 47 | memory: 128M 48 | -------------------------------------------------------------------------------- /apps/tiddlywiki/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | service: tiddlywiki 6 | name: tiddlywiki 7 | namespace: applications 8 | spec: 9 | ports: 10 | - name: "http" 11 | port: 80 12 | targetPort: 8080 13 | selector: 14 | app: tiddlywiki 15 | --- 16 | apiVersion: networking.k8s.io/v1 17 | kind: Ingress 18 | metadata: 19 | name: tiddlywiki 20 | namespace: applications 21 | annotations: 22 | auth.kube.bo0tzz.me/enabled: "true" 23 | kubernetes.io/ingress.class: nginx 24 | cert-manager.io/cluster-issuer: letsencrypt-prod 25 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 26 | spec: 27 | tls: 28 | - hosts: 29 | - wiki.bo0tzz.me 30 | secretName: wiki-web-tls 31 | rules: 32 | - host: wiki.bo0tzz.me 33 | http: 34 | paths: 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: tiddlywiki 40 | port: 41 | name: http 42 | -------------------------------------------------------------------------------- /apps/tiddlywiki/volume.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: tiddlywiki-data 5 | namespace: applications 6 | spec: 7 | storageClassName: zfs-iscsi 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 512Mi -------------------------------------------------------------------------------- /apps/vaultwarden/backup-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: vaultwarden-restic-secret 5 | namespace: applications 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/vaultwarden" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /apps/vaultwarden/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: vaultwarden-backup 5 | namespace: applications 6 | spec: 7 | sourcePVC: vaultwarden-config 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: vaultwarden-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Clone 18 | volumeSnapshotClassName: zfs-iscsi 19 | cacheStorageClassName: zfs-iscsi 20 | cacheAccessModes: ["ReadWriteOnce"] 21 | -------------------------------------------------------------------------------- /apps/vaultwarden/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: vaultwarden-db 5 | namespace: applications 6 | spec: 7 | database: vaultwarden 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: vaultwarden-user 13 | namespace: applications 14 | spec: 15 | role: vaultwarden 16 | database: vaultwarden-db 17 | secretName: database 18 | privileges: OWNER 19 | -------------------------------------------------------------------------------- /apps/vaultwarden/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: vaultwarden 5 | namespace: applications 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 1.3.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: applications 16 | interval: 1h 17 | values: 18 | image: 19 | repository: vaultwarden/server 20 | tag: 1.34.1-alpine 21 | service: 22 | main: 23 | ports: 24 | http: 25 | port: 80 26 | persistence: 27 | config: 28 | enabled: true 29 | existingClaim: vaultwarden-config 30 | env: 31 | SIGNUPS_ALLOWED: false 32 | DATABASE_URL: 33 | valueFrom: 34 | secretKeyRef: 35 | name: database-vaultwarden-user 36 | key: POSTGRES_URL 37 | ingress: 38 | main: 39 | enabled: true 40 | annotations: 41 | kubernetes.io/ingress.class: nginx 42 | cert-manager.io/cluster-issuer: letsencrypt-prod 43 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 44 | hosts: 45 | - host: pass.bo0tzz.me 46 | paths: 47 | - path: / 48 | pathType: Prefix 49 | tls: 50 | - hosts: 51 | - pass.bo0tzz.me 52 | secretName: vaultwarden-web-tls 53 | resources: 54 | requests: 55 | cpu: 100m 56 | memory: 250M 57 | -------------------------------------------------------------------------------- /apps/vaultwarden/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: vaultwarden-config 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 1Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/zipline/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: zipline-db 5 | namespace: applications 6 | spec: 7 | database: zipline 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: zipline-user 13 | namespace: applications 14 | spec: 15 | role: zipline 16 | database: zipline-db 17 | secretName: database 18 | privileges: OWNER 19 | -------------------------------------------------------------------------------- /apps/zipline/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: zipline-secret 5 | namespace: applications 6 | stringData: 7 | CORE_SECRET: ENC[AES256_GCM,data:riHSsbyt8twnAChh7KG8ZK+wOOKl6Z0vZCl5SRn0HVUKXfmIUyA1kiyKM6I=,iv:nFMtI2hTD/TsvQP1aIizJmK2KMYdq7cZe0KUBVO7HPA=,tag:5P5iTc1EKoZii+0jhj7wXw==,type:str] 8 | OAUTH_AUTHENTIK_CLIENT_ID: ENC[AES256_GCM,data:uvgvpvjvK7ds6KY9S29Un87bQsTUuYD2bwlOttokFTHmBWBBk7aVdg==,iv:vinlDL+aljowK70MjwvXXqMvh9hZN3hz39n2gPj3YlM=,tag:WnopgTh+giQZdSXp5rOGXg==,type:str] 9 | OAUTH_AUTHENTIK_CLIENT_SECRET: ENC[AES256_GCM,data:c3se/YxuuOs5tXRsHMkxlvb29Z/Jc15v3HTgArV7s5nhecVB6z+l11vuNmlYkbv+yA9du7BPBMFjzdgFTXRaCzTnP2a6Hc0ZpiMVF/BLvzvaHWyv2z3y641XRmkwhpp4/SfE/BMcl3GixsP5ByR7Up62goipf6TenQm3wDFWzB4=,iv:fhutaqUKz6lpR8X1rua4dqYGoV3D3W8Soc5g6B9Fh3Y=,tag:yg7MED8Po3IF+foAqgMpvA==,type:str] 10 | OAUTH_AUTHENTIK_AUTHORIZE_URL: ENC[AES256_GCM,data:o0XMCmtdTRKuHwa1LDXZXIOxevOFFkIQzyQfU0JZTpgaYd9p2IbHdxmo+W80K+g=,iv:dfZqgWOkHK1SDE5/IeK5wcQ/EKpJyg++1qNwlpFn74c=,tag:EKNWqCq1Ck1khfCaSLM0Aw==,type:str] 11 | OAUTH_AUTHENTIK_USERINFO_URL: ENC[AES256_GCM,data:JJ7IPc/Ey5P7HuX/sFBF24nU2f3EAL5z1G1Oe0NC8Hh/jESBxASzadn35XbF0w==,iv:J4XW1AVEgOTkIHtbW/YY5RLjQU4bPXoEOlNmOHupTMY=,tag:fspVq1WFZcm6rQuXF3zfpw==,type:str] 12 | OAUTH_AUTHENTIK_TOKEN_URL: ENC[AES256_GCM,data:Ck/i5JeuHGZF3ozN6hr8JM2kU9q0fo+1eLO7THCXdEJctRgLffi67Bwh9A==,iv:SomDR97vrePw61UNTFF1Eb6LTCrOwxHDQQILI+xC8wQ=,tag:y8hX8OlLPNb6GzZ9Kav5pA==,type:str] 13 | sops: 14 | kms: [] 15 | gcp_kms: [] 16 | azure_kv: [] 17 | hc_vault: [] 18 | age: [] 19 | lastmodified: "2024-05-19T14:03:06Z" 20 | mac: ENC[AES256_GCM,data:e6Hld6zt3/FWazlE3/46wJz4lEL0za6KX2SyO6exhGCZ6J29pHA00HwgQsr0QO4cUQa87rXRjhNmTkJV5P/pDdfjUFtWTy0410H8z5qQhuQblIeRMmA1tzzbvepzAuo4JzvtuF5VJc7mCsmHtaIX7y90GMQCEklU/yF8pJ4vTx8=,iv:Y6EvhwNboytajSCFtSMCim9Dx/P74VyDojFRFDti5TY=,tag:FZ07ZwQW5NOIeZvz39W07g==,type:str] 21 | pgp: 22 | - created_at: "2024-05-19T14:03:05Z" 23 | enc: | 24 | -----BEGIN PGP MESSAGE----- 25 | 26 | hQIMA2YE/I5Bjk+6AQ//akqybbJ4MOfMJFH8BoBqD5vWWPLi26FQqFwv6Xv8egMe 27 | r7Kb2ca8kc1G2kcVch+jL70PkCfjbbwW4IIuhedpiGaqaEudjlG+zMskznSUW+sS 28 | WbiV9ZWGEwrqtKKOJlOrYNOOg5rIQgXgnN1KtB1CIizJiTfESBta2hX7oZ41CU3j 29 | Hg+3OFCU95XFtFR8pCfHeyIjEx5kBRr4HPZFAPbgkFcO9lRpcwM0i3+DFP7/LPTY 30 | +64mwhTVWwYk4FNPCRADLZ1x4zrTWKcw/RdWXRI/rcPSc+20BHn8L0KJ/KpgPKm8 31 | SG/PM7d1neaPFDoSXS2dvnw+B3Z/3yvaoYxxLL5J7Fw6CEltd+OKpafYN/0C5mRF 32 | hOs7IY83O91AzZhy7mdO3jiaFFgwZihcRtLoNk1EGd+ET5NnDYUOGQlYTry0bwh6 33 | 5xgW78iRM14UwJxZQ26X5QrRoPN7IsbNFifCEQji7fm86OKySAI0qgSJEwMF6J+H 34 | IuBzfPg3pOP2i+pCBZ0Ro6NasOlm4aNW95YAbXYlSFwDC5p75lK4nEGYwb0mKVP1 35 | N8vuOvwp6b5RyOPAhdzLetbOyshuULO5Pkv4pGQTgOOqkKml1TNJfRHDLDiqGl+4 36 | vwnwh2uCOSfoUHSMuVdBJ8mF2PTDvZ/99Y2hsOI9qkFC3GY4UVm4YhB0NMg/qG/U 37 | ZgEJAhDQiwfY6tqmp5ZB3Uiqj3XU7/xQedFKP9VOMBM05gjMWy/CwO6BB6TobXM/ 38 | 75vAFkT6RdRwJxwmDSpUslDuAIJciStb4S9ZwubolLE/1Ev9NZjKMM2ryIG8hZpq 39 | Y8jE4X42MA== 40 | =wKmt 41 | -----END PGP MESSAGE----- 42 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 43 | encrypted_regex: ^(data|stringData)$ 44 | version: 3.7.3 45 | -------------------------------------------------------------------------------- /apps/zipline/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: zipline-data 5 | namespace: applications 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 100Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /apps/zipline/zipline.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: zipline 5 | namespace: applications 6 | spec: 7 | interval: 30m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.1.0 12 | interval: 30m 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: applications 17 | values: 18 | controllers: 19 | zipline: 20 | strategy: Recreate 21 | 22 | containers: 23 | app: 24 | image: 25 | repository: ghcr.io/diced/zipline 26 | tag: 3.7.13 27 | env: 28 | CORE_DATABASE_URL: 29 | valueFrom: 30 | secretKeyRef: 31 | name: database-zipline-user 32 | key: POSTGRES_URL 33 | CORE_RETURN_HTTPS: true 34 | DATASOURCE_TYPE: local 35 | DATASOURCE_LOCAL_DIRECTORY: /data 36 | # FEATURES_OAUTH_REGISTRATION: true 37 | UPLOADER_DEFAULT_FORMAT: random 38 | UPLOADER_MAX_FILE_SIZE: 10gb 39 | URLS_ROUTE: /z 40 | envFrom: 41 | - secretRef: 42 | name: zipline-secret 43 | probes: 44 | liveness: 45 | enabled: true 46 | readiness: 47 | enabled: true 48 | startup: 49 | enabled: true 50 | spec: 51 | failureThreshold: 30 52 | periodSeconds: 5 53 | resources: 54 | requests: 55 | cpu: 5m 56 | memory: 256Mi 57 | limits: 58 | memory: 512Mi 59 | 60 | persistence: 61 | data: 62 | existingClaim: zipline-data 63 | 64 | service: 65 | app: 66 | controller: zipline 67 | ports: 68 | http: 69 | port: 3000 70 | 71 | ingress: 72 | app: 73 | annotations: 74 | kubernetes.io/ingress.class: nginx 75 | cert-manager.io/cluster-issuer: letsencrypt-prod 76 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 77 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 78 | hosts: 79 | - host: &hostName bo0.tz 80 | paths: 81 | - path: / 82 | service: 83 | identifier: app 84 | port: http 85 | tls: 86 | - hosts: 87 | - *hostName 88 | secretName: zipline-tls 89 | -------------------------------------------------------------------------------- /automation/archiveteam.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: archiveteam 5 | namespace: automation 6 | labels: 7 | app: archiveteam 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: archiveteam 13 | template: 14 | metadata: 15 | labels: 16 | app: archiveteam 17 | spec: 18 | containers: 19 | - name: archiveteam 20 | image: atdr.meo.ws/archiveteam/usgovernment-grab 21 | imagePullPolicy: Always 22 | env: 23 | - name: SHARED_RSYNC_THREADS 24 | value: "2" 25 | args: 26 | - "--concurrent" 27 | - "10" 28 | - "--disable-web-server" 29 | - "bo0tzz" 30 | volumeMounts: 31 | - mountPath: /grab/data 32 | name: cache-volume 33 | volumes: 34 | - name: cache-volume 35 | emptyDir: 36 | sizeLimit: 4096Mi -------------------------------------------------------------------------------- /automation/emqx/helm-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: emqx 5 | namespace: automation 6 | spec: 7 | interval: 1h 8 | url: https://repos.emqx.io/charts 9 | -------------------------------------------------------------------------------- /automation/emqx/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/helmrelease-helm-v2beta1.json 3 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 4 | kind: HelmRelease 5 | metadata: 6 | name: emqx 7 | namespace: automation 8 | spec: 9 | interval: 30m 10 | chart: 11 | spec: 12 | chart: emqx 13 | version: 5.8.6 14 | sourceRef: 15 | kind: HelmRepository 16 | name: emqx 17 | namespace: automation 18 | maxHistory: 2 19 | install: 20 | remediation: 21 | retries: 3 22 | upgrade: 23 | cleanupOnFail: true 24 | remediation: 25 | retries: 3 26 | uninstall: 27 | keepHistory: false 28 | values: 29 | replicaCount: 3 30 | recreatePods: true 31 | 32 | emqxConfig: 33 | EMQX_ALLOW_ANONYMOUS: "false" 34 | EMQX_AUTH__MNESIA__PASSWORD_HASH: plain 35 | EMQX_DASHBOARD__DEFAULT_USERNAME: admin 36 | 37 | ingress: 38 | dashboard: 39 | enabled: true 40 | annotations: 41 | kubernetes.io/ingress.class: nginx-internal 42 | cert-manager.io/cluster-issuer: letsencrypt-prod 43 | path: / 44 | pathType: Prefix 45 | hosts: 46 | - &host "emqx.bo0tzz.me" 47 | tls: 48 | - hosts: 49 | - *host 50 | secretName: emqx-tls 51 | 52 | persistence: 53 | enabled: true 54 | storageClass: zfs-iscsi 55 | size: 100Mi 56 | 57 | affinity: 58 | podAntiAffinity: 59 | preferredDuringSchedulingIgnoredDuringExecution: 60 | - weight: 100 61 | podAffinityTerm: 62 | labelSelector: 63 | matchExpressions: 64 | - key: app.kubernetes.io/name 65 | operator: In 66 | values: ["emqx"] 67 | topologyKey: kubernetes.io/hostname 68 | 69 | resources: 70 | requests: 71 | cpu: 100m 72 | memory: 150Mi 73 | limits: 74 | memory: 512Mi 75 | 76 | valuesFrom: 77 | - targetPath: emqxConfig.EMQX_DASHBOARD__DEFAULT_PASSWORD 78 | kind: Secret 79 | name: emqx-secret 80 | valuesKey: admin_password 81 | - targetPath: emqxConfig.EMQX_AUTH__USER__1__USERNAME 82 | kind: Secret 83 | name: emqx-secret 84 | valuesKey: user_1_username 85 | - targetPath: emqxConfig.EMQX_AUTH__USER__1__PASSWORD 86 | kind: Secret 87 | name: emqx-secret 88 | valuesKey: user_1_password -------------------------------------------------------------------------------- /automation/emqx/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | stringData: 3 | user_1_username: ENC[AES256_GCM,data:1PQqwv+fI1g=,iv:ZjgGgNOIr1XM2G8ODBrVFNjxDcJmNl3fb3XP25orJRQ=,tag:FwPeQym3g+20DCPblXIeOg==,type:str] 4 | user_1_password: ENC[AES256_GCM,data:WhMyCHpE2It+VDO2LqtVNQXlry7tvVUHQOHLhX00J51mPpU/MhU7ug==,iv:9yqjCYU0tbal/EXSLB1CFnP4KIYbt/6rEy28OGS+kHU=,tag:4E/o/3nqd3BospY97iR9hw==,type:str] 5 | admin_password: ENC[AES256_GCM,data:Lw2aHiUHpAVqfOTn75WhFBmnL8ZsRGn1BYGcmSOIgUyoIxXr7xm5Mw==,iv:yJ3LzkJQvK6+qDjxlCiUdL7n9d2VkO0Q9AAPy3OHpIo=,tag:H2YBxNx+Zliatc6vRUx00g==,type:str] 6 | kind: Secret 7 | metadata: 8 | name: emqx-secret 9 | namespace: automation 10 | sops: 11 | kms: [] 12 | gcp_kms: [] 13 | azure_kv: [] 14 | hc_vault: [] 15 | age: [] 16 | lastmodified: "2023-12-13T11:35:03Z" 17 | mac: ENC[AES256_GCM,data:PIuuYpsGNchzTMbqvqzfktfPow7157tTIY/p/av+Dtn6Q8wU+z9yC5OrP0mS+sLh4QY8rb6ytx/r5SuboN1yIZBkNKazvoQ+jKVdGteOu/Sj3AvdNKGedeH0bIvWpHxw19WGPsOUff5CtOINV2GuVOBozKQITCARI1Ki1vNHkfQ=,iv:FSqaIh/Ij6PHcDA2uw32X3Ip8xzIvyRWzbCBOHT3/Lw=,tag:du1qPQLcRqaG7SAZmka1IA==,type:str] 18 | pgp: 19 | - created_at: "2023-12-13T11:35:03Z" 20 | enc: | 21 | -----BEGIN PGP MESSAGE----- 22 | 23 | hQIMA2YE/I5Bjk+6AQ//X3Uf76CA8myCQ71TI3Y2iyfCd5SxMkr8EA7ZgfSyyhur 24 | lF+aWJqMlVbbPN98ZmjIOrlrowdRWmEoudhO0J3BM7jn5wrCJGyfAdh1+yH3P2aY 25 | RWEQRG0QAEsVD77+I6bijSxm/kawg0+M37A82gzdJCUR0M00S4z4QsL+aU+QGRIJ 26 | TvAb14g1/+OddmOC/9KXi6slWa2LDgQ4aF5PTT/693ZJ1VbNNkFq2RFm7q4L+BCJ 27 | hc2OjRn5TYWbcTOXqfJlYDHiHAGKA2D6qVS6+78WToVspE/U82vmUkOvfQfGuRXj 28 | Us9n5DUoPb33eKh/pqU9uYHx+s0nKxPQND8vVvdyUH0lqN9oKM9BLbpLg7Gq/XVC 29 | qSgWBuultkpfEHXAc0tUiElEOZoqqMHnUw28inQihxKC8JJwtP68NCD0O0j/5feB 30 | FU0D5Wu6WtyLECsuX3XLn9zIJw4aHCkJsPa1HENdQ6EDyeayCFHxKjOmIVLL8rlS 31 | 5bd4EWbup0llhMPgHVeAqZs17ir1vkrDxlA0I9X2kNaHIeGfn5RhEeuZPZvgiVIc 32 | Ca0TYYrkmWWKJUrMIUY5G8rPq3vAXidMJzAvS5b/maXVAS4yzus6kNI+h6E6SsHf 33 | Pc+C/3afb93uaxe9FvusZs5FNn6fx1WJiPhjdf1CKVBM71eaTfIMTSL5rje4AAXU 34 | aAEJAhBFF6kayJqke/I4omXNbaay3v47MoQEWgwI1s8i+HcfMLT67YICXsmQT+VZ 35 | osFqlE1rVBd7QN7ZfOug9r88zu4BiUww9hlcRrJczLdb0AOk+dsX/ooaSnyfUaCs 36 | F20oq7aNGPn8 37 | =m+0F 38 | -----END PGP MESSAGE----- 39 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 40 | encrypted_regex: ^(data|stringData)$ 41 | version: 3.7.3 42 | -------------------------------------------------------------------------------- /automation/machinekamer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: machinekamer 5 | namespace: automation 6 | spec: 7 | strategy: 8 | type: Recreate 9 | selector: 10 | matchLabels: 11 | app: machinekamer 12 | replicas: 1 13 | template: 14 | metadata: 15 | labels: 16 | app: machinekamer 17 | spec: 18 | containers: 19 | - name: machinekamer 20 | image: ghcr.io/bo0tzz/machinekamer:main 21 | imagePullPolicy: Always 22 | env: 23 | - name: MQTT_SERVER 24 | value: emqx 25 | - name: MQTT_USER 26 | valueFrom: 27 | secretKeyRef: 28 | name: emqx-secret 29 | key: user_1_username 30 | - name: MQTT_PASSWORD 31 | valueFrom: 32 | secretKeyRef: 33 | name: emqx-secret 34 | key: user_1_password 35 | resources: 36 | requests: 37 | cpu: 20m 38 | memory: 200M 39 | -------------------------------------------------------------------------------- /automation/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: automation 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /automation/zigbee2mqtt/bjw-s-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s-charts 5 | namespace: automation 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /automation/zigbee2mqtt/exporter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 3 | kind: HelmRelease 4 | metadata: 5 | name: zigbee2mqtt-exporter 6 | namespace: automation 7 | spec: 8 | interval: 15m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: 1.5.1 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: automation 17 | install: 18 | remediation: 19 | retries: 3 20 | upgrade: 21 | remediation: 22 | retries: 3 23 | values: 24 | image: 25 | repository: ghcr.io/kpetremann/mqtt-exporter 26 | tag: 1.7.2 27 | env: 28 | MQTT_ADDRESS: emqx 29 | MQTT_TOPIC: "zigbee2mqtt/#" 30 | MQTT_V5_PROTOCOL: "True" 31 | MQTT_USERNAME: 32 | valueFrom: 33 | secretKeyRef: 34 | name: emqx-secret 35 | key: user_1_username 36 | MQTT_PASSWORD: 37 | valueFrom: 38 | secretKeyRef: 39 | name: emqx-secret 40 | key: user_1_password 41 | PROMETHEUS_PORT: &port 80 42 | PROMETHEUS_PREFIX: zigbee2mqtt_ 43 | ZIGBEE2MQTT_AVAILABILITY: "True" 44 | 45 | service: 46 | main: 47 | ports: 48 | http: 49 | port: *port 50 | resources: 51 | requests: 52 | cpu: 10m 53 | memory: 50Mi 54 | limits: 55 | memory: 200Mi 56 | -------------------------------------------------------------------------------- /automation/zigbee2mqtt/helmrelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/helmrelease-helm-v2beta1.json 3 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 4 | kind: HelmRelease 5 | metadata: 6 | name: zigbee2mqtt 7 | namespace: automation 8 | spec: 9 | interval: 30m 10 | chart: 11 | spec: 12 | chart: app-template 13 | version: 2.4.0 14 | sourceRef: 15 | kind: HelmRepository 16 | name: bjw-s-charts 17 | namespace: automation 18 | maxHistory: 2 19 | install: 20 | remediation: 21 | retries: 3 22 | upgrade: 23 | cleanupOnFail: true 24 | remediation: 25 | retries: 3 26 | uninstall: 27 | keepHistory: false 28 | values: 29 | controllers: 30 | main: 31 | containers: 32 | main: 33 | image: 34 | repository: ghcr.io/koenkk/zigbee2mqtt 35 | tag: 2.4.0 36 | env: 37 | TZ: "Europe/Amsterdam" 38 | ZIGBEE2MQTT_DATA: /config 39 | ZIGBEE2MQTT_CONFIG_ADVANCED_LAST_SEEN: ISO_8601 40 | ZIGBEE2MQTT_CONFIG_ADVANCED_LOG_LEVEL: info 41 | ZIGBEE2MQTT_CONFIG_ADVANCED_LOG_OUTPUT: '["console"]' 42 | ZIGBEE2MQTT_CONFIG_ADVANCED_NETWORK_KEY: "[49, 229, 25, 55, 202, 151, 66, 134, 187, 53, 240, 124, 1, 181, 115, 247]" 43 | ZIGBEE2MQTT_CONFIG_AVAILABILITY_ACTIVE_TIMEOUT: 60 44 | ZIGBEE2MQTT_CONFIG_AVAILABILITY_PASSIVE_TIMEOUT: 2000 45 | ZIGBEE2MQTT_CONFIG_DEVICE_OPTIONS_LEGACY: "false" 46 | ZIGBEE2MQTT_CONFIG_DEVICE_OPTIONS_RETAIN: "true" 47 | ZIGBEE2MQTT_CONFIG_EXPERIMENTAL_NEW_API: "true" 48 | ZIGBEE2MQTT_CONFIG_FRONTEND_ENABLED: "true" 49 | ZIGBEE2MQTT_CONFIG_MQTT_INCLUDE_DEVICE_INFORMATION: "true" 50 | ZIGBEE2MQTT_CONFIG_MQTT_KEEPALIVE: 60 51 | ZIGBEE2MQTT_CONFIG_MQTT_REJECT_UNAUTHORIZED: "true" 52 | ZIGBEE2MQTT_CONFIG_MQTT_SERVER: "mqtt://emqx.automation.svc.cluster.local." 53 | ZIGBEE2MQTT_CONFIG_MQTT_VERSION: 5 54 | ZIGBEE2MQTT_CONFIG_MQTT_USER: 55 | valueFrom: 56 | secretKeyRef: 57 | name: emqx-secret 58 | key: user_1_username 59 | ZIGBEE2MQTT_CONFIG_MQTT_PASSWORD: 60 | valueFrom: 61 | secretKeyRef: 62 | name: emqx-secret 63 | key: user_1_password 64 | ZIGBEE2MQTT_CONFIG_PERMIT_JOIN: "false" 65 | ZIGBEE2MQTT_CONFIG_SERIAL_PORT: tcp://192.168.178.7:6638 66 | ZIGBEE2MQTT_CONFIG_SERIAL_ADAPTER: zstack 67 | ZIGBEE2MQTT_CONFIG_ADVANCED_TRANSMIT_POWER: 20 68 | securityContext: 69 | privileged: true 70 | resources: 71 | requests: 72 | cpu: 10m 73 | memory: 128Mi 74 | limits: 75 | memory: 512Mi 76 | service: 77 | main: 78 | ports: 79 | http: 80 | port: 8080 81 | ingress: 82 | main: 83 | enabled: true 84 | annotations: 85 | auth.kube.bo0tzz.me/enabled: "true" 86 | kubernetes.io/ingress.class: nginx-internal 87 | cert-manager.io/cluster-issuer: letsencrypt-prod 88 | hosts: 89 | - host: &host "zigbee.bo0tzz.me" 90 | paths: 91 | - path: / 92 | service: 93 | name: main 94 | port: http 95 | tls: 96 | - hosts: 97 | - *host 98 | persistence: 99 | config: 100 | enabled: true 101 | existingClaim: zigbee2mqtt-config 102 | -------------------------------------------------------------------------------- /automation/zigbee2mqtt/volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: zigbee2mqtt-config 5 | namespace: automation 6 | spec: 7 | accessModes: 8 | - ReadWriteOnce 9 | resources: 10 | requests: 11 | storage: 1Gi 12 | storageClassName: zfs-iscsi 13 | -------------------------------------------------------------------------------- /database/app-db.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: Cluster 3 | metadata: 4 | name: app-db 5 | namespace: database 6 | spec: 7 | instances: 3 8 | imageName: ghcr.io/tensorchord/cloudnative-vectorchord:14.18-0.3.0 9 | enableSuperuserAccess: true 10 | primaryUpdateMethod: switchover 11 | 12 | postgresql: 13 | shared_preload_libraries: 14 | - "vchord.so" 15 | 16 | storage: 17 | storageClass: local-path 18 | size: 20Gi 19 | 20 | monitoring: 21 | enablePodMonitor: true 22 | 23 | backup: 24 | retentionPolicy: "14d" 25 | barmanObjectStore: 26 | destinationPath: s3://cnpg-backups 27 | endpointURL: https://s3.eu-central-003.backblazeb2.com 28 | wal: 29 | compression: bzip2 30 | s3Credentials: 31 | accessKeyId: 32 | name: database-backblaze 33 | key: ACCESS_KEY_ID 34 | secretAccessKey: 35 | name: database-backblaze 36 | key: SECRET_ACCESS_KEY 37 | 38 | bootstrap: 39 | recovery: 40 | backup: 41 | name: daily-backup-20240211000000 42 | --- 43 | apiVersion: postgresql.cnpg.io/v1 44 | kind: ScheduledBackup 45 | metadata: 46 | name: daily-backup 47 | namespace: database 48 | spec: 49 | schedule: "@daily" 50 | cluster: 51 | name: app-db 52 | -------------------------------------------------------------------------------- /database/backblaze-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: database-backblaze 5 | namespace: database 6 | type: Opaque 7 | stringData: 8 | ACCESS_KEY_ID: ENC[AES256_GCM,data:4MTiSGU/tVPSZ78oEufyNW1/sM/XEcsRRw==,iv:HiN7MnzQJOlYK+/MjaZ8UeFKQrmpd5HrWNHxLJsycFw=,tag:UgCVg8V56vcsFsISOa6V7g==,type:str] 9 | SECRET_ACCESS_KEY: ENC[AES256_GCM,data:gKvs9vM8WgnePu8IAMgweUAk+RLY1U0J4VAURvjpwg==,iv:BW58L8H4lgq40xQnFcjBhRpGV5c6YK7PAwh8mMTBGXY=,tag:Fc2QIxU9XJs9z4jS5NfU5w==,type:str] 10 | sops: 11 | kms: [] 12 | gcp_kms: [] 13 | azure_kv: [] 14 | hc_vault: [] 15 | age: [] 16 | lastmodified: "2024-02-11T11:20:08Z" 17 | mac: ENC[AES256_GCM,data:GccCaR77rVf89MYKK6gKDSRhAT/yAb31m3WFrvfD6REsGcP0srCYsGxtCE4+szjKezQ/MTRxpx+hqSYbGouo8gd4+/JuptkFINIRpGpNRLo4rzVKjdnJnMFmkcJ9eNmT31376bqnhi/Miq62oZEqX1H6iNx06axyQdSep6ywgw8=,iv:e2bnhMl25bQODX+3iXBA23F2gvJstsb73jsDwsVmZCU=,tag:timoAmOk46R1UoegzDsi0Q==,type:str] 18 | pgp: 19 | - created_at: "2024-02-11T11:20:07Z" 20 | enc: | 21 | -----BEGIN PGP MESSAGE----- 22 | 23 | hQIMA2YE/I5Bjk+6ARAAsqv2KGkUoTxpoCe/d8zSEAH9qEbUemZ5wFCDFDuNt6ZV 24 | ZZ16hSw7qg7oZGfCC+m3ZBWuOKTQ7HMfnZH21z/nh8usL8L98iPlJ6zNbEovGudd 25 | 3co5r+MySyOCgzEMaPxEYO4r/h5jjtFE9A9FNSHuP/vUGZVlVjhuUDqFQw5RJo9w 26 | ozP6Ueo9FlZoU3Pbr+owmllKdWUrJ5pOTMwBr3B1YROw52GjxGua4UvxH4yrmcKP 27 | zpGht84OztmCM3Li62cvaiXnfSP9Z7Q8G/Xk9JVImvSmxG2Huv4vI4cC3N6xKVHq 28 | 6ri6Ikhs/MOfshsCo3HUuU1xBk2ikKw2BRHZXoxP0yJ+kX0k56+bK27P0cpBcwjl 29 | 0wsGKKuJMVCPB1OLLUkMur1mCi0fvJdLSMtM38zksYJNOyklW1XVOgPpW7P6AMXz 30 | 9qR2i1IaCF2tp6hq98BexjNvPzVczN1mjsuZ/OnQAQirPFavaRiyARyL0Ev5Xv1N 31 | 90jGiK0Hb0pQh0OFHaLeNf0fEtPhJu3Li7Bgq6cGBCFv1kH7T1rCC0WO00WJDDuJ 32 | vVanYmHtgGtX/YaF6WdtxCMWi+MaEaqwLUcyP55Lxr/zxoIspY726Y8jMirSH2tA 33 | zAlUUDaAWEAgd4yYQn4w4wdEQZAtWFySOvFUQ4mA+dE8rmtpK4e64w80JZ1ozEnU 34 | aAEJAhBtqJqNAKi/VPEoTM8nLdhbIzka/F/crtlxthky+Ka8glXtjdTS3QeoPJRo 35 | r+zvm0B3nai6XoS0BN7VOVLySVH81gJF4mbHq0NUvTa5oK29ZiChCKgkA3DXiSVO 36 | sLoHdwTGjtfv 37 | =AiAG 38 | -----END PGP MESSAGE----- 39 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 40 | encrypted_regex: ^(data|stringData)$ 41 | version: 3.7.3 42 | -------------------------------------------------------------------------------- /database/cnpg-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: cnpg-system 5 | --- 6 | apiVersion: source.toolkit.fluxcd.io/v1beta1 7 | kind: HelmRepository 8 | metadata: 9 | name: cnpg 10 | namespace: cnpg-system 11 | spec: 12 | interval: 1h 13 | url: https://cloudnative-pg.github.io/charts 14 | --- 15 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 16 | kind: HelmRelease 17 | metadata: 18 | name: cnpg 19 | namespace: cnpg-system 20 | spec: 21 | interval: 1h 22 | chart: 23 | spec: 24 | chart: cloudnative-pg 25 | version: '0.24.0' 26 | sourceRef: 27 | kind: HelmRepository 28 | name: cnpg 29 | namespace: cnpg-system 30 | interval: 1h 31 | upgrade: 32 | crds: CreateReplace 33 | -------------------------------------------------------------------------------- /database/ext-postgres-operator/crds.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: postgres.db.movetokube.com 5 | spec: 6 | group: db.movetokube.com 7 | names: 8 | kind: Postgres 9 | listKind: PostgresList 10 | plural: postgres 11 | singular: postgres 12 | scope: Namespaced 13 | versions: 14 | - name: v1alpha1 15 | schema: 16 | openAPIV3Schema: 17 | description: Postgres is the Schema for the postgres API 18 | properties: 19 | apiVersion: 20 | description: 'APIVersion defines the versioned schema of this representation 21 | of an object. Servers should convert recognized schemas to the latest 22 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 23 | type: string 24 | kind: 25 | description: 'Kind is a string value representing the REST resource this 26 | object represents. Servers may infer this from the endpoint the client 27 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 28 | type: string 29 | metadata: 30 | type: object 31 | spec: 32 | description: PostgresSpec defines the desired state of Postgres 33 | properties: 34 | database: 35 | type: string 36 | dropOnDelete: 37 | type: boolean 38 | extensions: 39 | items: 40 | type: string 41 | type: array 42 | x-kubernetes-list-type: set 43 | masterRole: 44 | type: string 45 | schemas: 46 | items: 47 | type: string 48 | type: array 49 | x-kubernetes-list-type: set 50 | required: 51 | - database 52 | type: object 53 | status: 54 | description: PostgresStatus defines the observed state of Postgres 55 | properties: 56 | extensions: 57 | items: 58 | type: string 59 | type: array 60 | x-kubernetes-list-type: set 61 | roles: 62 | description: PostgresRoles stores the different group roles for database 63 | properties: 64 | owner: 65 | type: string 66 | reader: 67 | type: string 68 | writer: 69 | type: string 70 | required: 71 | - owner 72 | - reader 73 | - writer 74 | type: object 75 | schemas: 76 | items: 77 | type: string 78 | type: array 79 | x-kubernetes-list-type: set 80 | succeeded: 81 | type: boolean 82 | required: 83 | - roles 84 | - succeeded 85 | type: object 86 | type: object 87 | served: true 88 | storage: true 89 | subresources: 90 | status: {} 91 | --- 92 | apiVersion: apiextensions.k8s.io/v1 93 | kind: CustomResourceDefinition 94 | metadata: 95 | name: postgresusers.db.movetokube.com 96 | spec: 97 | group: db.movetokube.com 98 | names: 99 | kind: PostgresUser 100 | listKind: PostgresUserList 101 | plural: postgresusers 102 | singular: postgresuser 103 | scope: Namespaced 104 | versions: 105 | - name: v1alpha1 106 | schema: 107 | openAPIV3Schema: 108 | description: PostgresUser is the Schema for the postgresusers API 109 | properties: 110 | apiVersion: 111 | description: 'APIVersion defines the versioned schema of this representation 112 | of an object. Servers should convert recognized schemas to the latest 113 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 114 | type: string 115 | kind: 116 | description: 'Kind is a string value representing the REST resource this 117 | object represents. Servers may infer this from the endpoint the client 118 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 119 | type: string 120 | metadata: 121 | type: object 122 | spec: 123 | description: PostgresUserSpec defines the desired state of PostgresUser 124 | properties: 125 | database: 126 | type: string 127 | privileges: 128 | type: string 129 | role: 130 | type: string 131 | secretName: 132 | type: string 133 | required: 134 | - database 135 | - role 136 | - secretName 137 | type: object 138 | status: 139 | description: PostgresUserStatus defines the observed state of PostgresUser 140 | properties: 141 | databaseName: 142 | type: string 143 | postgresGroup: 144 | type: string 145 | postgresLogin: 146 | type: string 147 | postgresRole: 148 | type: string 149 | succeeded: 150 | type: boolean 151 | required: 152 | - databaseName 153 | - postgresGroup 154 | - postgresLogin 155 | - postgresRole 156 | - succeeded 157 | type: object 158 | type: object 159 | served: true 160 | storage: true 161 | subresources: 162 | status: {} 163 | -------------------------------------------------------------------------------- /database/ext-postgres-operator/operator.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Move to helm chart (https://github.com/movetokube/postgres-operator/pull/90) 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: ext-postgres-operator 6 | namespace: database 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | name: ext-postgres-operator 12 | template: 13 | metadata: 14 | labels: 15 | name: ext-postgres-operator 16 | spec: 17 | serviceAccountName: ext-postgres-operator 18 | containers: 19 | - name: ext-postgres-operator 20 | image: ghcr.io/movetokube/postgres-operator:1.3.5 21 | command: 22 | - postgres-operator 23 | imagePullPolicy: Always 24 | env: 25 | - name: WATCH_NAMESPACE 26 | value: "" 27 | - name: POD_NAME 28 | valueFrom: 29 | fieldRef: 30 | fieldPath: metadata.name 31 | - name: OPERATOR_NAME 32 | value: "ext-postgres-operator" 33 | - name: POSTGRES_HOST 34 | value: app-db-rw.database.svc 35 | - name: POSTGRES_USER 36 | valueFrom: 37 | secretKeyRef: 38 | name: app-db-superuser 39 | key: username 40 | - name: POSTGRES_PASS 41 | valueFrom: 42 | secretKeyRef: 43 | name: app-db-superuser 44 | key: password 45 | - name: POSTGRES_URI_ARGS 46 | value: "" 47 | -------------------------------------------------------------------------------- /database/ext-postgres-operator/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ext-postgres-operator 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - pods 10 | - services 11 | - endpoints 12 | - persistentvolumeclaims 13 | - events 14 | - configmaps 15 | - secrets 16 | verbs: 17 | - '*' 18 | - apiGroups: 19 | - apps 20 | resources: 21 | - deployments 22 | - daemonsets 23 | - replicasets 24 | - statefulsets 25 | verbs: 26 | - '*' 27 | - apiGroups: 28 | - apps 29 | resourceNames: 30 | - ext-postgres-operator 31 | resources: 32 | - deployments/finalizers 33 | verbs: 34 | - update 35 | - apiGroups: 36 | - db.movetokube.com 37 | resources: 38 | - '*' 39 | verbs: 40 | - '*' 41 | --- 42 | kind: ClusterRoleBinding 43 | apiVersion: rbac.authorization.k8s.io/v1 44 | metadata: 45 | name: ext-postgres-operator 46 | subjects: 47 | - kind: ServiceAccount 48 | name: ext-postgres-operator 49 | namespace: database 50 | roleRef: 51 | kind: ClusterRole 52 | name: ext-postgres-operator 53 | apiGroup: rbac.authorization.k8s.io 54 | --- 55 | apiVersion: v1 56 | kind: ServiceAccount 57 | metadata: 58 | name: ext-postgres-operator 59 | namespace: database -------------------------------------------------------------------------------- /database/minio/backup/backup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: volsync.backube/v1alpha1 2 | kind: ReplicationSource 3 | metadata: 4 | name: database-restic-backup 5 | namespace: database 6 | spec: 7 | sourcePVC: database-backup 8 | trigger: 9 | schedule: 0 23 * * * 10 | restic: 11 | pruneIntervalDays: 14 12 | repository: database-restic-secret 13 | retain: 14 | daily: 2 15 | weekly: 1 16 | monthly: 1 17 | copyMethod: Direct 18 | cacheStorageClassName: zfs-iscsi 19 | cacheAccessModes: ["ReadWriteOnce"] 20 | -------------------------------------------------------------------------------- /database/minio/backup/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: database-restic-secret 5 | namespace: database 6 | type: Opaque 7 | stringData: 8 | RESTIC_REPOSITORY: "${VOLSYNC_RESTIC_REPOSITORY}/database" 9 | RESTIC_PASSWORD: "${VOLSYNC_RESTIC_PASSWORD}" 10 | AWS_ACCESS_KEY_ID: "${VOLSYNC_B2_KEY_ID}" 11 | AWS_SECRET_ACCESS_KEY: "${VOLSYNC_B2_KEY_SECRET}" 12 | -------------------------------------------------------------------------------- /database/minio/minio-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | MINIO_ROOT_PASSWORD: ENC[AES256_GCM,data:06IyLT4iV7WpnZ7T5wgxfPiJNapJXZcQQyowYKCfBIm5f97UK+s0Vz0j9/pFeyfLv+OLVRZ9h0Rkz8fKgEgVXhdsiQ3ihbyonQPvcsE6NmHZUoBrdwYHeg==,iv:mVR+13YhNDXzf5/moVszmF8KFUTclEdQXR5CzJBJyE8=,tag:z1wSxMHdHCDXY0sdP4HIGA==,type:str] 4 | MINIO_ROOT_USER: ENC[AES256_GCM,data:RF7U9QyJ6XI=,iv:t8YE1nSTtju9RFwIsTnuMRxcpNfEryNfVKqJjDtE7b8=,tag:xrjhpEexW6J9ClioX/xsYw==,type:str] 5 | kind: Secret 6 | metadata: 7 | creationTimestamp: null 8 | name: minio-creds 9 | namespace: database 10 | sops: 11 | kms: [] 12 | gcp_kms: [] 13 | azure_kv: [] 14 | hc_vault: [] 15 | age: [] 16 | lastmodified: "2022-06-12T12:35:36Z" 17 | mac: ENC[AES256_GCM,data:gtTLnYtXmJrLZr9gukMbuXMY/R8xkRJwXuO1nTjoRYkqw5Ob5ZPoSwaXO6lx1kPy4IxLB2EbbCjHhGztFkv9+LmPG/SodHtAqr8BLS+Mng9SdMajHefrWiR/+f0rl2Yeh9Hdf3mhUYZiRRPTx1N8ebEk9PK1W5RsZFMbSOByoTs=,iv:ft+maxNG1ANzyoaStiGmq19R1HTadIx+iP80IZl55BI=,tag:e8wxBqatggdNIG9mizzLqQ==,type:str] 18 | pgp: 19 | - created_at: "2022-06-12T12:35:35Z" 20 | enc: | 21 | -----BEGIN PGP MESSAGE----- 22 | 23 | hQIMA2YE/I5Bjk+6AQ//WrqW/X5cWyTYRFww7YxVT96sMqH2x6llP0J/Q/Xtk6wZ 24 | BMZpWDC+uIvqRowXIrOdOxvSSEL7fajx9Kd8Pzh18oxJSHw2FJv/vIpf561JLfBu 25 | ZejgjKL/hxtQWXCGb7bknyZ/y0tVyGTglrJ+GAf+ZG1wUWnEaKVOJjaWGk5N+ZQL 26 | MCowAVMg9Fy4TY8aAagz6PpamqnFHYqT9xZdq8tPm8lf+8aQwM0gdse2UtONgW21 27 | U2bR8kcEtThz2uAiAWQ2ePcl4PJjOSEG7DL7zwJyJArcOniPSvP3Gw0ZqNr4P7Zz 28 | 7nCxp4l4e6Cg5KtmmXHL1j5uYYhRjGCw9XwrF4dWtDmgMZqphsHTA9d+uz8NIYaH 29 | hihHGLQJT/plqzF0SJvuadysot5E0Q4Me6AagbU673m7qJwtg9h4T9hegtGlB5rK 30 | 8H6Whd2Ds0OtW2RUHR2vicu7CuVnrndmww4eY9Av2WK/m2BW5n8RThKDmufiDXOv 31 | N7gD01NRKa+wQAH5X7UnpmApMvjtgsBxBJtP3BX5LWPW4ZC5AkmFMmYPbamwJPrZ 32 | zX7RCj+ui0jjn4eiZQVBQ5m//X6xi+VSZ72pwDltNU26eKMSsPzbm7jYIkgacJJ/ 33 | BdpiaUyv0a1ZD9HW07ixfwVAD9OcB/W2CB7cMooj4gaUVpq1e88kkYN+E1Mh8x3U 34 | aAEJAhBGLLT4RH1O7r97rGy3VZUvWg0FtlRoSEIapy+sy0oE4MKwZW6EqTUeGKBW 35 | V3aM8eOC7d5SnBxGwmDnhpbDTEM3FNUu+0BO6arB1WSOkPnXnYND8cJVFU2gtm/L 36 | 3a3QJG/m15pw 37 | =9maX 38 | -----END PGP MESSAGE----- 39 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 40 | encrypted_regex: ^(data|stringData)$ 41 | version: 3.7.3 42 | -------------------------------------------------------------------------------- /database/minio/minio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: database-backup 5 | namespace: database 6 | spec: 7 | storageClassName: manual 8 | capacity: 9 | storage: 40G 10 | accessModes: 11 | - ReadWriteMany 12 | nfs: 13 | server: 192.168.2.1 14 | path: "/rpool/backup/kube/database" 15 | --- 16 | apiVersion: v1 17 | kind: PersistentVolumeClaim 18 | metadata: 19 | name: database-backup 20 | namespace: database 21 | spec: 22 | storageClassName: manual 23 | volumeName: database-backup 24 | accessModes: 25 | - ReadWriteMany 26 | resources: 27 | requests: 28 | storage: 40G 29 | --- 30 | apiVersion: apps/v1 31 | kind: Deployment 32 | metadata: 33 | name: minio 34 | namespace: database 35 | spec: 36 | selector: 37 | matchLabels: 38 | app: minio 39 | strategy: 40 | type: Recreate 41 | template: 42 | metadata: 43 | labels: 44 | app: minio 45 | spec: 46 | volumes: 47 | - name: storage 48 | persistentVolumeClaim: 49 | claimName: database-backup 50 | containers: 51 | - name: minio 52 | image: minio/minio:RELEASE.2022-05-19T18-20-59Z 53 | args: 54 | - gateway 55 | - nas 56 | - /storage 57 | envFrom: 58 | - secretRef: 59 | name: minio-creds 60 | ports: 61 | - containerPort: 9000 62 | hostPort: 9000 63 | volumeMounts: 64 | - name: storage 65 | mountPath: "/storage" 66 | --- 67 | apiVersion: v1 68 | kind: Service 69 | metadata: 70 | name: minio 71 | namespace: database 72 | spec: 73 | type: ClusterIP 74 | ports: 75 | - port: 9000 76 | targetPort: 9000 77 | protocol: TCP 78 | selector: 79 | app: minio -------------------------------------------------------------------------------- /database/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: database 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /flux-system/cluster-secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: cluster-secrets 5 | namespace: flux-system 6 | stringData: 7 | VOLSYNC_RESTIC_REPOSITORY: ENC[AES256_GCM,data:Yx8xu3PODguwcAOvWMZLm9cH6gW0Y3X4LzQG7UIrpYXShnhB8UW2ALwYApEWat64T9do7tGrMEZe0fdg,iv:X0EMKyYpYiyZQhcsJwBaXwX6/Cpvp96gN++L/G5hrEQ=,tag:UdZHAR5dRXlSVb+FROEhqw==,type:str] 8 | VOLSYNC_RESTIC_PASSWORD: ENC[AES256_GCM,data:tv2GaBlOgq+gVCWV8DCp958Y8Yh3aSp5,iv:Kti6t85YKl1PhlsgzrUt98MxgoVKEsUubQbWoKLTAeo=,tag:79TCzKW/8jQFmoj9pOx77Q==,type:str] 9 | VOLSYNC_B2_KEY_ID: ENC[AES256_GCM,data:7DB7gZvMel5qF/UbMZYXOu0h0l2LaJ7uEA==,iv:/bLdr8sG8OrtDhyujlEoeedxhpQ2N9gSOzygT1o/CyY=,tag:oANq104pQ1q7rnYGZVDgqQ==,type:str] 10 | VOLSYNC_B2_KEY_SECRET: ENC[AES256_GCM,data:49aqYd03L7efroXV5j7QM0I+o3DtDe/3XXaDxdCU1Q==,iv:tGgfhrKotSIZlgqjWZX5+RX4kiZ9h5mqPlBH5ogDrS4=,tag:pGD4yzMi1/x4JOpSY2kHKw==,type:str] 11 | sops: 12 | kms: [] 13 | gcp_kms: [] 14 | azure_kv: [] 15 | hc_vault: [] 16 | age: [] 17 | lastmodified: "2023-02-06T16:09:19Z" 18 | mac: ENC[AES256_GCM,data:jLMHAOQX3jaMz9N1vmnsGAXfFiV0EizSoW5XiZoLN365ISt9GLDgL/wrBU8fjCtNiy+Duh72DEvkldBqqiMQdNC9HJsAf2rBY9X7AryDHib2kOkkCGewL5jYgMP6ITmjX6IHvx+au+9Y+S8hVKNieckIPwka6hfgbrL3L30V8RQ=,iv:RNfC1mFdErhBpTOXrw2ByUxKDYFmWU85zIGIGGyT9Jo=,tag:SPyiJjun9XgKzViCwQxb1w==,type:str] 19 | pgp: 20 | - created_at: "2023-02-06T14:00:12Z" 21 | enc: | 22 | -----BEGIN PGP MESSAGE----- 23 | 24 | hQIMA2YE/I5Bjk+6AQ/6A2LvpyKw6g+ojs5yQi1ICjTbkTivKSH0si8rU0EMEn1b 25 | aWTSGTeQwB3omBqp+mHmHcb7cbRq9S1yEXvYTejbfp8ueccoW1O3HIB5Ki47UoMT 26 | 6WRsapWL1uwNfI7WXV3SlB6qhMtVhpeuRPnfiv01ijukP+4aomi4bAnjhRXOACzX 27 | cHTHDoOIQ5FpnJTNZmA8yumg4falfA7LQDu3xAKz2pWmsUMkydlh+6U4ghsURZpR 28 | 6XPwLXg5e1hslO74i+bkCjKDVNZFCfNeZw204TVUipxDZxCUe7FMoYFZpkNVSANG 29 | a6QQAQfX8D9iGLBMomovZXiX9JKijNRuxHQRwaiGYG7ZD5bXR0xvm+8dvbar3BZQ 30 | 7iXFEg5DzezN5VrL7nKZ3UaIjycnlOceQ0BdhIsufB090sptwUUDz837jQ/buJSe 31 | sScej1GpHk42wfK/mjKCbQmRjDUia1FDn7bmeIr9J5Lz0ouJvCaomwQuqZ77Iah4 32 | 8f4iMeZk5AnGeLkqMUuviftk0i4woaNDjBIPa3fXjh8/th6QS4Yaz8tmQp1hXn1F 33 | +SCqa/JNx1ynqMdxPUcdhVBXzW5XuxmzoUWskC0JnDxQ0hrBJHqXNbCy1zqwZSCc 34 | IE5r65Y+kZQu7fcMchM0o7OzMHbFOBogp+wQKUdObJypRNfECPr9J8O39j4Jff3U 35 | aAEJAhB2NGgfYjaZy3uCWNq7HFuHD+yiRpyJ2+cyDnrHKPaczXdYeGZLZKCbd/WM 36 | Uc8qXLDt1TvkdAWu8saXK1nsNC42N1dHzX+xWYRWtM8i7aUf7+tys3w7o5DNStJE 37 | c7ks3SpSua5w 38 | =GijG 39 | -----END PGP MESSAGE----- 40 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 41 | encrypted_regex: ^(data|stringData)$ 42 | version: 3.7.3 43 | -------------------------------------------------------------------------------- /flux-system/gotk-sync.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: GitRepository 3 | metadata: 4 | name: flux-system 5 | namespace: flux-system 6 | spec: 7 | interval: 1m0s 8 | ref: 9 | branch: main 10 | url: https://github.com/bo0tzz/kube.git 11 | --- 12 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 13 | kind: Kustomization 14 | metadata: 15 | name: flux-system 16 | namespace: flux-system 17 | spec: 18 | interval: 10m0s 19 | path: ./ 20 | prune: true 21 | decryption: 22 | provider: sops 23 | secretRef: 24 | name: sops-gpg 25 | sourceRef: 26 | kind: GitRepository 27 | name: flux-system 28 | postBuild: 29 | substituteFrom: 30 | - kind: Secret 31 | name: cluster-secrets 32 | -------------------------------------------------------------------------------- /flux-system/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: webhook 5 | namespace: flux-system 6 | annotations: 7 | kubernetes.io/ingress.class: nginx 8 | cert-manager.io/cluster-issuer: letsencrypt-prod 9 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 10 | spec: 11 | tls: 12 | - hosts: 13 | - flux-webhook.bo0tzz.me 14 | secretName: flux-webhook-tls 15 | rules: 16 | - host: flux-webhook.bo0tzz.me 17 | http: 18 | paths: 19 | - path: / 20 | pathType: Prefix 21 | backend: 22 | service: 23 | name: webhook-receiver 24 | port: 25 | number: 80 -------------------------------------------------------------------------------- /flux-system/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - cluster-secrets.yaml 5 | - gotk-components.yaml 6 | - gotk-sync.yaml 7 | - webhook-secret.yaml 8 | - webhook.yaml 9 | - ingress.yaml 10 | -------------------------------------------------------------------------------- /flux-system/webhook-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: webhook-token 5 | namespace: flux-system 6 | data: 7 | token: ENC[AES256_GCM,data:JQUro3bGjx56Ia+nhkHH1Xgy0M+5Yyp3h7eOlGjK10o0KeTu8y3UgRI9cKCj2gLhXfB7lpH63jk=,iv:eDoFzLCH41qO6vgbjHLBu/b2QFEXIZpnhBwkQVabxwQ=,tag:ICH5OcWaTOmGrh6y+vy9Fw==,type:str] 8 | type: Opaque 9 | sops: 10 | kms: [] 11 | gcp_kms: [] 12 | azure_kv: [] 13 | hc_vault: [] 14 | age: [] 15 | lastmodified: "2022-06-21T14:34:53Z" 16 | mac: ENC[AES256_GCM,data:r/TQbUzSAzr8H0VAVxn9pgAB5+bI8cKoY0XYa5VKdzLA+YDEwdod6StzrRhLZ+oVdgLw50EMB8SvFcHKUwvjjMy8ZudX8iZRMqdKfVDdPyHa4G9IvPl0gvQ9UY2mq1eEwcdwxYPUUH3IRPBvAPGPg25jWQ8RYgCf2EJVPzPzSyo=,iv:60BpKGg+33piS+RHOn/MyMDINgYtEXupCHoo92U00Rg=,tag:GgZTTyez4+4FPPRRkohrqA==,type:str] 17 | pgp: 18 | - created_at: "2022-06-21T14:34:53Z" 19 | enc: | 20 | -----BEGIN PGP MESSAGE----- 21 | 22 | hQIMA2YE/I5Bjk+6ARAAudWU9BGAa+3zqhb6PlJ6VWKbkVZV5PHlJameJkSkyvcu 23 | LlSu36T9lTv84iHQRPEubSGBXZsdff/dQI0NbMwxlpVX7uQXiI16fKrgL2WbDZzS 24 | NLNFu0OuAEpIvDVXkJVdU9uQ1jngbiU5fgwaaGaNu4n47M4Bdm+cCFjzq+gzjp4q 25 | vyQ5qzIPN4Hgv3r+xdMXspBYsA4psaEgvGzePMFbM2iHEL/8+9Tg9BirY0WYQAfD 26 | kFEEDDVUY8xct/hCuNB1obJJlHJ3nao/sDoBQhgn211TO004aGsyktk7HI+ZhJ9r 27 | 6a5xoB6OykQudhtBDEaJVfIkxs7rBsGQbyjWgKXAKvx8d6y+iVq0E744ZWY8jwFH 28 | xlHoYlcuQnApx/I5YvNU+LKLCfthxbzMSA8XvH3ho4L+a6hHW//YNrVcG6mUJZ5n 29 | kfZJPdDL6olA4s0yUkKa1TYM+RSAsvV9WFRHmJDNJzty3XK4fJtLXJLN6ZG3fCMv 30 | JoqDjvS18z/dDj93Gaw0p4a+0juHfGlKcRgVQBDt8P7v3VSj6Mz/GvF1id6pEzxq 31 | LnsqaFfuJRlAhDGg1chqACP3au0UkOm9kpeQTEB3CMZh/hnmraAt0b6sl2BF1QTn 32 | JaKQCyAjHBdW6Pb4zqhgg+nlaXIDjEtk61xe5zXwVNJqft7kH7lA8tzVN2KMnknU 33 | aAEJAhArjDsijAAoqEwcbr3eaYkJdU9y64cFg8yDGC1gr4egMxVEtxLUrjDipVHY 34 | aEEMLWYP9z0AAezoYSjTGvvCocoPW+mGXTaw1zyDcoBiZjh+HLeC0QsrYbneroZJ 35 | /XwOCe0L3FT5 36 | =FWkK 37 | -----END PGP MESSAGE----- 38 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.7.3 41 | -------------------------------------------------------------------------------- /flux-system/webhook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: notification.toolkit.fluxcd.io/v1beta1 2 | kind: Receiver 3 | metadata: 4 | name: webhook 5 | namespace: flux-system 6 | spec: 7 | type: github 8 | events: 9 | - "ping" 10 | - "push" 11 | secretRef: 12 | name: webhook-token 13 | resources: 14 | - kind: GitRepository 15 | name: flux-system -------------------------------------------------------------------------------- /infrastructure/auth/authentik.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: authentik 5 | namespace: auth 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: authentik 11 | version: 2025.4.1 12 | sourceRef: 13 | kind: HelmRepository 14 | name: authentik 15 | namespace: auth 16 | 17 | values: 18 | server: 19 | metrics: 20 | enabled: true 21 | serviceMonitor: 22 | enabled: true 23 | ingress: 24 | enabled: true 25 | annotations: 26 | kubernetes.io/ingress.class: nginx 27 | cert-manager.io/cluster-issuer: letsencrypt-prod 28 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 29 | hosts: [&host auth.bo0tzz.me] 30 | tls: 31 | - hosts: 32 | - *host 33 | secretName: authentik-web-tls 34 | 35 | authentik: 36 | log_level: trace 37 | email: 38 | port: 465 39 | use_ssl: true 40 | 41 | postgresql: 42 | enabled: false 43 | redis: 44 | enabled: true 45 | global: 46 | storageClass: zfs-iscsi 47 | 48 | prometheus: 49 | rules: 50 | enabled: true 51 | 52 | valuesFrom: 53 | - kind: Secret 54 | name: &secret authentik-secret 55 | valuesKey: AUTHENTIK_SECRET_KEY 56 | targetPath: authentik.secret_key 57 | - kind: Secret 58 | name: *secret 59 | valuesKey: AUTHENTIK_EMAIL__HOST 60 | targetPath: authentik.email.host 61 | - kind: Secret 62 | name: *secret 63 | valuesKey: AUTHENTIK_EMAIL__USERNAME 64 | targetPath: authentik.email.username 65 | - kind: Secret 66 | name: *secret 67 | valuesKey: AUTHENTIK_EMAIL__PASSWORD 68 | targetPath: authentik.email.password 69 | - kind: Secret 70 | name: *secret 71 | valuesKey: AUTHENTIK_EMAIL__FROM 72 | targetPath: authentik.email.from 73 | - kind: Secret 74 | name: &db-secret authentik-postgres-authentik 75 | valuesKey: HOST 76 | targetPath: authentik.postgresql.host 77 | - kind: Secret 78 | name: *db-secret 79 | valuesKey: LOGIN 80 | targetPath: authentik.postgresql.user 81 | - kind: Secret 82 | name: *db-secret 83 | valuesKey: PASSWORD 84 | targetPath: authentik.postgresql.password 85 | - kind: Secret 86 | name: *db-secret 87 | valuesKey: DATABASE_NAME 88 | targetPath: authentik.postgresql.name 89 | -------------------------------------------------------------------------------- /infrastructure/auth/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: db.movetokube.com/v1alpha1 2 | kind: Postgres 3 | metadata: 4 | name: authentik-db 5 | namespace: auth 6 | spec: 7 | database: authentik 8 | --- 9 | apiVersion: db.movetokube.com/v1alpha1 10 | kind: PostgresUser 11 | metadata: 12 | name: authentik 13 | namespace: auth 14 | spec: 15 | role: authentik 16 | database: authentik-db 17 | secretName: authentik-postgres 18 | privileges: OWNER -------------------------------------------------------------------------------- /infrastructure/auth/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: auth -------------------------------------------------------------------------------- /infrastructure/auth/repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: authentik 5 | namespace: auth 6 | spec: 7 | interval: 1h 8 | url: https://charts.goauthentik.io -------------------------------------------------------------------------------- /infrastructure/auth/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: authentik-secret 5 | namespace: auth 6 | stringData: 7 | AUTHENTIK_SECRET_KEY: ENC[AES256_GCM,data:DCZ1b8cnnFm0PGVzkQXzNOWLK/YqqiXAlaawuC5R7yWP/i2KwNteZ8hqRitP72HmDm91UEeNn5gcefwelbGEnw==,iv:VydUeJXk8rFsllFkwvHr5oH6rEj/IYt9KSEGRiJc5rI=,tag:L3FjLvBLPSuDvWrsIPc8SA==,type:str] 8 | AUTHENTIK_EMAIL__HOST: ENC[AES256_GCM,data:U0hB/vXkMrjtP4bjeaCz0wM=,iv:KOdFEgpPp9bZ1MBns39303hr9Z/Pdc5HInRpssIr9Ho=,tag:Uhevu4shK5clhkJOQg67pQ==,type:str] 9 | AUTHENTIK_EMAIL__USERNAME: ENC[AES256_GCM,data:NVPu4hlJ9BYCDs0Y,iv:8ybzu+taz1bTU4+/i5HPeIxMOACEPEmfGCtg2aX3LBE=,tag:a0o6TwUtr6FSEC6DtguX/g==,type:str] 10 | AUTHENTIK_EMAIL__PASSWORD: ENC[AES256_GCM,data:KZ//JJfDx1PLu0FCS6DACQ==,iv:umPhSdwtN5Q3yoFN4kIZx4J+1gUsFlDa4et3EgZsXWc=,tag:Loa140W/S9Asvf4Pq68N0w==,type:str] 11 | AUTHENTIK_EMAIL__FROM: ENC[AES256_GCM,data:co0Knw1VrJGEXivwBCryCSxDJi5UxPoL1O4=,iv:f9r8alw+nB+Yp5tYDygrG2ifZ3YI6uuxA2fWgoHvkr4=,tag:XpmyH9NUVi/bc7D2020nkw==,type:str] 12 | sops: 13 | kms: [] 14 | gcp_kms: [] 15 | azure_kv: [] 16 | hc_vault: [] 17 | age: [] 18 | lastmodified: "2023-01-09T15:13:11Z" 19 | mac: ENC[AES256_GCM,data:wvxyx1KPjE1Y5wbQW/jSz3Gmlxzej4/WbwBXfSS9iRtlE0LsMmi0s9rVr2ZlqcCpIcTc0A8H3K6uPh+9hzAeSLwevwfam2XsA31FHq9NU4jb9Eqp02HAlB3b462n6x1YRMSTRrzoMOOfSyTP3/jo6mi4a2UfktJl66qk887UHYo=,iv:wGfIh8NSXcsLjfiXjA0476SrVXAohRUlWz34KW1Wz08=,tag:BWA+FsUS9dsCNIsyRylBSg==,type:str] 20 | pgp: 21 | - created_at: "2023-01-09T14:10:12Z" 22 | enc: | 23 | -----BEGIN PGP MESSAGE----- 24 | 25 | hQIMA2YE/I5Bjk+6AQ//cZPD2nLqVOm+b1Gkl+WfJS7fPXRpxec4+pEPw1jU4Zl9 26 | 5tnnLKFkeyWessU2IT22xmC/G2jnpVOgt5h5cJ+WcmM+akMztS4hjbC77oDcnla1 27 | XyJ99PP7W5herFiMP8P6ZMD3xbXOPfDhKbMa9b73qU1dTRVFeycCVJZwZzfGDM7z 28 | h6z4sSYXj+npd+u0i0XXsMmU1tPQwPTMVK9dK1qBjmOfTpEFHhNCrAHZPXbSgTRa 29 | SPKZlhrk8FsLE78Rifdnz5UFU9nNhZC2KCXsNKKrGKsFfLD60YqDjQDuVtRPn0N6 30 | ct0LQCSSoFUXmobtIvnM5UTkzDy5PiFcaug7LbSykHAnKXWpFtbBV2i45km69u20 31 | /V4vjZw27nUA7uCX+Ww1xhBcn7BqEdB2JZr2WqZSDIhY0rFDXgUO2vy7UP5ypGkm 32 | y6o1hXEVPVN96nbdtb4p0BTOlqOPKaiPzNc73jy6w7U7mXw6rsvUhSpDwzGAkTcG 33 | XwO62FtKHUytLHgTncBo9ldZk1tWtUxz36kNEdURkPlpEc1HEyhu4HpuTIeAIajd 34 | l8u3msh8vQjc+G/FAPddSOdirZJQaDSPKWrk/z7kL1144fUSe0XGUiTQjKBgHwqD 35 | zclskWoYQnB46J86ypF4g9rWc23cRmFkqNqRRuCYfRExTPGfbkgdNbO0FHmIULbU 36 | ZgEJAhAh2Ooqo0Pyv1wuxJQmQHCMALyTkORW4zj2szpYls3CxkDZzN5UP9WmrikX 37 | Vq3pkTaY5dUkxF+Ud715ulgGU8oVGR20jH1+/zJQmYkn+AGwg7GXoR8sLuGdekVd 38 | vM9n38PmZg== 39 | =STFz 40 | -----END PGP MESSAGE----- 41 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 42 | encrypted_regex: ^(data|stringData)$ 43 | version: 3.7.3 44 | -------------------------------------------------------------------------------- /infrastructure/dns/cert-manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: cert-manager 5 | namespace: dns 6 | spec: 7 | interval: 1h 8 | url: https://charts.jetstack.io 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: cert-manager 14 | namespace: dns 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: cert-manager 20 | version: 'v1.17.2' 21 | sourceRef: 22 | kind: HelmRepository 23 | name: cert-manager 24 | namespace: dns 25 | interval: 1h 26 | values: 27 | installCRDs: true 28 | -------------------------------------------------------------------------------- /infrastructure/dns/cloudflare-api-token.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | cloudflare_api_token: ENC[AES256_GCM,data:rEEStDagBWEgklMUeUUFdYUrPPcJ+MZJDGVL2uQHJo6lA5oouhjN/RZykklLkuObTPT/ymkv3kg=,iv:AynXhgfPlB8TeCImw8a0C2JKv+zi+lEY+aXxcdiaoRg=,tag:MtGMI3MM8scWx84y+xb73w==,type:str] 4 | kind: Secret 5 | metadata: 6 | creationTimestamp: null 7 | name: cloudflare-api-token 8 | namespace: dns 9 | type: Opaque 10 | sops: 11 | kms: [] 12 | gcp_kms: [] 13 | azure_kv: [] 14 | hc_vault: [] 15 | age: [] 16 | lastmodified: "2022-06-11T10:17:26Z" 17 | mac: ENC[AES256_GCM,data:5tZANU0ySBT4olIrzl1DyKDqCJPNfmZEwW3OW73sW9l2z5cvMdI+0+41V4bloSnefNnoP9QuuVwx9rYTqL88gzLO8pnINFA/sLaQThrAx8yfkkmH/8rauBCls0kpuaNMKaVcqKh9Vw9cccsIg4gnE2A/X8kEfu4+iUYczoYkM40=,iv:L1tI/Oe7fdCuI/qwnqaXZ9fWm5/JCI50CT6xf5WmX30=,tag:yYGXjkTqq5lszqTGbKvDBw==,type:str] 18 | pgp: 19 | - created_at: "2022-06-11T10:17:26Z" 20 | enc: | 21 | -----BEGIN PGP MESSAGE----- 22 | 23 | hQIMA2YE/I5Bjk+6AQ//Ral42Ks7k5YoUP6ltW4uYE1zGYhD+DIXbklzmEUr+y01 24 | PGD6Dx9PQLtCujM2KaIMY6pCFCXqb6SlUZj/XOUK+jqoq48zUsBBa7rWBll9uWyj 25 | Vz4uGL/1PuXSI/lVXJb869cIRqU0KK33ZlWN1W+Lqnk5UhAYNEWREhQAV321kkAW 26 | faDIWEBvLZFann7GyWNN7Xc3th0rYUYL7zb8tBsljfe7KJXf8tQqygkkIdTZCKee 27 | ZPkKKzaVawnE8SYw0IhOVdYJ21P7bbpCQQYt4xRk9VDs66hWN5G8IoKS4YTHpxU6 28 | 5si5UBX4jFfvMXdgW/TwDMuRH2G6afmQSVSJr9yQj5tSmjaozKHSRYDTbsniuBLW 29 | ZQ0fqUzf9qjyC13DxDpzmQpQLkHyCKfdONR/ZL7YU099ZrHWRnHLfdpWeQULm7NI 30 | BahIm1X6Q5frM5XIYKRq5inEKofv30N3VfZ4hhcEoWVCyFsduc2potlBSmY/ASYP 31 | Nuax1mVu6sLWNYlBxPbpWOXK4XpKGmszl3KPM4xc/L5t6MRNRB7hoN8trVLs4rBh 32 | JNAAx4kv70aRUTAFJv8R+E6qw7JdPnMxd922lr1DkD5M2KyiSnpRwBO72XhHTiHU 33 | Waqogkbhl0b/CnjQJOMfQ//E5f2Im1wzocs43Coxb+Q0vwTHw/oIBo9BqgkBIzDU 34 | aAEJAhCrVY3IsljNpZ+180361Cqrgh7f1Fx7s7Wjpa8STYTHFzYXcuxsadzsow8C 35 | 4lFGoYztTlhUwqzWAmePF8U31DgFGdd28f6iYLpqi40525ZQmiAM8qXDlbBHAuLS 36 | MJrO/Qagaz7q 37 | =pbBk 38 | -----END PGP MESSAGE----- 39 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 40 | encrypted_regex: ^(data|stringData)$ 41 | version: 3.7.3 42 | -------------------------------------------------------------------------------- /infrastructure/dns/cloudflare-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: letsencrypt-prod 5 | namespace: dns 6 | spec: 7 | acme: 8 | email: le-acme@bo0tzz.me 9 | server: https://acme-v02.api.letsencrypt.org/directory 10 | privateKeySecretRef: 11 | name: letsencrypt-prod-key 12 | solvers: 13 | - dns01: 14 | cloudflare: 15 | email: btdewilligen@gmail.com 16 | apiTokenSecretRef: 17 | name: cloudflare-api-token 18 | key: cloudflare_api_token -------------------------------------------------------------------------------- /infrastructure/dns/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: external-dns 5 | namespace: dns 6 | spec: 7 | interval: 1h 8 | url: https://kubernetes-sigs.github.io/external-dns/ 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: external-dns 14 | namespace: dns 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: external-dns 20 | version: '1.16.1' 21 | sourceRef: 22 | kind: HelmRepository 23 | name: external-dns 24 | namespace: dns 25 | interval: 1h 26 | values: 27 | provider: 28 | name: cloudflare 29 | sources: 30 | - ingress 31 | policy: sync 32 | interval: 60m 33 | triggerLoopOnEvent: true 34 | extraArgs: 35 | - --annotation-filter=external-dns.alpha.kubernetes.io/exclude notin (true) 36 | env: 37 | - name: CF_API_TOKEN 38 | valueFrom: 39 | secretKeyRef: 40 | name: cloudflare-api-token 41 | key: cloudflare_api_token 42 | -------------------------------------------------------------------------------- /infrastructure/dns/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: dns -------------------------------------------------------------------------------- /infrastructure/goldilocks/goldilocks.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: goldilocks 5 | namespace: goldilocks 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: goldilocks 11 | version: '9.0.2' 12 | sourceRef: 13 | kind: HelmRepository 14 | name: fairwinds 15 | namespace: goldilocks 16 | interval: 1h 17 | values: 18 | dashboard: 19 | replicaCount: 1 -------------------------------------------------------------------------------- /infrastructure/goldilocks/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: goldilocks -------------------------------------------------------------------------------- /infrastructure/goldilocks/repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: fairwinds 5 | namespace: goldilocks 6 | spec: 7 | interval: 1h 8 | url: https://charts.fairwinds.com/stable -------------------------------------------------------------------------------- /infrastructure/goldilocks/vpa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: vertical-pod-autoscaler 5 | namespace: goldilocks 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: vpa 11 | version: '3.1.0' 12 | sourceRef: 13 | kind: HelmRepository 14 | name: fairwinds 15 | namespace: goldilocks 16 | interval: 1h 17 | values: 18 | recommender: 19 | enabled: true 20 | updater: 21 | enabled: false 22 | admissionController: 23 | enabled: false 24 | -------------------------------------------------------------------------------- /infrastructure/ingress/ingress-nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: ingress-nginx 5 | namespace: ingress 6 | spec: 7 | interval: 1h 8 | url: https://kubernetes.github.io/ingress-nginx 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: ingress-nginx 14 | namespace: ingress 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: ingress-nginx 20 | version: '4.12.2' 21 | sourceRef: 22 | kind: HelmRepository 23 | name: ingress-nginx 24 | namespace: ingress 25 | interval: 1h 26 | values: 27 | controller: 28 | config: 29 | allow-snippet-annotations: true 30 | annotations-risk-level: Critical 31 | service: 32 | loadBalancerIP: 192.168.4.100 33 | annotations: 34 | external-dns.alpha.kubernetes.io/hostname: bo0tzz.me 35 | image: 36 | digest: null 37 | metrics: 38 | enabled: true 39 | serviceMonitor: 40 | enabled: true 41 | --- 42 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 43 | kind: HelmRelease 44 | metadata: 45 | name: ingress-nginx-internal 46 | namespace: ingress 47 | spec: 48 | interval: 1h 49 | chart: 50 | spec: 51 | chart: ingress-nginx 52 | version: '4.12.2' 53 | sourceRef: 54 | kind: HelmRepository 55 | name: ingress-nginx 56 | namespace: ingress 57 | interval: 1h 58 | values: 59 | controller: 60 | config: 61 | allow-snippet-annotations: true 62 | annotations-risk-level: Critical 63 | electionID: ingress-controller-internal-leader 64 | service: 65 | loadBalancerIP: 192.168.4.101 66 | ingressClass: nginx-internal 67 | image: 68 | digest: null 69 | metrics: 70 | enabled: true 71 | serviceMonitor: 72 | enabled: true 73 | -------------------------------------------------------------------------------- /infrastructure/ingress/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ingress -------------------------------------------------------------------------------- /infrastructure/kyverno/kyverno.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: kyverno 5 | namespace: kyverno 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: kyverno 11 | version: 2.7.5 12 | sourceRef: 13 | kind: HelmRepository 14 | name: kyverno-charts 15 | namespace: kyverno 16 | interval: 1h 17 | values: 18 | resources: 19 | requests: 20 | cpu: 247m 21 | memory: 443M 22 | limits: 23 | memory: 1336M 24 | -------------------------------------------------------------------------------- /infrastructure/kyverno/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: kyverno -------------------------------------------------------------------------------- /infrastructure/kyverno/policies/apply-ingress-auth-annotations.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kyverno.io/v1 3 | kind: ClusterPolicy 4 | metadata: 5 | name: apply-ingress-auth-annotations 6 | annotations: 7 | policies.kyverno.io/title: Update ingress annotations 8 | policies.kyverno.io/subject: Ingress 9 | policies.kyverno.io/description: >- 10 | This policy creates auth annotations on ingresses. When 11 | the `auth.kube.bo0tzz.me/enabled` annotation is `true` it 12 | applies the nginx auth annotations for use with Authentik. 13 | spec: 14 | mutateExistingOnPolicyUpdate: true 15 | generateExistingOnPolicyUpdate: true 16 | rules: 17 | - name: auth-internal 18 | match: 19 | any: 20 | - resources: 21 | kinds: ["Ingress"] 22 | annotations: 23 | auth.kube.bo0tzz.me/enabled: "true" 24 | kubernetes.io/ingress.class: nginx-internal 25 | mutate: 26 | patchStrategicMerge: 27 | metadata: 28 | annotations: 29 | +(nginx.ingress.kubernetes.io/auth-url): http://ak-outpost-internal-authentik-embedded-outpost-internal-ingress.auth.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx 30 | +(nginx.ingress.kubernetes.io/auth-signin): /outpost.goauthentik.io/start?rd=$escaped_request_uri 31 | +(nginx.ingress.kubernetes.io/auth-response-headers): Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid 32 | +(nginx.ingress.kubernetes.io/auth-snippet): proxy_set_header X-Forwarded-Host $http_host; 33 | 34 | - name: auth-external 35 | match: 36 | any: 37 | - resources: 38 | kinds: ["Ingress"] 39 | annotations: 40 | auth.kube.bo0tzz.me/enabled: "true" 41 | kubernetes.io/ingress.class: nginx 42 | mutate: 43 | patchStrategicMerge: 44 | metadata: 45 | annotations: 46 | +(nginx.ingress.kubernetes.io/auth-url): http://ak-outpost-authentik-embedded-outpost.auth.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx 47 | +(nginx.ingress.kubernetes.io/auth-signin): /outpost.goauthentik.io/start?rd=$escaped_request_uri 48 | +(nginx.ingress.kubernetes.io/auth-response-headers): Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid 49 | +(nginx.ingress.kubernetes.io/auth-snippet): proxy_set_header X-Forwarded-Host $http_host; -------------------------------------------------------------------------------- /infrastructure/kyverno/repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: kyverno-charts 5 | namespace: kyverno 6 | spec: 7 | interval: 1h 8 | url: https://kyverno.github.io/kyverno/ -------------------------------------------------------------------------------- /infrastructure/metallb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: metallb 5 | namespace: kube-system 6 | spec: 7 | interval: 1h 8 | url: https://charts.bitnami.com/bitnami 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: metallb 14 | namespace: kube-system 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: metallb 20 | version: '3.0.9' 21 | sourceRef: 22 | kind: HelmRepository 23 | name: metallb 24 | namespace: kube-system 25 | interval: 1h 26 | values: 27 | configInline: | 28 | address-pools: 29 | - name: default 30 | protocol: layer2 31 | addresses: 32 | - 192.168.4.100-192.168.4.128 33 | -------------------------------------------------------------------------------- /infrastructure/monitoring/kube-prometheus-stack.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: kube-prometheus-stack 5 | namespace: monitoring 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: kube-prometheus-stack 11 | version: "61.0.0" 12 | sourceRef: 13 | kind: HelmRepository 14 | name: prometheus-community 15 | namespace: monitoring 16 | interval: 1h 17 | upgrade: 18 | crds: CreateReplace 19 | values: 20 | grafana: 21 | ingress: 22 | enabled: true 23 | annotations: 24 | kubernetes.io/ingress.class: nginx-internal 25 | cert-manager.io/cluster-issuer: letsencrypt-prod 26 | hosts: 27 | - grafana.bo0tzz.me 28 | tls: 29 | - hosts: 30 | - grafana.bo0tzz.me 31 | secretName: grafana-web-tls 32 | persistence: 33 | enabled: true 34 | storageClassName: zfs-iscsi 35 | prometheus: 36 | prometheusSpec: 37 | serviceMonitorSelectorNilUsesHelmValues: false 38 | podMonitorSelectorNilUsesHelmValues: false 39 | retention: 1y 40 | storageSpec: 41 | volumeClaimTemplate: 42 | spec: 43 | storageClassName: zfs-iscsi 44 | accessModes: ["ReadWriteOnce"] 45 | resources: 46 | requests: 47 | storage: 200Gi 48 | additionalScrapeConfigs: 49 | - job_name: "apcups" 50 | static_configs: 51 | - targets: 52 | - 10.0.0.5 53 | metrics_path: /snmp 54 | params: 55 | module: [apcups] 56 | relabel_configs: 57 | - source_labels: [__address__] 58 | target_label: __param_target 59 | - source_labels: [__param_target] 60 | target_label: instance 61 | - target_label: __address__ 62 | replacement: snmp-exporter-prometheus-snmp-exporter:9116 63 | - job_name: zigbee2mqtt 64 | scrape_interval: 15s 65 | scrape_timeout: 10s 66 | honor_timestamps: true 67 | static_configs: 68 | - targets: 69 | - "zigbee2mqtt-exporter.automation" 70 | - job_name: pve 71 | static_configs: 72 | - targets: ['192.168.2.1:9100'] 73 | -------------------------------------------------------------------------------- /infrastructure/monitoring/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: monitoring 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /infrastructure/monitoring/repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: prometheus-community 5 | namespace: monitoring 6 | spec: 7 | interval: 1h 8 | url: https://prometheus-community.github.io/helm-charts 9 | --- 10 | apiVersion: source.toolkit.fluxcd.io/v1beta2 11 | kind: HelmRepository 12 | metadata: 13 | name: bjw-s-charts 14 | namespace: monitoring 15 | spec: 16 | interval: 1h 17 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /infrastructure/monitoring/shelly-exporter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: shelly-exporter 5 | namespace: monitoring 6 | spec: 7 | interval: 30m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.0.4 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: monitoring 16 | values: 17 | controllers: 18 | main: 19 | containers: 20 | app: 21 | image: 22 | repository: ghcr.io/cimnine/shelly-openmetrics-exporter 23 | tag: v0.4.1@sha256:64b509317c5ad817618d318a4c88d639214aa6762e2dd6634b1d55b218bc3be4 24 | resources: 25 | requests: 26 | cpu: 15m 27 | memory: 30Mi 28 | limits: 29 | memory: 50Mi 30 | service: 31 | main: 32 | controller: main 33 | ports: 34 | http: 35 | port: 54901 36 | serviceMonitor: 37 | main: 38 | serviceName: shelly-exporter 39 | endpoints: 40 | - port: http 41 | scheme: http 42 | path: /probe 43 | interval: 30s 44 | scrapeTimeout: 10s 45 | params: 46 | target: ["192.168.178.8"] 47 | metricRelabelings: 48 | - action: labeldrop 49 | regex: (pod) 50 | -------------------------------------------------------------------------------- /infrastructure/monitoring/snmp-exporter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: snmp-exporter 5 | namespace: monitoring 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: prometheus-snmp-exporter 11 | version: '9.3.1' 12 | sourceRef: 13 | kind: HelmRepository 14 | name: prometheus-community 15 | namespace: monitoring 16 | interval: 1h -------------------------------------------------------------------------------- /infrastructure/storage/democratic-csi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: democratic-csi-charts 5 | namespace: storage 6 | spec: 7 | interval: 1h 8 | url: https://democratic-csi.github.io/charts/ 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: democratic-csi-iscsi 14 | namespace: storage 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: democratic-csi 20 | version: 0.14.7 21 | sourceRef: 22 | kind: HelmRepository 23 | name: democratic-csi-charts 24 | namespace: storage 25 | values: 26 | csiDriver: 27 | name: "org.democratic-csi.zfs-iscsi" 28 | installCRD: true 29 | 30 | driver: 31 | existingConfigSecret: zfs-generic-iscsi-config 32 | config: 33 | driver: zfs-generic-iscsi 34 | 35 | controller: 36 | driver: 37 | image: ghcr.io/democratic-csi/democratic-csi:v1.9.3 38 | 39 | node: 40 | driver: 41 | image: ghcr.io/democratic-csi/democratic-csi:v1.9.3 42 | 43 | csiProxy: 44 | image: ghcr.io/democratic-csi/csi-grpc-proxy:v0.5.6 45 | 46 | storageClasses: 47 | - name: zfs-iscsi 48 | defaultClass: false 49 | reclaimPolicy: Delete 50 | volumeBindingMode: Immediate 51 | allowVolumeExpansion: true 52 | parameters: 53 | fsType: ext4 54 | 55 | volumeSnapshotClasses: 56 | - name: zfs-iscsi 57 | deletionPolicy: Delete -------------------------------------------------------------------------------- /infrastructure/storage/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: storage -------------------------------------------------------------------------------- /infrastructure/storage/snapshot-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: piraeus-charts 5 | namespace: storage 6 | spec: 7 | interval: 1h 8 | url: https://piraeus.io/helm-charts/ 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: snapshot-controller 14 | namespace: storage 15 | spec: 16 | interval: 1h 17 | chart: 18 | spec: 19 | chart: snapshot-controller 20 | version: 2.2.2 21 | sourceRef: 22 | kind: HelmRepository 23 | name: piraeus-charts 24 | namespace: storage 25 | upgrade: 26 | crds: CreateReplace 27 | -------------------------------------------------------------------------------- /infrastructure/storage/volsync.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: backube-charts 5 | namespace: storage 6 | spec: 7 | interval: 2h 8 | url: https://backube.github.io/helm-charts/ 9 | --- 10 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 11 | kind: HelmRelease 12 | metadata: 13 | name: volsync 14 | namespace: storage 15 | spec: 16 | interval: 15m 17 | chart: 18 | spec: 19 | chart: volsync 20 | version: 0.12.1 21 | sourceRef: 22 | kind: HelmRepository 23 | name: backube-charts 24 | namespace: storage 25 | maxHistory: 3 26 | install: 27 | createNamespace: true 28 | remediation: 29 | retries: 3 30 | upgrade: 31 | cleanupOnFail: true 32 | remediation: 33 | retries: 3 34 | uninstall: 35 | keepHistory: false 36 | values: 37 | manageCRDs: true 38 | metrics: 39 | disableAuth: true 40 | -------------------------------------------------------------------------------- /infrastructure/storage/zfs-generic-iscsi-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: zfs-generic-iscsi-config 5 | namespace: storage 6 | stringData: 7 | driver-config-file.yaml: ENC[AES256_GCM,data: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,iv:dGAAYUcDKwWWFbTp0OoXNcCrMAWP0iCvkiX4qxfPGjU=,tag:YkHPQsvgqtFIt9SWaY0+gg==,type:str] 8 | sops: 9 | kms: [] 10 | gcp_kms: [] 11 | azure_kv: [] 12 | hc_vault: [] 13 | age: [] 14 | lastmodified: "2022-06-20T15:23:44Z" 15 | mac: ENC[AES256_GCM,data:IReON67BhQY8XY0S8PIXy9geHbzFoi0sMIvOK3YRukMBfz++NhdSyGNToGc/7WzsuXulkY5s1Jjl0ZJFX5rsr7B2y3UGHRCXlAZtshT+4YHZxb5lJ5kj1oLw5hLZC1K62P40nTFz5z6P7790OX0PN8YW0hpJijK8nUHKwnXXQKk=,iv:qTsW3P5oPpN9PvTmb6wl0y6FggbrHRBQEkGvZF+yow0=,tag:zuK7ww5qD4xUa4rp4DPWgQ==,type:str] 16 | pgp: 17 | - created_at: "2022-06-20T15:23:43Z" 18 | enc: | 19 | -----BEGIN PGP MESSAGE----- 20 | 21 | hQIMA2YE/I5Bjk+6AQ//UGZqxwlVIbrzqAL2fKXgKjzQ0eGXh3gwdey68QnP0Sgv 22 | 3Y30O5uBsDTghgsFTOe0S7aks28YQgZXyODkzbDdcdWM3t4KK+vKwKZ5zofRfT2B 23 | 8Kk/+niD3alVAJy9iK7Grl1ba+TnMcsAAUgWn4vrI6OMjhFvzssDx1Fxxiw7Q4U6 24 | L9rnj1zQNa3d6vWg4V+rQlqw3a9qICDb1+O+0NOxLrnEfAjVby2WCe2BMTjWb4vc 25 | 0SLqWrtQdEoPJ846Yi/wHxa+wVlhFIjbpwcRR93L0NtAfo6Vk9BnlsHdhBnhD2us 26 | PkNxdFmhqWk+3UnylSTm2YGJgeMUfImMFKYX0YhV4CRBxyTmhBjcTiqjSzQBKhoC 27 | vp2+/DzgA1L9A/MhIpZopKJ+zfvXgqfVn9FcrKIHdyXMgQrnVqAH5v3PuWfrSjYl 28 | JCPEa7uO6j/ePMacpLywcoetfD1q6KbLqMvGs8zGZw4YYP3ZlBF/7+d+qoiBn/jC 29 | O5xO8NgLGmcRkvjWTmECIa5/4bqx+5diDAo8EbeB1avR2CY3qnYH2qrmZu91rFnc 30 | /ybgcjtlUUR572Nc5zbJ9jiK4pPOETHvdFnA/kHmUiej7KqE0ISHPllaIGpa3XLX 31 | 4UWtXAskKHwq24S2EPhgO9UC7Z9wl5b5G4O4B2xmeLrzQtZ/tiB6E6HCz+xq+/rU 32 | aAEJAhBIeEd0xFNLK25F1QYKriVeypmt/HDPBr5pli/Itx2XFNhqGXcSr2BRW4fL 33 | Z124r1Q/8mY+0+CFLbqpQXRZMnmb5lMsuOgPCxLaz6KtmhwQTz4r1x/KaS/JfvG3 34 | Hb6WW5MqIgbH 35 | =4LDD 36 | -----END PGP MESSAGE----- 37 | fp: DB3395B20E82DA5501D7B353AF52965D73D119F7 38 | encrypted_regex: ^(data|stringData)$ 39 | version: 3.7.3 40 | -------------------------------------------------------------------------------- /infrastructure/system/generic-device-plugin/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | devices: 3 | - name: rtlsdr 4 | groups: 5 | - count: 1 6 | usb: 7 | - vendor: "0bda" 8 | product: "2838" 9 | -------------------------------------------------------------------------------- /infrastructure/system/generic-device-plugin/hr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: generic-device-plugin 5 | namespace: system 6 | spec: 7 | interval: 30m 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 3.7.1 12 | interval: 30m 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: system 17 | values: 18 | controllers: 19 | generic-device-plugin: 20 | type: daemonset 21 | strategy: RollingUpdate 22 | containers: 23 | app: 24 | image: 25 | repository: ghcr.io/squat/generic-device-plugin 26 | tag: a4eabe9fbda65b11afe5a745093730ca7d468c26@sha256:8f4b616ff1ef70126be150fab41d4bb4445c80469b6cd8a1ca5a6c3e1c7f111d 27 | args: 28 | - --log-level=debug 29 | - --config=/config/config.yaml 30 | resources: 31 | requests: 32 | cpu: 10m 33 | limits: 34 | memory: 64Mi 35 | # Apparently necessary to avoid some conflict in /dev? 36 | terminationMessagePath: /tmp/term 37 | securityContext: 38 | privileged: true 39 | readOnlyRootFilesystem: true 40 | persistence: 41 | config: 42 | type: configMap 43 | name: generic-device-plugin 44 | globalMounts: 45 | - path: /config/config.yaml 46 | subPath: config.yaml 47 | readOnly: true 48 | dev: 49 | type: hostPath 50 | hostPath: /dev 51 | globalMounts: 52 | - readOnly: true 53 | sys: 54 | type: hostPath 55 | hostPath: /sys 56 | globalMounts: 57 | - readOnly: true 58 | var-lib-kubelet-device-plugins: 59 | type: hostPath 60 | hostPath: /var/lib/kubelet/device-plugins 61 | -------------------------------------------------------------------------------- /infrastructure/system/generic-device-plugin/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ./hr.yaml 5 | configMapGenerator: 6 | - name: generic-device-plugin 7 | namespace: system 8 | files: 9 | - ./config.yaml 10 | generatorOptions: 11 | disableNameSuffixHash: true -------------------------------------------------------------------------------- /infrastructure/system/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s-charts 5 | namespace: system 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ 9 | -------------------------------------------------------------------------------- /infrastructure/system/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: system -------------------------------------------------------------------------------- /media/bazarr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: bazarr 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 2.5.0 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | controllers: 19 | main: 20 | containers: 21 | main: 22 | image: 23 | repository: ghcr.io/home-operations/bazarr 24 | tag: 1.5.2@sha256:e569e3dd344a9a83e948f12eb7fd2c58ab051d0af5507ba69cacfdb5119a8362 25 | probes: 26 | liveness: &probes 27 | enabled: true 28 | custom: true 29 | spec: 30 | httpGet: 31 | path: /health 32 | port: &port 6767 33 | initialDelaySeconds: 0 34 | periodSeconds: 10 35 | timeoutSeconds: 1 36 | failureThreshold: 3 37 | readiness: *probes 38 | startup: 39 | enabled: false 40 | resources: 41 | requests: 42 | cpu: 10m 43 | limits: 44 | memory: 1Gi 45 | pod: 46 | securityContext: 47 | runAsUser: 568 48 | runAsGroup: 568 49 | fsGroup: 568 50 | fsGroupChangePolicy: OnRootMismatch 51 | ingress: 52 | main: 53 | enabled: true 54 | annotations: 55 | kubernetes.io/ingress.class: nginx-internal 56 | cert-manager.io/cluster-issuer: letsencrypt-prod 57 | hosts: 58 | - host: &host bazarr.bo0tzz.me 59 | paths: 60 | - path: / 61 | service: 62 | name: main 63 | port: http 64 | tls: 65 | - secretName: bazarr-tls 66 | hosts: 67 | - *host 68 | persistence: 69 | config: 70 | enabled: true 71 | storageClass: zfs-iscsi 72 | size: 2Gi 73 | media: 74 | enabled: true 75 | existingClaim: media-library 76 | service: 77 | main: 78 | ports: 79 | http: 80 | port: *port 81 | 82 | -------------------------------------------------------------------------------- /media/bjw-s-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: HelmRepository 3 | metadata: 4 | name: bjw-s-charts 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | url: https://bjw-s-labs.github.io/helm-charts/ -------------------------------------------------------------------------------- /media/emby.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: emby 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 0.2.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | image: 19 | repository: emby/embyserver 20 | tag: 4.9.0.60 21 | env: 22 | UID: 568 23 | GID: 568 24 | service: 25 | main: 26 | ports: 27 | http: 28 | port: 8096 29 | persistence: 30 | config: 31 | enabled: true 32 | storageClass: zfs-iscsi 33 | size: 20Gi 34 | media: 35 | enabled: true 36 | existingClaim: media-library 37 | ingress: 38 | main: 39 | enabled: true 40 | annotations: 41 | kubernetes.io/ingress.class: nginx-internal 42 | cert-manager.io/cluster-issuer: letsencrypt-prod 43 | hosts: 44 | - host: emby.bo0tzz.me 45 | paths: 46 | - path: / 47 | pathType: Prefix 48 | tls: 49 | - hosts: 50 | - emby.bo0tzz.me 51 | secretName: emby-web-tls 52 | external: 53 | enabled: true 54 | annotations: 55 | kubernetes.io/ingress.class: nginx 56 | cert-manager.io/cluster-issuer: letsencrypt-prod 57 | external-dns.alpha.kubernetes.io/target: bo0tzz.me 58 | auth.kube.bo0tzz.me/enabled: "true" 59 | hosts: 60 | - host: emby-external.bo0tzz.me 61 | paths: 62 | - path: / 63 | pathType: Prefix 64 | tls: 65 | - hosts: 66 | - emby-external.bo0tzz.me 67 | secretName: emby-external-web-tls 68 | resources: 69 | requests: 70 | cpu: 1 71 | memory: 1G 72 | limits: 73 | memory: 1.5G 74 | -------------------------------------------------------------------------------- /media/media-library.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: media-library 5 | namespace: media 6 | spec: 7 | storageClassName: manual 8 | capacity: 9 | storage: 1T 10 | accessModes: 11 | - ReadWriteMany 12 | nfs: 13 | server: 192.168.2.1 14 | path: "/rpool/media" 15 | --- 16 | apiVersion: v1 17 | kind: PersistentVolumeClaim 18 | metadata: 19 | name: media-library 20 | namespace: media 21 | annotations: 22 | k8up.io/backup: false 23 | spec: 24 | storageClassName: manual 25 | volumeName: media-library 26 | accessModes: 27 | - ReadWriteMany 28 | resources: 29 | requests: 30 | storage: 1T -------------------------------------------------------------------------------- /media/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: media 5 | labels: 6 | goldilocks.fairwinds.com/enabled: "true" 7 | -------------------------------------------------------------------------------- /media/ombi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: ombi 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 0.2.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | image: 19 | repository: ghcr.io/linuxserver/ombi 20 | tag: 4.48.5-development 21 | service: 22 | main: 23 | ports: 24 | http: 25 | port: 3579 26 | dnsConfig: 27 | options: 28 | - name: ndots 29 | value: "1" 30 | persistence: 31 | config: 32 | enabled: true 33 | storageClass: zfs-iscsi 34 | ingress: 35 | main: 36 | enabled: true 37 | annotations: 38 | kubernetes.io/ingress.class: nginx-internal 39 | cert-manager.io/cluster-issuer: letsencrypt-prod 40 | hosts: 41 | - host: ombi.bo0tzz.me 42 | paths: 43 | - path: / 44 | pathType: Prefix 45 | tls: 46 | - hosts: 47 | - ombi.bo0tzz.me 48 | secretName: ombi-web-tls 49 | resources: 50 | requests: 51 | cpu: 20m 52 | memory: 400M -------------------------------------------------------------------------------- /media/prowlarr.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 3 | kind: HelmRelease 4 | metadata: 5 | name: prowlarr 6 | namespace: media 7 | spec: 8 | interval: 15m 9 | chart: 10 | spec: 11 | chart: app-template 12 | version: 1.5.1 13 | sourceRef: 14 | kind: HelmRepository 15 | name: bjw-s-charts 16 | namespace: media 17 | install: 18 | remediation: 19 | retries: 3 20 | upgrade: 21 | remediation: 22 | retries: 3 23 | values: 24 | image: 25 | repository: ghcr.io/home-operations/prowlarr 26 | tag: 1.36.2.5059@sha256:8b998084a1696afb0bdc2e4c2a9750ac4e0f26528fc3db6fa77d7339811f305f 27 | service: 28 | main: 29 | ports: 30 | http: 31 | port: 9696 32 | ingress: 33 | main: 34 | enabled: true 35 | annotations: 36 | kubernetes.io/ingress.class: nginx-internal 37 | cert-manager.io/cluster-issuer: letsencrypt-prod 38 | hosts: 39 | - host: prowlarr.bo0tzz.me 40 | paths: 41 | - path: / 42 | pathType: Prefix 43 | tls: 44 | - hosts: 45 | - prowlarr.bo0tzz.me 46 | secretName: prowlarr-web-tls 47 | persistence: 48 | config: 49 | enabled: true 50 | storageClass: zfs-iscsi 51 | podSecurityContext: 52 | runAsUser: 568 53 | runAsGroup: 568 54 | fsGroup: 568 55 | fsGroupChangePolicy: "OnRootMismatch" 56 | resources: 57 | requests: 58 | cpu: 10m 59 | memory: 100Mi 60 | limits: 61 | memory: 500Mi 62 | -------------------------------------------------------------------------------- /media/qbittorrent.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: qbittorrent 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 0.2.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | image: 19 | repository: ghcr.io/home-operations/qbittorrent 20 | tag: 5.1.0@sha256:fe26058628e9eb57b542204b76443b7304ed8820151d51b5c285e1828ca175a0 21 | dnsConfig: 22 | options: 23 | - name: ndots 24 | value: "1" 25 | service: 26 | main: 27 | ports: 28 | http: 29 | port: 8080 30 | bittorrent: 31 | enabled: true 32 | type: ClusterIP 33 | ports: 34 | bittorrent: 35 | enabled: true 36 | port: 6881 37 | protocol: TCP 38 | targetPort: 6881 39 | podSecurityContext: 40 | runAsUser: 568 41 | runAsGroup: 568 42 | fsGroup: 568 43 | fsGroupChangePolicy: "OnRootMismatch" 44 | persistence: 45 | config: 46 | enabled: true 47 | storageClass: zfs-iscsi 48 | media: 49 | enabled: true 50 | existingClaim: media-library 51 | ingress: 52 | main: 53 | enabled: true 54 | annotations: 55 | kubernetes.io/ingress.class: nginx-internal 56 | cert-manager.io/cluster-issuer: letsencrypt-prod 57 | hosts: 58 | - host: qbittorrent.bo0tzz.me 59 | paths: 60 | - path: / 61 | pathType: Prefix 62 | tls: 63 | - hosts: 64 | - qbittorrent.bo0tzz.me 65 | secretName: qbittorrent-web-tls 66 | resources: 67 | requests: 68 | cpu: 20m 69 | memory: 150M -------------------------------------------------------------------------------- /media/radarr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: radarr 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 0.2.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | image: 19 | repository: ghcr.io/home-operations/radarr 20 | tag: 5.25.0@sha256:512dee5af5226f4952413fac01d599e89a24107f21ae451ef44644c779bf4f7d 21 | service: 22 | main: 23 | ports: 24 | http: 25 | port: 7878 26 | dnsConfig: 27 | options: 28 | - name: ndots 29 | value: "1" 30 | podSecurityContext: 31 | runAsUser: 568 32 | runAsGroup: 568 33 | fsGroup: 568 34 | fsGroupChangePolicy: "OnRootMismatch" 35 | persistence: 36 | config: 37 | enabled: true 38 | storageClass: zfs-iscsi 39 | media: 40 | enabled: true 41 | existingClaim: media-library 42 | ingress: 43 | main: 44 | enabled: true 45 | annotations: 46 | kubernetes.io/ingress.class: nginx-internal 47 | cert-manager.io/cluster-issuer: letsencrypt-prod 48 | hosts: 49 | - host: radarr.bo0tzz.me 50 | paths: 51 | - path: / 52 | pathType: Prefix 53 | tls: 54 | - hosts: 55 | - radarr.bo0tzz.me 56 | secretName: radarr-web-tls 57 | resources: 58 | requests: 59 | cpu: 20m 60 | memory: 500M -------------------------------------------------------------------------------- /media/sonarr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: sonarr 5 | namespace: media 6 | spec: 7 | interval: 1h 8 | chart: 9 | spec: 10 | chart: app-template 11 | version: 0.2.2 12 | sourceRef: 13 | kind: HelmRepository 14 | name: bjw-s-charts 15 | namespace: media 16 | interval: 1h 17 | values: 18 | image: 19 | repository: ghcr.io/home-operations/sonarr 20 | tag: 4.0.14.2938@sha256:95c3d63b46c2ff242a0b646086da557a13ef1376f415bb755b9d87c0d94d0330 21 | service: 22 | main: 23 | ports: 24 | http: 25 | port: 8989 26 | dnsConfig: 27 | options: 28 | - name: ndots 29 | value: "1" 30 | podSecurityContext: 31 | runAsUser: 568 32 | runAsGroup: 568 33 | fsGroup: 568 34 | fsGroupChangePolicy: "OnRootMismatch" 35 | persistence: 36 | config: 37 | enabled: true 38 | storageClass: zfs-iscsi 39 | size: 2Gi 40 | media: 41 | enabled: true 42 | existingClaim: media-library 43 | ingress: 44 | main: 45 | enabled: true 46 | annotations: 47 | kubernetes.io/ingress.class: nginx-internal 48 | cert-manager.io/cluster-issuer: letsencrypt-prod 49 | hosts: 50 | - host: sonarr.bo0tzz.me 51 | paths: 52 | - path: / 53 | pathType: Prefix 54 | tls: 55 | - hosts: 56 | - sonarr.bo0tzz.me 57 | secretName: sonarr-web-tls 58 | resources: 59 | requests: 60 | cpu: 20m 61 | memory: 500M 62 | -------------------------------------------------------------------------------- /media/twitch-dl.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: twitch-download 5 | namespace: media 6 | annotations: 7 | kustomize.toolkit.fluxcd.io/force: enabled 8 | spec: 9 | template: 10 | spec: 11 | restartPolicy: OnFailure 12 | containers: 13 | - name: yt-dlp 14 | image: "ghcr.io/bo0tzz/yt-dlp:latest" 15 | imagePullPolicy: Always 16 | args: 17 | - "--newline" 18 | - "-P" 19 | - "/library/twitch" 20 | - "--download-sections" 21 | - "*890-" 22 | - "--exec" 23 | - 'set -x && ffmpeg -f lavfi -i "movie=%(filepath)q[out0+subcc]" %(filepath)q.srt -y && sed -i.sed s/\\\\h//g %(filepath)q.srt && ffmpeg -itsoffset -1 -i %(filepath)q.srt %(filepath)q.offset.srt' 24 | - "https://www.twitch.tv/videos/1754072907" 25 | volumeMounts: 26 | - name: library 27 | mountPath: /library 28 | volumes: 29 | - name: library 30 | persistentVolumeClaim: 31 | claimName: media-library 32 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:recommended", 4 | ":disableRateLimiting", 5 | ":dependencyDashboard", 6 | ":semanticCommits" 7 | ], 8 | "automerge": true, 9 | "rebaseWhen": "conflicted", 10 | "suppressNotifications": [ 11 | "prIgnoreNotification" 12 | ], 13 | "helm-values": { 14 | "fileMatch": [ 15 | "\\.yaml$" 16 | ] 17 | }, 18 | "kubernetes": { 19 | "fileMatch": [ 20 | "\\.yaml$" 21 | ], 22 | "ignorePaths": [ 23 | "**/flux-system/**" 24 | ] 25 | }, 26 | "flux": { 27 | "fileMatch": [ 28 | "\\.yaml$" 29 | ] 30 | }, 31 | "customManagers": [ 32 | { 33 | "customType": "regex", 34 | "description": "Process custom dependencies", 35 | "fileMatch": [ 36 | "\\.ya?ml$" 37 | ], 38 | "matchStrings": [ 39 | "datasource=(?\\S+) depName=(?\\S+)( versioning=(?\\S+))?\n.*?\"(?.*)\"\n" 40 | ], 41 | "datasourceTemplate": "{{#if datasource}}{{{datasource}}}{{else}}github-releases{{/if}}", 42 | "versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}" 43 | } 44 | ], 45 | "packageRules": [ 46 | { 47 | "matchDatasources": [ 48 | "helm" 49 | ], 50 | "ignoreDeprecated": true 51 | }, 52 | { 53 | "description": "Auto merge patch versions", 54 | "matchDatasources": [ 55 | "docker" 56 | ], 57 | "automerge": true, 58 | "ignoreTests": true, 59 | "automergeType": "branch", 60 | "matchUpdateTypes": [ 61 | "patch", 62 | "digest" 63 | ], 64 | "matchPackageNames": [ 65 | "esphome/esphome{/,}**", 66 | "ghcr.io/n8n-io/n8n{/,}**", 67 | "ghcr.io/auricom/libreddit{/,}**", 68 | "quay.io/redlib/redlib{/,}**" 69 | ] 70 | }, 71 | { 72 | "description": "Auto merge minor versions", 73 | "matchDatasources": [ 74 | "docker" 75 | ], 76 | "automerge": true, 77 | "ignoreTests": true, 78 | "automergeType": "branch", 79 | "matchUpdateTypes": [ 80 | "minor" 81 | ], 82 | "matchPackageNames": [ 83 | "ghcr.io/n8n-io/n8n{/,}**" 84 | ] 85 | } 86 | ] 87 | } 88 | --------------------------------------------------------------------------------