From 35b77bb0df91810e643e1df8a12485e29285e445 Mon Sep 17 00:00:00 2001 From: alexlebens Date: Wed, 22 May 2024 12:49:28 -0500 Subject: [PATCH] init --- .../renovate-update-notification/Dockerfile | 2 + .github/renovate.json | 175 ++++++ .github/workflows/lint-test.yaml | 37 ++ LICENSE | 201 ++++++ README.md | 7 + .../applications/audiobookshelf/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 40 ++ .../templates/persistent-volume.yaml | 25 + .../applications/audiobookshelf/values.yaml | 48 ++ .../applications/calibre-server/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 19 + .../templates/persistent-volume.yaml | 25 + .../applications/calibre-server/values.yaml | 20 + .../applications/calibre-web/Chart.yaml | 11 + .../calibre-web/templates/ingress-route.yaml | 33 + .../calibre-web/templates/middleware.yaml | 27 + .../templates/persistent-volume-claim.yaml | 19 + .../templates/persistent-volume.yaml | 25 + .../applications/calibre-web/values.yaml | 33 + .../applications/code-server/Chart.yaml | 12 + .../templates/external-secret.yaml | 23 + .../templates/persistent-volume-claim.yaml | 19 + .../applications/code-server/values.yaml | 34 + clusters/cl01tl/applications/cops/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 19 + .../cops/templates/persistent-volume.yaml | 25 + clusters/cl01tl/applications/cops/values.yaml | 22 + .../cl01tl/applications/freshrss/Chart.yaml | 15 + .../freshrss/templates/external-secret.yaml | 94 +++ .../cl01tl/applications/freshrss/values.yaml | 42 ++ .../applications/home-assistant/Chart.yaml | 11 + .../templates/external-secret.yaml | 48 ++ .../applications/home-assistant/values.yaml | 46 ++ .../applications/homepage-dev/Chart.yaml | 18 + .../templates/external-secret.yaml | 23 + .../applications/homepage-dev/values.yaml | 225 +++++++ .../cl01tl/applications/homepage/Chart.yaml | 12 + .../homepage/templates/external-secret.yaml | 44 ++ .../cl01tl/applications/homepage/values.yaml | 420 +++++++++++++ .../cl01tl/applications/jellyfin/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 40 ++ .../jellyfin/templates/persistent-volume.yaml | 52 ++ .../cl01tl/applications/jellyfin/values.yaml | 55 ++ clusters/cl01tl/applications/kyoo/Chart.yaml | 32 + .../kyoo/templates/external-secret.yaml | 183 ++++++ .../kyoo/templates/ingress-route.yaml | 32 + .../kyoo/templates/middleware.yaml | 15 + .../templates/persistent-volume-claim.yaml | 229 +++++++ .../kyoo/templates/persistent-volume.yaml | 295 +++++++++ clusters/cl01tl/applications/kyoo/values.yaml | 590 ++++++++++++++++++ .../cl01tl/applications/libation/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 19 + .../libation/templates/persistent-volume.yaml | 25 + .../cl01tl/applications/libation/values.yaml | 14 + .../cl01tl/applications/navidrome/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 19 + .../templates/persistent-volume.yaml | 25 + .../cl01tl/applications/navidrome/values.yaml | 43 ++ .../cl01tl/applications/outline/Chart.yaml | 21 + .../outline/templates/external-secret.yaml | 176 ++++++ .../cl01tl/applications/outline/values.yaml | 123 ++++ .../cl01tl/applications/penpot/Chart.yaml | 25 + .../penpot/templates/external-secret.yaml | 169 +++++ .../cl01tl/applications/penpot/values.yaml | 135 ++++ clusters/cl01tl/applications/plex/Chart.yaml | 11 + .../templates/persistent-volume-claim.yaml | 40 ++ .../plex/templates/persistent-volume.yaml | 25 + clusters/cl01tl/applications/plex/values.yaml | 78 +++ clusters/cl01tl/applications/taiga/Chart.yaml | 17 + .../taiga/templates/external-secret.yaml | 200 ++++++ .../cl01tl/applications/taiga/values.yaml | 152 +++++ .../applications/tubearchivist/Chart.yaml | 13 + .../templates/external-secret.yaml | 83 +++ .../templates/persistent-volume-claim.yaml | 19 + .../templates/persistent-volume.yaml | 25 + .../applications/tubearchivist/values.yaml | 46 ++ .../cl01tl/applications/vikunja/Chart.yaml | 20 + .../vikunja/templates/external-secret.yaml | 62 ++ .../cl01tl/applications/vikunja/values.yaml | 117 ++++ .../deployment/argo-rollouts/Chart.yaml | 11 + .../deployment/argo-rollouts/values.yaml | 45 ++ .../deployment/argo-workflows/Chart.yaml | 20 + .../templates/external-secret.yaml | 62 ++ .../deployment/argo-workflows/values.yaml | 121 ++++ clusters/cl01tl/deployment/argocd/Chart.yaml | 12 + .../argocd/templates/external-secret.yaml | 110 ++++ clusters/cl01tl/deployment/argocd/values.yaml | 66 ++ clusters/cl01tl/deployment/kargo/Chart.yaml | 11 + .../kargo/templates/external-secret.yaml | 56 ++ clusters/cl01tl/deployment/kargo/values.yaml | 120 ++++ clusters/cl01tl/deployment/stack/Chart.yaml | 6 + .../stack/templates/application-set.yaml | 55 ++ .../stack/templates/application.yaml | 82 +++ clusters/cl01tl/deployment/stack/values.yaml | 148 +++++ clusters/cl01tl/platform/authentik/Chart.yaml | 21 + .../authentik/templates/config-map.yaml | 60 ++ .../authentik/templates/external-secret.yaml | 80 +++ .../cl01tl/platform/authentik/values.yaml | 118 ++++ .../platform/external-secrets/Chart.yaml | 11 + .../templates/cluster-secret-store.yaml | 21 + clusters/cl01tl/platform/gitea/Chart.yaml | 16 + .../gitea/templates/external-secret.yaml | 94 +++ clusters/cl01tl/platform/gitea/values.yaml | 96 +++ clusters/cl01tl/platform/grafana/Chart.yaml | 11 + .../grafana/templates/external-secret.yaml | 62 ++ clusters/cl01tl/platform/grafana/values.yaml | 142 +++++ clusters/cl01tl/platform/headlamp/Chart.yaml | 11 + .../templates/cluster-role-binding.yaml | 19 + .../headlamp/templates/external-secret.yaml | 30 + clusters/cl01tl/platform/headlamp/values.yaml | 48 ++ clusters/cl01tl/platform/pgadmin/Chart.yaml | 11 + .../pgadmin/templates/external-secret.yaml | 62 ++ clusters/cl01tl/platform/pgadmin/values.yaml | 40 ++ clusters/cl01tl/platform/portainer/Chart.yaml | 11 + .../cl01tl/platform/portainer/values.yaml | 35 ++ clusters/cl01tl/platform/vault/Chart.yaml | 11 + .../platform/vault/templates/cron-job.yaml | 64 ++ .../platform/vault/templates/ingress.yaml | 26 + .../templates/persistent-volume-claim.yaml | 19 + clusters/cl01tl/platform/vault/values.yaml | 170 +++++ .../cl01tl/services/cert-manager/Chart.yaml | 11 + .../templates/cluster-issuer.yaml | 21 + .../cl01tl/services/cert-manager/values.yaml | 11 + .../services/intel-device-plugin/Chart.yaml | 13 + .../services/intel-device-plugin/values.yaml | 28 + .../services/kube-prometheus-stack/Chart.yaml | 11 + .../templates/external-secret.yaml | 37 ++ .../kube-prometheus-stack/values.yaml | 140 +++++ .../kubernetes-cloudflare-ddns/Chart.yaml | 11 + .../templates/external-secret.yaml | 44 ++ .../kubernetes-cloudflare-ddns/values.yaml | 12 + clusters/cl01tl/services/loki/Chart.yaml | 14 + clusters/cl01tl/services/loki/values.yaml | 48 ++ clusters/cl01tl/services/metallb/Chart.yaml | 11 + .../metallb/templates/ip-address-pool.yaml | 16 + .../services/metallb/templates/namespace.yaml | 8 + clusters/cl01tl/services/metallb/values.yaml | 15 + .../node-feature-discovery/Chart.yaml | 10 + .../node-feature-discovery/values.yaml | 256 ++++++++ clusters/cl01tl/services/reloader/Chart.yaml | 11 + clusters/cl01tl/services/reloader/values.yaml | 5 + .../services/speedtest-exporter/Chart.yaml | 11 + .../services/speedtest-exporter/values.yaml | 16 + .../services/tailscale-operator/Chart.yaml | 11 + .../templates/external-secrets.yaml | 30 + .../services/tailscale-operator/values.yaml | 22 + clusters/cl01tl/services/traefik/Chart.yaml | 11 + .../traefik/templates/certificate.yaml | 19 + clusters/cl01tl/services/traefik/values.yaml | 82 +++ clusters/cl01tl/services/unpoller/Chart.yaml | 11 + .../unpoller/templates/external-secret.yaml | 30 + clusters/cl01tl/services/unpoller/values.yaml | 33 + clusters/cl01tl/standalone/cilium/Chart.yaml | 11 + clusters/cl01tl/standalone/cilium/values.yaml | 71 +++ .../kubelet-serving-cert-approver/Chart.yaml | 11 + .../standalone/metrics-server/Chart.yaml | 11 + .../standalone/metrics-server/values.yaml | 12 + .../prometheus-operator-crds/Chart.yaml | 11 + .../cl01tl/storage/cloudnative-pg/Chart.yaml | 11 + .../cl01tl/storage/cloudnative-pg/values.yaml | 4 + .../democratic-csi-synology-iscsi/Chart.yaml | 11 + .../templates/external-secret.yaml | 23 + .../democratic-csi-synology-iscsi/values.yaml | 37 ++ .../storage/local-path-provisioner/Chart.yaml | 11 + .../local-path-provisioner/values.yaml | 42 ++ .../cl01tl/storage/minio-operator/Chart.yaml | 11 + .../cl01tl/storage/minio-operator/values.yaml | 24 + clusters/cl01tl/storage/nfs/Chart.yaml | 11 + clusters/cl01tl/storage/nfs/values.yaml | 8 + clusters/cl01tl/storage/rook-ceph/Chart.yaml | 14 + clusters/cl01tl/storage/rook-ceph/values.yaml | 192 ++++++ .../ps08rp/portainer-agent/docker-compose.yml | 11 + hosts/ps08rp/tailscale/.env | 4 + hosts/ps08rp/tailscale/docker-compose.yml | 24 + hosts/ps08rp/technitium/.env | 3 + hosts/ps08rp/technitium/docker-compose.yaml | 37 ++ hosts/ps08rp/traefik/.env | 3 + hosts/ps08rp/traefik/docker-compose.yaml | 45 ++ .../traefik/traefik_config/conf/iplocal.yml | 15 + .../traefik/traefik_config/conf/metrics.yml | 8 + .../ps08rp/traefik/traefik_config/traefik.yml | 113 ++++ hosts/ps08rp/watchtower/.env | 5 + hosts/ps08rp/watchtower/docker-compose.yml | 10 + .../ps09rp/portainer-agent/docker-compose.yml | 11 + hosts/ps09rp/tailscale/.env | 11 + hosts/ps09rp/tailscale/docker-compose.yml | 24 + hosts/ps09rp/technitium/.env | 3 + hosts/ps09rp/technitium/docker-compose.yaml | 37 ++ hosts/ps09rp/traefik/.env | 3 + hosts/ps09rp/traefik/docker-compose.yaml | 45 ++ .../traefik/traefik_config/conf/iplocal.yml | 15 + .../traefik/traefik_config/conf/metrics.yml | 8 + .../ps09rp/traefik/traefik_config/traefik.yml | 113 ++++ hosts/ps09rp/watchtower/.env | 5 + hosts/ps09rp/watchtower/docker-compose.yml | 10 + hosts/ps10rp/cloudflare-ddns/.env | 3 + .../ps10rp/cloudflare-ddns/docker-compose.yml | 6 + hosts/ps10rp/gitea/.env | 8 + hosts/ps10rp/gitea/.postgresql.env | 3 + hosts/ps10rp/gitea/docker-compose.yml | 51 ++ .../Files/homepage_config/bookmarks.yaml | 1 + .../Files/homepage_config/docker.yaml | 4 + .../Files/homepage_config/services.yaml | 33 + .../Files/homepage_config/settings.yaml | 9 + .../Files/homepage_config/widgets.yaml | 15 + hosts/ps10rp/homepage/docker-compose.yml | 56 ++ hosts/ps10rp/pihole/.env | 5 + hosts/ps10rp/pihole/.exporter.env | 6 + hosts/ps10rp/pihole/docker-compose.yml | 61 ++ .../ps10rp/portainer-agent/docker-compose.yml | 10 + hosts/ps10rp/tailscale/.env | 4 + hosts/ps10rp/tailscale/docker-compose.yml | 23 + hosts/ps10rp/traefik/.env | 3 + hosts/ps10rp/traefik/docker-compose.yaml | 44 ++ .../traefik/traefik_config/conf/iplocal.yml | 15 + .../traefik/traefik_config/conf/metrics.yml | 8 + .../ps10rp/traefik/traefik_config/traefik.yml | 113 ++++ hosts/ps10rp/watchtower/.env | 5 + hosts/ps10rp/watchtower/docker-compose.yml | 9 + 219 files changed, 9997 insertions(+) create mode 100644 .github/renovate-update-notification/Dockerfile create mode 100644 .github/renovate.json create mode 100644 .github/workflows/lint-test.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 clusters/cl01tl/applications/audiobookshelf/Chart.yaml create mode 100644 clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/audiobookshelf/values.yaml create mode 100644 clusters/cl01tl/applications/calibre-server/Chart.yaml create mode 100644 clusters/cl01tl/applications/calibre-server/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/calibre-server/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/calibre-server/values.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/Chart.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/templates/ingress-route.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/templates/middleware.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/calibre-web/values.yaml create mode 100644 clusters/cl01tl/applications/code-server/Chart.yaml create mode 100644 clusters/cl01tl/applications/code-server/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/code-server/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/code-server/values.yaml create mode 100644 clusters/cl01tl/applications/cops/Chart.yaml create mode 100644 clusters/cl01tl/applications/cops/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/cops/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/cops/values.yaml create mode 100644 clusters/cl01tl/applications/freshrss/Chart.yaml create mode 100644 clusters/cl01tl/applications/freshrss/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/freshrss/values.yaml create mode 100644 clusters/cl01tl/applications/home-assistant/Chart.yaml create mode 100644 clusters/cl01tl/applications/home-assistant/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/home-assistant/values.yaml create mode 100644 clusters/cl01tl/applications/homepage-dev/Chart.yaml create mode 100644 clusters/cl01tl/applications/homepage-dev/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/homepage-dev/values.yaml create mode 100644 clusters/cl01tl/applications/homepage/Chart.yaml create mode 100644 clusters/cl01tl/applications/homepage/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/homepage/values.yaml create mode 100644 clusters/cl01tl/applications/jellyfin/Chart.yaml create mode 100644 clusters/cl01tl/applications/jellyfin/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/jellyfin/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/jellyfin/values.yaml create mode 100644 clusters/cl01tl/applications/kyoo/Chart.yaml create mode 100644 clusters/cl01tl/applications/kyoo/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/kyoo/templates/ingress-route.yaml create mode 100644 clusters/cl01tl/applications/kyoo/templates/middleware.yaml create mode 100644 clusters/cl01tl/applications/kyoo/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/kyoo/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/kyoo/values.yaml create mode 100644 clusters/cl01tl/applications/libation/Chart.yaml create mode 100644 clusters/cl01tl/applications/libation/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/libation/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/libation/values.yaml create mode 100644 clusters/cl01tl/applications/navidrome/Chart.yaml create mode 100644 clusters/cl01tl/applications/navidrome/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/navidrome/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/navidrome/values.yaml create mode 100644 clusters/cl01tl/applications/outline/Chart.yaml create mode 100644 clusters/cl01tl/applications/outline/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/outline/values.yaml create mode 100644 clusters/cl01tl/applications/penpot/Chart.yaml create mode 100644 clusters/cl01tl/applications/penpot/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/penpot/values.yaml create mode 100644 clusters/cl01tl/applications/plex/Chart.yaml create mode 100644 clusters/cl01tl/applications/plex/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/plex/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/plex/values.yaml create mode 100644 clusters/cl01tl/applications/taiga/Chart.yaml create mode 100644 clusters/cl01tl/applications/taiga/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/taiga/values.yaml create mode 100644 clusters/cl01tl/applications/tubearchivist/Chart.yaml create mode 100644 clusters/cl01tl/applications/tubearchivist/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/tubearchivist/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/applications/tubearchivist/templates/persistent-volume.yaml create mode 100644 clusters/cl01tl/applications/tubearchivist/values.yaml create mode 100644 clusters/cl01tl/applications/vikunja/Chart.yaml create mode 100644 clusters/cl01tl/applications/vikunja/templates/external-secret.yaml create mode 100644 clusters/cl01tl/applications/vikunja/values.yaml create mode 100644 clusters/cl01tl/deployment/argo-rollouts/Chart.yaml create mode 100644 clusters/cl01tl/deployment/argo-rollouts/values.yaml create mode 100644 clusters/cl01tl/deployment/argo-workflows/Chart.yaml create mode 100644 clusters/cl01tl/deployment/argo-workflows/templates/external-secret.yaml create mode 100644 clusters/cl01tl/deployment/argo-workflows/values.yaml create mode 100644 clusters/cl01tl/deployment/argocd/Chart.yaml create mode 100644 clusters/cl01tl/deployment/argocd/templates/external-secret.yaml create mode 100644 clusters/cl01tl/deployment/argocd/values.yaml create mode 100644 clusters/cl01tl/deployment/kargo/Chart.yaml create mode 100644 clusters/cl01tl/deployment/kargo/templates/external-secret.yaml create mode 100644 clusters/cl01tl/deployment/kargo/values.yaml create mode 100644 clusters/cl01tl/deployment/stack/Chart.yaml create mode 100644 clusters/cl01tl/deployment/stack/templates/application-set.yaml create mode 100644 clusters/cl01tl/deployment/stack/templates/application.yaml create mode 100644 clusters/cl01tl/deployment/stack/values.yaml create mode 100644 clusters/cl01tl/platform/authentik/Chart.yaml create mode 100644 clusters/cl01tl/platform/authentik/templates/config-map.yaml create mode 100644 clusters/cl01tl/platform/authentik/templates/external-secret.yaml create mode 100644 clusters/cl01tl/platform/authentik/values.yaml create mode 100644 clusters/cl01tl/platform/external-secrets/Chart.yaml create mode 100644 clusters/cl01tl/platform/external-secrets/templates/cluster-secret-store.yaml create mode 100644 clusters/cl01tl/platform/gitea/Chart.yaml create mode 100644 clusters/cl01tl/platform/gitea/templates/external-secret.yaml create mode 100644 clusters/cl01tl/platform/gitea/values.yaml create mode 100644 clusters/cl01tl/platform/grafana/Chart.yaml create mode 100644 clusters/cl01tl/platform/grafana/templates/external-secret.yaml create mode 100644 clusters/cl01tl/platform/grafana/values.yaml create mode 100644 clusters/cl01tl/platform/headlamp/Chart.yaml create mode 100644 clusters/cl01tl/platform/headlamp/templates/cluster-role-binding.yaml create mode 100644 clusters/cl01tl/platform/headlamp/templates/external-secret.yaml create mode 100644 clusters/cl01tl/platform/headlamp/values.yaml create mode 100644 clusters/cl01tl/platform/pgadmin/Chart.yaml create mode 100644 clusters/cl01tl/platform/pgadmin/templates/external-secret.yaml create mode 100644 clusters/cl01tl/platform/pgadmin/values.yaml create mode 100644 clusters/cl01tl/platform/portainer/Chart.yaml create mode 100644 clusters/cl01tl/platform/portainer/values.yaml create mode 100644 clusters/cl01tl/platform/vault/Chart.yaml create mode 100644 clusters/cl01tl/platform/vault/templates/cron-job.yaml create mode 100644 clusters/cl01tl/platform/vault/templates/ingress.yaml create mode 100644 clusters/cl01tl/platform/vault/templates/persistent-volume-claim.yaml create mode 100644 clusters/cl01tl/platform/vault/values.yaml create mode 100644 clusters/cl01tl/services/cert-manager/Chart.yaml create mode 100644 clusters/cl01tl/services/cert-manager/templates/cluster-issuer.yaml create mode 100644 clusters/cl01tl/services/cert-manager/values.yaml create mode 100644 clusters/cl01tl/services/intel-device-plugin/Chart.yaml create mode 100644 clusters/cl01tl/services/intel-device-plugin/values.yaml create mode 100644 clusters/cl01tl/services/kube-prometheus-stack/Chart.yaml create mode 100644 clusters/cl01tl/services/kube-prometheus-stack/templates/external-secret.yaml create mode 100644 clusters/cl01tl/services/kube-prometheus-stack/values.yaml create mode 100644 clusters/cl01tl/services/kubernetes-cloudflare-ddns/Chart.yaml create mode 100644 clusters/cl01tl/services/kubernetes-cloudflare-ddns/templates/external-secret.yaml create mode 100644 clusters/cl01tl/services/kubernetes-cloudflare-ddns/values.yaml create mode 100644 clusters/cl01tl/services/loki/Chart.yaml create mode 100644 clusters/cl01tl/services/loki/values.yaml create mode 100644 clusters/cl01tl/services/metallb/Chart.yaml create mode 100644 clusters/cl01tl/services/metallb/templates/ip-address-pool.yaml create mode 100644 clusters/cl01tl/services/metallb/templates/namespace.yaml create mode 100644 clusters/cl01tl/services/metallb/values.yaml create mode 100644 clusters/cl01tl/services/node-feature-discovery/Chart.yaml create mode 100644 clusters/cl01tl/services/node-feature-discovery/values.yaml create mode 100644 clusters/cl01tl/services/reloader/Chart.yaml create mode 100644 clusters/cl01tl/services/reloader/values.yaml create mode 100644 clusters/cl01tl/services/speedtest-exporter/Chart.yaml create mode 100644 clusters/cl01tl/services/speedtest-exporter/values.yaml create mode 100644 clusters/cl01tl/services/tailscale-operator/Chart.yaml create mode 100644 clusters/cl01tl/services/tailscale-operator/templates/external-secrets.yaml create mode 100644 clusters/cl01tl/services/tailscale-operator/values.yaml create mode 100644 clusters/cl01tl/services/traefik/Chart.yaml create mode 100644 clusters/cl01tl/services/traefik/templates/certificate.yaml create mode 100644 clusters/cl01tl/services/traefik/values.yaml create mode 100644 clusters/cl01tl/services/unpoller/Chart.yaml create mode 100644 clusters/cl01tl/services/unpoller/templates/external-secret.yaml create mode 100644 clusters/cl01tl/services/unpoller/values.yaml create mode 100644 clusters/cl01tl/standalone/cilium/Chart.yaml create mode 100644 clusters/cl01tl/standalone/cilium/values.yaml create mode 100644 clusters/cl01tl/standalone/kubelet-serving-cert-approver/Chart.yaml create mode 100644 clusters/cl01tl/standalone/metrics-server/Chart.yaml create mode 100644 clusters/cl01tl/standalone/metrics-server/values.yaml create mode 100644 clusters/cl01tl/standalone/prometheus-operator-crds/Chart.yaml create mode 100644 clusters/cl01tl/storage/cloudnative-pg/Chart.yaml create mode 100644 clusters/cl01tl/storage/cloudnative-pg/values.yaml create mode 100644 clusters/cl01tl/storage/democratic-csi-synology-iscsi/Chart.yaml create mode 100644 clusters/cl01tl/storage/democratic-csi-synology-iscsi/templates/external-secret.yaml create mode 100644 clusters/cl01tl/storage/democratic-csi-synology-iscsi/values.yaml create mode 100644 clusters/cl01tl/storage/local-path-provisioner/Chart.yaml create mode 100644 clusters/cl01tl/storage/local-path-provisioner/values.yaml create mode 100644 clusters/cl01tl/storage/minio-operator/Chart.yaml create mode 100644 clusters/cl01tl/storage/minio-operator/values.yaml create mode 100644 clusters/cl01tl/storage/nfs/Chart.yaml create mode 100644 clusters/cl01tl/storage/nfs/values.yaml create mode 100644 clusters/cl01tl/storage/rook-ceph/Chart.yaml create mode 100644 clusters/cl01tl/storage/rook-ceph/values.yaml create mode 100644 hosts/ps08rp/portainer-agent/docker-compose.yml create mode 100644 hosts/ps08rp/tailscale/.env create mode 100644 hosts/ps08rp/tailscale/docker-compose.yml create mode 100644 hosts/ps08rp/technitium/.env create mode 100644 hosts/ps08rp/technitium/docker-compose.yaml create mode 100644 hosts/ps08rp/traefik/.env create mode 100644 hosts/ps08rp/traefik/docker-compose.yaml create mode 100644 hosts/ps08rp/traefik/traefik_config/conf/iplocal.yml create mode 100644 hosts/ps08rp/traefik/traefik_config/conf/metrics.yml create mode 100644 hosts/ps08rp/traefik/traefik_config/traefik.yml create mode 100644 hosts/ps08rp/watchtower/.env create mode 100644 hosts/ps08rp/watchtower/docker-compose.yml create mode 100644 hosts/ps09rp/portainer-agent/docker-compose.yml create mode 100644 hosts/ps09rp/tailscale/.env create mode 100644 hosts/ps09rp/tailscale/docker-compose.yml create mode 100644 hosts/ps09rp/technitium/.env create mode 100644 hosts/ps09rp/technitium/docker-compose.yaml create mode 100644 hosts/ps09rp/traefik/.env create mode 100644 hosts/ps09rp/traefik/docker-compose.yaml create mode 100644 hosts/ps09rp/traefik/traefik_config/conf/iplocal.yml create mode 100644 hosts/ps09rp/traefik/traefik_config/conf/metrics.yml create mode 100644 hosts/ps09rp/traefik/traefik_config/traefik.yml create mode 100644 hosts/ps09rp/watchtower/.env create mode 100644 hosts/ps09rp/watchtower/docker-compose.yml create mode 100644 hosts/ps10rp/cloudflare-ddns/.env create mode 100644 hosts/ps10rp/cloudflare-ddns/docker-compose.yml create mode 100644 hosts/ps10rp/gitea/.env create mode 100644 hosts/ps10rp/gitea/.postgresql.env create mode 100644 hosts/ps10rp/gitea/docker-compose.yml create mode 100644 hosts/ps10rp/homepage/Files/homepage_config/bookmarks.yaml create mode 100644 hosts/ps10rp/homepage/Files/homepage_config/docker.yaml create mode 100644 hosts/ps10rp/homepage/Files/homepage_config/services.yaml create mode 100644 hosts/ps10rp/homepage/Files/homepage_config/settings.yaml create mode 100644 hosts/ps10rp/homepage/Files/homepage_config/widgets.yaml create mode 100644 hosts/ps10rp/homepage/docker-compose.yml create mode 100644 hosts/ps10rp/pihole/.env create mode 100644 hosts/ps10rp/pihole/.exporter.env create mode 100644 hosts/ps10rp/pihole/docker-compose.yml create mode 100644 hosts/ps10rp/portainer-agent/docker-compose.yml create mode 100644 hosts/ps10rp/tailscale/.env create mode 100644 hosts/ps10rp/tailscale/docker-compose.yml create mode 100644 hosts/ps10rp/traefik/.env create mode 100644 hosts/ps10rp/traefik/docker-compose.yaml create mode 100644 hosts/ps10rp/traefik/traefik_config/conf/iplocal.yml create mode 100644 hosts/ps10rp/traefik/traefik_config/conf/metrics.yml create mode 100644 hosts/ps10rp/traefik/traefik_config/traefik.yml create mode 100644 hosts/ps10rp/watchtower/.env create mode 100644 hosts/ps10rp/watchtower/docker-compose.yml diff --git a/.github/renovate-update-notification/Dockerfile b/.github/renovate-update-notification/Dockerfile new file mode 100644 index 000000000..40cc41837 --- /dev/null +++ b/.github/renovate-update-notification/Dockerfile @@ -0,0 +1,2 @@ +# This file is processed by Renovate bot so that it creates a PR on new major Renovate versions +FROM renovate/renovate:37 \ No newline at end of file diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 000000000..5fffd00ee --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,175 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + "mergeConfidence:all-badges", + ":rebaseStalePrs" + ], + "timezone": "US/Central", + "schedule": [ + "every weekday" + ], + "labels": [], + "packageRules": [ + { + "description": "Disables for non major Renovate version", + "matchPaths": [ + ".github/renovate-update-notification/Dockerfile" + ], + "matchUpdateTypes": [ + "minor", + "patch", + "pin", + "digest", + "rollback" + ], + "enabled": false + }, + { + "description": "Generate for major Renovate version", + "matchPaths": [ + ".github/renovate-update-notification/Dockerfile" + ], + "matchUpdateTypes": [ + "major" + ], + "addLabels": [ + "upgrade" + ], + "automerge": false + }, + { + "description": "Label service images", + "matchDepNames": [ + "dpage/pgadmin4", + "ghcr.io/cloudnative-pg/postgresql", + "hashicorp/vault", + "portainer/portainer-ce", + "redis/redis-stack-server", + "unpoller/unpoller" + ], + "matchDatasources": [ + "docker" + ], + "addLabels": [ + "service", + "image" + ], + "automerge": false, + "minimumReleaseAge": "3 days" + }, + { + "description": "Label service charts", + "matchDepNames": [ + "argo-cd", + "authentik", + "cert-manager", + "cilium", + "cloudnative-pg", + "democratic-csi", + "external-secrets", + "gitea", + "grafana", + "intel-device-plugins-gpu", + "intel-device-plugins-operator", + "kube-prometheus-stack", + "kubelet-serving-cert-approver", + "kubernetes-cloudflare-ddns", + "loki", + "metallb", + "metrics-server", + "nfs-subdir-external-provisioner", + "node-feature-discovery", + "pgadmin4", + "portainer", + "postgres-cluster", + "prometheus-operator-crds", + "promtail", + "redis", + "rook-ceph-cluster", + "rook-ceph", + "speedtest-exporter", + "traefik", + "unpoller", + "vault" + ], + "matchDatasources": [ + "helm" + ], + "addLabels": [ + "service", + "chart" + ], + "automerge": false, + "minimumReleaseAge": "3 days" + }, + { + "description": "Label application images", + "matchDepNames": [ + "deluan/navidrome", + "ghcr.io/advplyr/audiobookshelf", + "ghcr.io/linuxserver/calibre-web", + "jellyfin/jellyfin", + "linuxserver/code-server", + "vikunja/api", + "vikunja/frontend" + ], + "matchDatasources": [ + "docker" + ], + "addLabels": [ + "application", + "image" + ], + "automerge": false, + "minimumReleaseAge": "3 days" + }, + { + "description": "Label application charts", + "matchDepNames": [ + "audiobookshelf", + "calibre-server", + "calibre-web", + "code-server", + "cops", + "freshrss", + "home-assistant", + "homepage", + "jellyfin", + "libation", + "navidrome", + "outline", + "plex", + "tubearchivist", + "tubearchivist-to-jellyfin", + "vikunja" + ], + "matchDatasources": [ + "helm" + ], + "addLabels": [ + "application", + "chart" + ], + "automerge": false, + "minimumReleaseAge": "3 days" + }, + { + "description": "Automerge the plex image", + "matchDepNames": [ + "ghcr.io/onedr0p/plex" + ], + "matchDatasources": [ + "docker" + ], + "addLabels": [ + "application", + "image" + ], + "versioning": "regex:^(?\\d+)\\.(?\\d+)\\.(?\\d+)\\.(?\\d+)-(?.+)?$", + "automerge": true, + "automergeType": "branch", + "minimumReleaseAge": "3 days" + } + ] +} \ No newline at end of file diff --git a/.github/workflows/lint-test.yaml b/.github/workflows/lint-test.yaml new file mode 100644 index 000000000..600bde3ae --- /dev/null +++ b/.github/workflows/lint-test.yaml @@ -0,0 +1,37 @@ +name: lint-and-test-charts + +on: pull_request + +jobs: + lint-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v4 + with: + version: v3.13.3 + + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + check-latest: true + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Run chart-testing (lint) + if: steps.list-changed.outputs.changed == 'true' + run: ct lint --target-branch ${{ github.event.repository.default_branch }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 000000000..6552c274e --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# alexlebens.net + +GitOps definied infrastrucutre for the alexlebens.net domain. + +## License + +This project is licensed under the terms of the Apache 2.0 License license. diff --git a/clusters/cl01tl/applications/audiobookshelf/Chart.yaml b/clusters/cl01tl/applications/audiobookshelf/Chart.yaml new file mode 100644 index 000000000..0f6ce3572 --- /dev/null +++ b/clusters/cl01tl/applications/audiobookshelf/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: audiobookshelf +version: 0.0.1 +sources: + - https://github.com/advplyr/audiobookshelf + - https://github.com/k8s-home-lab/helm-charts/tree/master/charts/stable/audiobookshelf +dependencies: + - name: audiobookshelf + version: 2.0.0 + repository: https://k8s-home-lab.github.io/helm-charts/ +appVersion: "2.8.0" diff --git a/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..b91ce0a19 --- /dev/null +++ b/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume-claim.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: audiobookshelf-nfs-storage-backup + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeMode: Filesystem + storageClassName: nfs-client + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: audiobookshelf-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: audiobookshelf-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume.yaml b/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume.yaml new file mode 100644 index 000000000..f710f90e2 --- /dev/null +++ b/clusters/cl01tl/applications/audiobookshelf/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: audiobookshelf-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.nfs.path }} + server: {{ .Values.storage.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/audiobookshelf/values.yaml b/clusters/cl01tl/applications/audiobookshelf/values.yaml new file mode 100644 index 000000000..e3fbe37b9 --- /dev/null +++ b/clusters/cl01tl/applications/audiobookshelf/values.yaml @@ -0,0 +1,48 @@ +audiobookshelf: + image: + repository: ghcr.io/advplyr/audiobookshelf + tag: 2.9.0 + env: + TZ: US/Central + ingress: + main: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: audiobookshelf.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: audiobookshelf-secret-tls + hosts: + - audiobookshelf.alexlebens.net + persistence: + config: + enabled: true + mountPath: /config + accessMode: ReadWriteOnce + size: 2Gi + metadata: + enabled: true + mountPath: /metadata + accessMode: ReadWriteOnce + size: 10Gi + backup: + enabled: true + mountPath: /metadata/backups + type: pvc + existingClaim: audiobookshelf-nfs-storage-backup + audiobooks: + enabled: true + mountPath: /mnt/store/ + type: pvc + existingClaim: audiobookshelf-nfs-storage +storage: + nfs: + path: /volume2/Storage + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/calibre-server/Chart.yaml b/clusters/cl01tl/applications/calibre-server/Chart.yaml new file mode 100644 index 000000000..85f8176d7 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-server/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: calibre-server +version: 1.0.0 +sources: + - https://github.com/kovidgoyal/calibre + - https://github.com/alexlebens/helm-charts/tree/main/charts/calibre-server +dependencies: + - name: calibre-server + version: 0.0.8 + repository: http://alexlebens.github.io/helm-charts +appVersion: 7.5.1 diff --git a/clusters/cl01tl/applications/calibre-server/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/calibre-server/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..68c507feb --- /dev/null +++ b/clusters/cl01tl/applications/calibre-server/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: calibre-server-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: calibre-server-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/calibre-server/templates/persistent-volume.yaml b/clusters/cl01tl/applications/calibre-server/templates/persistent-volume.yaml new file mode 100644 index 000000000..f44568e96 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-server/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: calibre-server-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ index .Values "calibre-server" "persistence" "books" "nfs" "path" }} + server: {{ index .Values "calibre-server" "persistence" "books" "nfs" "server" }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/calibre-server/values.yaml b/clusters/cl01tl/applications/calibre-server/values.yaml new file mode 100644 index 000000000..d517c5271 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-server/values.yaml @@ -0,0 +1,20 @@ +calibre-server: + deployment: + env: + TZ: US/Central + ingressRoute: + enabled: true + http: + host: calibre-server.alexlebens.net + authentik: + outpost: authentik-outpost-proxy + namespace: authentik + persistence: + config: + storageClassName: ceph-block + storageSize: 5Gi + books: + claimName: calibre-server-nfs-storage + nfs: + path: /volume2/Storage/Calibre + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/calibre-web/Chart.yaml b/clusters/cl01tl/applications/calibre-web/Chart.yaml new file mode 100644 index 000000000..d0fe1eaf2 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: calibre-web +version: 0.0.1 +sources: + - https://github.com/janeczku/calibre-web + - https://github.com/k8s-home-lab/helm-charts/tree/master/charts/stable/calibre-web +dependencies: + - name: calibre-web + version: 9.0.2 + repository: https://k8s-home-lab.github.io/helm-charts/ +appVersion: v0.6.21 diff --git a/clusters/cl01tl/applications/calibre-web/templates/ingress-route.yaml b/clusters/cl01tl/applications/calibre-web/templates/ingress-route.yaml new file mode 100644 index 000000000..7c0d98d1a --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/templates/ingress-route.yaml @@ -0,0 +1,33 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + entryPoints: + - websecure + routes: + - kind: Rule + match: "Host(`{{ .Values.ingressRoute.host }}`)" + middlewares: + - name: "authentik-{{ .Release.Name }}" + namespace: {{ .Release.Namespace }} + priority: 10 + services: + - kind: Service + name: {{ .Release.Name }} + port: {{ .Values.ingressRoute.port }} + - kind: Rule + match: "Host(`{{ .Values.ingressRoute.host }}`) && PathPrefix(`/outpost.goauthentik.io/`)" + priority: 15 + services: + - kind: Service + name: {{ .Values.ingressRoute.authentik.outpost }} + port: {{ .Values.ingressRoute.authentik.port }} + namespace: {{ .Values.ingressRoute.authentik.namespace }} diff --git a/clusters/cl01tl/applications/calibre-web/templates/middleware.yaml b/clusters/cl01tl/applications/calibre-web/templates/middleware.yaml new file mode 100644 index 000000000..13ff7eff2 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/templates/middleware.yaml @@ -0,0 +1,27 @@ +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: "authentik-{{ .Release.Name }}" + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + forwardAuth: + address: "http://{{ .Values.ingressRoute.authentik.outpost }}.authentik:{{ .Values.ingressRoute.authentik.port }}/outpost.goauthentik.io/auth/traefik" + trustForwardHeader: true + authResponseHeaders: + - X-authentik-username + - X-authentik-groups + - X-authentik-email + - X-authentik-name + - X-authentik-uid + - X-authentik-jwt + - X-authentik-meta-jwks + - X-authentik-meta-outpost + - X-authentik-meta-provider + - X-authentik-meta-app + - X-authentik-meta-version diff --git a/clusters/cl01tl/applications/calibre-web/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/calibre-web/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..99b41a824 --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: calibre-web-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: calibre-web-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/calibre-web/templates/persistent-volume.yaml b/clusters/cl01tl/applications/calibre-web/templates/persistent-volume.yaml new file mode 100644 index 000000000..12776b9fd --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: calibre-web-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.storage.nfs.path }} + server: {{ .Values.storage.storage.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/calibre-web/values.yaml b/clusters/cl01tl/applications/calibre-web/values.yaml new file mode 100644 index 000000000..313240f2d --- /dev/null +++ b/clusters/cl01tl/applications/calibre-web/values.yaml @@ -0,0 +1,33 @@ +calibre-web: + image: + repository: ghcr.io/linuxserver/calibre-web + tag: 0.6.21-ls253 + env: + TZ: US/Central + DOCKER_MODS: linuxserver/mods:universal-calibre + ingress: + main: + enabled: false + persistence: + config: + enabled: true + mountPath: /config + accessMode: ReadWriteOnce + size: 5Gi + media: + enabled: true + mountPath: /books + type: pvc + existingClaim: calibre-web-nfs-storage +ingressRoute: + host: calibre.alexlebens.net + port: 8083 + authentik: + outpost: authentik-outpost-proxy + port: 9000 + namespace: authentik +storage: + storage: + nfs: + path: /volume2/Storage/Calibre + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/code-server/Chart.yaml b/clusters/cl01tl/applications/code-server/Chart.yaml new file mode 100644 index 000000000..05437b8b6 --- /dev/null +++ b/clusters/cl01tl/applications/code-server/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: code-server +version: 0.0.1 +sources: + - https://github.com/coder/code-server + - https://github.com/linuxserver/docker-code-server + - https://gitlab.com/alexander-chernov/helm/code-server +dependencies: + - name: code-server + version: 0.1.1 + repository: https://charts.alekc.dev +appVersion: "4.22.0" diff --git a/clusters/cl01tl/applications/code-server/templates/external-secret.yaml b/clusters/cl01tl/applications/code-server/templates/external-secret.yaml new file mode 100644 index 000000000..a24842bc4 --- /dev/null +++ b/clusters/cl01tl/applications/code-server/templates/external-secret.yaml @@ -0,0 +1,23 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: codeserver-password-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /code-server/auth + metadataPolicy: None + property: password diff --git a/clusters/cl01tl/applications/code-server/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/code-server/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..fdd88cb10 --- /dev/null +++ b/clusters/cl01tl/applications/code-server/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: code-server-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeMode: Filesystem + storageClassName: nfs-client + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/code-server/values.yaml b/clusters/cl01tl/applications/code-server/values.yaml new file mode 100644 index 000000000..0e2820042 --- /dev/null +++ b/clusters/cl01tl/applications/code-server/values.yaml @@ -0,0 +1,34 @@ +code-server: + image: + repository: linuxserver/code-server + tag: 4.89.1 + ingress: + enabled: true + className: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: codeserver.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: codeserver-secret-tls + hosts: + - codeserver.alexlebens.net + env: + simple: + TZ: US/Central + DEFAULT_WORKSPACE: /config + full: + - name: SUDO_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: codeserver-password-secret + optional: false + persistence: + existingClaim: code-server-nfs-storage + enabled: true diff --git a/clusters/cl01tl/applications/cops/Chart.yaml b/clusters/cl01tl/applications/cops/Chart.yaml new file mode 100644 index 000000000..e58d2e08e --- /dev/null +++ b/clusters/cl01tl/applications/cops/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cops +version: 0.0.1 +sources: + - https://github.com/mikespub-org/seblucas-cops + - http://alexlebens.github.io/helm-charts +dependencies: + - name: cops + version: 0.0.3 + repository: http://alexlebens.github.io/helm-charts +appVersion: 1.1.3 diff --git a/clusters/cl01tl/applications/cops/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/cops/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..cf2d956bf --- /dev/null +++ b/clusters/cl01tl/applications/cops/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: cops-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: cops-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/cops/templates/persistent-volume.yaml b/clusters/cl01tl/applications/cops/templates/persistent-volume.yaml new file mode 100644 index 000000000..abc37fd5e --- /dev/null +++ b/clusters/cl01tl/applications/cops/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: cops-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.books.nfsPath }} + server: {{ .Values.storage.books.nfsServer }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/cops/values.yaml b/clusters/cl01tl/applications/cops/values.yaml new file mode 100644 index 000000000..900c096c3 --- /dev/null +++ b/clusters/cl01tl/applications/cops/values.yaml @@ -0,0 +1,22 @@ +cops: + deployment: + env: + TZ: US/Central + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + className: traefik + host: calibre-content.alexlebens.net + persistence: + config: + storageClassName: ceph-block + storageSize: 1Gi + books: + claimName: cops-nfs-storage +storage: + books: + nfsPath: /volume2/Storage/Calibre + nfsServer: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/freshrss/Chart.yaml b/clusters/cl01tl/applications/freshrss/Chart.yaml new file mode 100644 index 000000000..ef5b309d7 --- /dev/null +++ b/clusters/cl01tl/applications/freshrss/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +name: freshrss +version: 1.0.0 +sources: + - https://github.com/FreshRSS/FreshRSS + - https://github.com/alexlebens/helm-charts/tree/main/charts/hfreshrss +dependencies: + - name: freshrss + version: 0.0.3 + repository: http://alexlebens.github.io/helm-charts + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: "1.23.1" diff --git a/clusters/cl01tl/applications/freshrss/templates/external-secret.yaml b/clusters/cl01tl/applications/freshrss/templates/external-secret.yaml new file mode 100644 index 000000000..d28e62fd7 --- /dev/null +++ b/clusters/cl01tl/applications/freshrss/templates/external-secret.yaml @@ -0,0 +1,94 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: freshrss-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: OIDC_CLIENT_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/freshrss + metadataPolicy: None + property: client + - secretKey: OIDC_CLIENT_SECRET + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/freshrss + metadataPolicy: None + property: secret + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: freshrss-install-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: FRESHRSS_INSTALL + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /freshrss/config + metadataPolicy: None + property: FRESHRSS_INSTALL + - secretKey: FRESHRSS_USER + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /freshrss/config + metadataPolicy: None + property: FRESHRSS_USER + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: freshrss-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: freshrss-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-freshrss-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-freshrss-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/freshrss/values.yaml b/clusters/cl01tl/applications/freshrss/values.yaml new file mode 100644 index 000000000..6cd0d8379 --- /dev/null +++ b/clusters/cl01tl/applications/freshrss/values.yaml @@ -0,0 +1,42 @@ +freshrss: + deployment: + env: + TZ: US/Central + CRON_MIN: 13,43 + OIDC_ENABLED: 1 + OIDC_PROVIDER_METADATA_URL: https://authentik.alexlebens.net/application/o/freshrss/.well-known/openid-configuration + OIDC_X_FORWARDED_HEADERS: X-Forwarded-Port X-Forwarded-Proto X-Forwarded-Host + OIDC_SCOPES: openid email profile + OIDC_REMOTE_USER_CLAIM: preferred_username + envFrom: + - secretRef: + name: freshrss-oidc-secret + ingress: + enabled: true + className: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + host: rss.alexlebens.net + persistence: + config: + storageClassName: ceph-block + storageSize: 5Gi +postgres-16-cluster: + mode: standalone + kubernetesClusterName: cl01tl + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/freshrss + endpointCredentials: freshrss-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/applications/home-assistant/Chart.yaml b/clusters/cl01tl/applications/home-assistant/Chart.yaml new file mode 100644 index 000000000..13996603a --- /dev/null +++ b/clusters/cl01tl/applications/home-assistant/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: home-assistant +version: 1.0.0 +sources: + - https://github.com/home-assistant + - https://github.com/alexlebens/helm-charts/tree/main/charts/home-assistant +dependencies: + - name: home-assistant + version: 0.1.15 + repository: http://alexlebens.github.io/helm-charts +appVersion: v2024.5.3 diff --git a/clusters/cl01tl/applications/home-assistant/templates/external-secret.yaml b/clusters/cl01tl/applications/home-assistant/templates/external-secret.yaml new file mode 100644 index 000000000..ef05fb75e --- /dev/null +++ b/clusters/cl01tl/applications/home-assistant/templates/external-secret.yaml @@ -0,0 +1,48 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: home-assistant-codeserver-password-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: SUDO_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /home-assistant/auth + metadataPolicy: None + property: SUDO_PASSWORD + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: home-assistant-token-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: bearerToken + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /home-assistant/auth + metadataPolicy: None + property: bearerToken diff --git a/clusters/cl01tl/applications/home-assistant/values.yaml b/clusters/cl01tl/applications/home-assistant/values.yaml new file mode 100644 index 000000000..f7cc998f2 --- /dev/null +++ b/clusters/cl01tl/applications/home-assistant/values.yaml @@ -0,0 +1,46 @@ +home-assistant: + deployment: + env: + TZ: US/Central + ingressRoute: + enabled: true + host: homeassistant.alexlebens.net + authentik: + outpost: authentik-outpost-proxy + namespace: authentik + metrics: + enabled: true + serviceMonitor: + bearerTokenSecret: + name: home-assistant-token-secret + key: bearerToken + prometheusRule: + enabled: true + rules: + - alert: HomeAssistantAbsent + annotations: + description: Home Assistant has disappeared from Prometheus service discovery. + summary: Home Assistant is down. + expr: | + absent(up{job=~".*home-assistant.*"} == 1) + for: 5m + labels: + severity: critical + persistence: + config: + storageClassName: ceph-block + storageSize: 1Gi + codeserver: + enabled: true + env: + TZ: US/Central + DEFAULT_WORKSPACE: /config + envFrom: + - secretRef: + name: home-assistant-codeserver-password-secret + ingressRoute: + enabled: true + host: homeassistant-codeserver.alexlebens.net + authentik: + outpost: authentik-outpost-proxy + namespace: authentik diff --git a/clusters/cl01tl/applications/homepage-dev/Chart.yaml b/clusters/cl01tl/applications/homepage-dev/Chart.yaml new file mode 100644 index 000000000..d68e60291 --- /dev/null +++ b/clusters/cl01tl/applications/homepage-dev/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: homepage-dev +version: 1.0.0 +home: https://outline.alexlebens.net/doc/homepage-dev-s2clWoI5EC +sources: + - https://github.com/gethomepage/homepage + - https://github.com/cloudflare/cloudflared + - https://github.com/bjw-s/helm-charts/blob/main/charts/other/app-template/values.yaml +dependencies: + - name: app-template + alias: homepage + repository: https://bjw-s.github.io/helm-charts/ + version: 3.1.0 + - name: app-template + alias: cloudflared + repository: https://bjw-s.github.io/helm-charts/ + version: 3.1.0 +appVersion: v0.8.12 diff --git a/clusters/cl01tl/applications/homepage-dev/templates/external-secret.yaml b/clusters/cl01tl/applications/homepage-dev/templates/external-secret.yaml new file mode 100644 index 000000000..3f843211f --- /dev/null +++ b/clusters/cl01tl/applications/homepage-dev/templates/external-secret.yaml @@ -0,0 +1,23 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: homepage-dev-cloudflared-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: homepage-dev-cloudflared-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: cf-tunnel-token + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/tunnels/homepage-dev + metadataPolicy: None + property: token diff --git a/clusters/cl01tl/applications/homepage-dev/values.yaml b/clusters/cl01tl/applications/homepage-dev/values.yaml new file mode 100644 index 000000000..832ff9dfc --- /dev/null +++ b/clusters/cl01tl/applications/homepage-dev/values.yaml @@ -0,0 +1,225 @@ +homepage: + global: + nameOverride: homepage + controllers: + main: + type: deployment + annotations: + reloader.stakater.com/auto: "true" + strategy: Recreate + containers: + main: + image: + repository: ghcr.io/gethomepage/homepage + tag: v0.8.13 + pullPolicy: IfNotPresent + resources: + limits: + cpu: 1000m + memory: 512Mi + requests: + cpu: 10m + memory: 128Mi + serviceAccount: + create: true + configMaps: + config: + enabled: true + data: + docker.yaml: "" + kubernetes.yaml: "" + settings.yaml: | + favicon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png + headerStyle: clean + hideVersion: true + color: slate + background: + image: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/background.jpg + theme: dark + disableCollapse: true + layout: + - Media: + icon: mdi-multimedia-#ffffff + - Applications: + icon: mdi-application-#ffffff + widgets.yaml: | + - logo: + icon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png + - datetime: + text_size: xl + format: + dateStyle: long + timeStyle: short + hour12: false + - openmeteo: + label: Denver + latitude: 39.73 + longitude: 104.99 + units: metric + cache: 5 + services.yaml: | + - Media: + - Plex: + icon: plex.png + href: https://plex.alexlebens.net + description: Media server + siteMonitor: http://plex.plex:32400 + statusStyle: dot + - Overseerr: + icon: overseerr.png + description: Requests + href: https://overseerr.alexlebens.net + siteMonitor: http://overseerr.overseerr:5055 + statusStyle: dot + - Jellyfin: + icon: jellyfin.png + description: Media server + href: https://jellyfin.alexlebens.net/ + siteMonitor: http://jellyfin.jellyfin:8096 + statusStyle: dot + - TubeAchivist: + icon: tube-archivist.png + description: Youtube downloader + href: https://tubearchivist.alexlebens.net/login/ + siteMonitor: http://tubearchivist.tubearchivist:8000 + statusStyle: dot + - Navidrome: + icon: navidrome.png + description: Music + href: https://navidrome.alexlebens.net + siteMonitor: http://navidrome.navidrome:4533 + statusStyle: dot + - Audiobookshelf: + icon: audiobookshelf.png + description: Audiobooks, Books, and Podcasts + href: https://audiobookshelf.alexlebens.net + siteMonitor: http://audiobookshelf.audiobookshelf:80 + statusStyle: dot + - Calibre: + icon: calibre-web.png + description: Books + href: https://calibre.alexlebens.net + siteMonitor: http://calibre-web.calibre-web:8083 + statusStyle: dot + - Applications: + - Ghost: + icon: ghost.png + description: Website and blog + href: https://blog.alexlebens.dev + siteMonitor: https://blog.alexlebens.dev + statusStyle: dot + - Chat: + icon: element.svg + description: Web client for Matrix chat + href: https://chat.alexlebens.dev + siteMonitor: https://chat.alexlebens.dev + statusStyle: dot + - Home Assistant: + icon: home-assistant.png + description: Home automation + href: https://homeassistant.alexlebens.net + siteMonitor: http://home-assistant.home-assistant:8123 + statusStyle: dot + - Vikunja: + icon: vikunja.png + description: Notes and tasks + href: https://vikunja.alexlebens.net + siteMonitor: http://vikunja-frontend.vikunja:80 + statusStyle: dot + - Taiga: + icon: taiga.png + description: Project planning + href: https://taiga.alexlebens.net + siteMonitor: http://taiga-front.taiga:80 + statusStyle: dot + - Penpot: + icon: https://raw.githubusercontent.com/penpot/penpot/362d4ea47f06d169dd6e0a34cb9d141200e646e6/frontend/resources/images/icons/penpot-logo-icon.svg + description: Web design + href: https://penpot.alexlebens.net + siteMonitor: http://penpot.penpot:80 + statusStyle: dot + - Outline: + icon: outline.png + description: Wiki + href: https://outline.alexlebens.net + siteMonitor: http://outline.outline:3000 + statusStyle: dot + - FreshRss: + icon: freshrss.svg + description: Rss reader + href: https://rss.alexlebens.net + siteMonitor: http://freshrss.freshrss:80 + statusStyle: dot + bookmarks.yaml: "" + service: + http: + controller: main + ports: + http: + port: 80 + targetPort: 3000 + protocol: HTTP + persistence: + config: + enabled: true + type: configMap + name: homepage-dev-config + advancedMounts: + main: + main: + - path: /app/config/bookmarks.yaml + readOnly: true + mountPropagation: None + subPath: bookmarks.yaml + - path: /app/config/docker.yaml + readOnly: true + mountPropagation: None + subPath: docker.yaml + - path: /app/config/kubernetes.yaml + readOnly: true + mountPropagation: None + subPath: kubernetes.yaml + - path: /app/config/services.yaml + readOnly: true + mountPropagation: None + subPath: services.yaml + - path: /app/config/settings.yaml + readOnly: true + mountPropagation: None + subPath: settings.yaml + - path: /app/config/widgets.yaml + readOnly: true + mountPropagation: None + subPath: widgets.yaml +cloudflared: + global: + nameOverride: cloudflared + controllers: + main: + type: deployment + strategy: Recreate + containers: + main: + image: + repository: cloudflare/cloudflared + tag: "2024.5.0" + pullPolicy: IfNotPresent + args: + - tunnel + - --no-autoupdate + - run + - --token + - $(CF_MANAGED_TUNNEL_TOKEN) + env: + - name: CF_MANAGED_TUNNEL_TOKEN + valueFrom: + secretKeyRef: + name: homepage-dev-cloudflared-secret + key: cf-tunnel-token + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi diff --git a/clusters/cl01tl/applications/homepage/Chart.yaml b/clusters/cl01tl/applications/homepage/Chart.yaml new file mode 100644 index 000000000..2764e8feb --- /dev/null +++ b/clusters/cl01tl/applications/homepage/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: homepage-front +version: 1.0.0 +home: https://outline.alexlebens.net/doc/homepage-s2clWoI5EC +sources: + - https://github.com/gethomepage/homepage + - https://github.com/alexlebens/helm-charts/tree/main/charts/homepage +dependencies: + - name: homepage + version: 0.0.15 + repository: http://alexlebens.github.io/helm-charts +appVersion: v0.8.12 diff --git a/clusters/cl01tl/applications/homepage/templates/external-secret.yaml b/clusters/cl01tl/applications/homepage/templates/external-secret.yaml new file mode 100644 index 000000000..d7f7ced37 --- /dev/null +++ b/clusters/cl01tl/applications/homepage/templates/external-secret.yaml @@ -0,0 +1,44 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: homepage-back-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: HOMEPAGE_VAR_SYNOLOGY_USER + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /synology/auth + metadataPolicy: None + property: user + - secretKey: HOMEPAGE_VAR_SYNOLOGY_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /synology/auth + metadataPolicy: None + property: password + - secretKey: HOMEPAGE_VAR_UNIFI_USER + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /unifi/auth + metadataPolicy: None + property: user + - secretKey: HOMEPAGE_VAR_UNIFI_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /unifi/auth + metadataPolicy: None + property: password diff --git a/clusters/cl01tl/applications/homepage/values.yaml b/clusters/cl01tl/applications/homepage/values.yaml new file mode 100644 index 000000000..a1ba28654 --- /dev/null +++ b/clusters/cl01tl/applications/homepage/values.yaml @@ -0,0 +1,420 @@ +homepage: + deployment: + annotations: + reloader.stakater.com/auto: "true" + resources: + limits: + memory: 2Gi + cpu: 1000m + envFrom: + - secretRef: + name: homepage-back-key-secret + ingressRoute: + host: home.alexlebens.net + authentik: + outpost: authentik-outpost-proxy + namespace: authentik + config: + widgets: + - logo: + icon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png + - kubernetes: + cluster: + show: true + cpu: true + memory: true + showLabel: true + label: "Cluster" + nodes: + show: false + - datetime: + text_size: xl + format: + dateStyle: long + timeStyle: short + hour12: false + - openmeteo: + label: Denver + latitude: 39.73 + longitude: 104.99 + units: metric + cache: 5 + services: + - Media: + - Plex: + icon: plex.png + href: https://plex.alexlebens.net + description: Media server + siteMonitor: http://plex.plex:32400 + statusStyle: dot + - Overseerr: + icon: overseerr.png + description: Requests + href: https://overseerr.alexlebens.net + siteMonitor: http://overseerr.overseerr:5055 + statusStyle: dot + - Jellyfin: + icon: jellyfin.png + description: Media server + href: https://jellyfin.alexlebens.net/ + siteMonitor: http://jellyfin.jellyfin:8096 + statusStyle: dot + - Kyoo: + icon: https://raw.githubusercontent.com/zoriya/Kyoo/master/icons/icon-256x256.png + description: Media server + href: https://kyoo.alexlebens.net/ + siteMonitor: http://kyoo-front.kyoo:8901 + statusStyle: dot + - TubeAchivist: + icon: tube-archivist.png + description: Youtube downloader + href: https://tubearchivist.alexlebens.net/login/ + siteMonitor: http://tubearchivist.tubearchivist:8000 + statusStyle: dot + - Navidrome: + icon: navidrome.png + description: Music + href: https://navidrome.alexlebens.net + siteMonitor: http://navidrome.navidrome:4533 + statusStyle: dot + - Audiobookshelf: + icon: audiobookshelf.png + description: Audiobooks, Books, and Podcasts + href: https://audiobookshelf.alexlebens.net + siteMonitor: http://audiobookshelf.audiobookshelf:80 + statusStyle: dot + - Calibre: + icon: calibre-web.png + description: Books + href: https://calibre.alexlebens.net + siteMonitor: http://calibre-web.calibre-web:8083 + statusStyle: dot + - Applications: + - Ghost (.dev): + icon: ghost.png + description: Website and blog + href: https://blog.alexlebens.dev + siteMonitor: https://blog.alexlebens.dev + statusStyle: dot + - Chat (.dev): + icon: element.svg + description: Web client for Matrix chat + href: https://chat.alexlebens.dev + siteMonitor: https://chat.alexlebens.dev + statusStyle: dot + - Home Assistant: + icon: home-assistant.png + description: Home automation + href: https://homeassistant.alexlebens.net + siteMonitor: http://home-assistant.home-assistant:8123 + statusStyle: dot + - Vikunja: + icon: vikunja.png + description: Notes and tasks + href: https://vikunja.alexlebens.net + siteMonitor: http://vikunja-frontend.vikunja:80 + statusStyle: dot + - Taiga: + icon: taiga.png + description: Project planning + href: https://taiga.alexlebens.net + siteMonitor: http://taiga-front.taiga:80 + statusStyle: dot + - Penpot: + icon: https://raw.githubusercontent.com/penpot/penpot/362d4ea47f06d169dd6e0a34cb9d141200e646e6/frontend/resources/images/icons/penpot-logo-icon.svg + description: Web design + href: https://penpot.alexlebens.net + siteMonitor: http://penpot.penpot:80 + statusStyle: dot + - Outline: + icon: outline.png + description: Wiki + href: https://outline.alexlebens.net + siteMonitor: http://outline.outline:3000 + statusStyle: dot + - FreshRss: + icon: freshrss.svg + description: Rss reader + href: https://rss.alexlebens.net + siteMonitor: http://freshrss.freshrss:80 + statusStyle: dot + - Code: + - Code Server: + icon: code-server.png + description: VS Code in a browser + href: https://codeserver.alexlebens.net + siteMonitor: http://code-server.code-server:8443 + statusStyle: dot + - Code Server - Home Assistant: + icon: code-server.png + description: Edit config for Home Assistant + href: https://homeassistant-codeserver.alexlebens.net + siteMonitor: http://home-assistant-codeserver.home-assistant:8443 + statusStyle: dot + - Gitea: + icon: gitea.png + description: Code repository + href: https://gitea.alexlebens.net + siteMonitor: http://gitea-http.gitea:3000 + statusStyle: dot + - ArgoCD: + icon: argocd.png + description: Continous Deployment + href: https://argocd.alexlebens.net + siteMonitor: http://argocd-server.argocd:80 + statusStyle: dot + namespace: argocd + - Argo Rollouts: + icon: argocd.png + description: Deployment mangement and evaluation + href: https://argo-rollouts.alexlebens.net + siteMonitor: http://argo-rollouts-dashboard.argocd:3100 + statusStyle: dot + namespace: argocd + - Argo Workflows: + icon: argocd.png + description: Workflows and events for ArgoCD + href: https://argo-workflows.alexlebens.net + siteMonitor: http://argo-workflows-server.argocd:2746 + statusStyle: dot + namespace: argocd + - Kargo: + icon: https://raw.githubusercontent.com/akuity/kargo/main/ui/public/kargo-icon.png + description: Continous Integration + href: https://kargo.alexlebens.net + siteMonitor: http://kargo-api.argocd:80 + statusStyle: dot + namespace: argocd + - Management: + - Calibre Server: + icon: calibre.png + description: Calibre content server + href: https://calibre-server.alexlebens.net + siteMonitor: http://calibre-server.calibre-server:8080 + statusStyle: dot + - COPS: + icon: calibre-web.png + description: Calibre OPDS (and HTML) PHP Server + href: https://calibre-content.alexlebens.net + siteMonitor: http://cops.cops:80 + statusStyle: dot + - Monitoring: + - Portainer: + icon: portainer.png + description: Service monitoring + href: https://portainer.alexlebens.net + siteMonitor: http://portainer.portainer:9000 + statusStyle: dot + - Headlamp: + icon: kubernetes.png + description: Kubernetes dashboard + href: https://headlamp.alexlebens.net + siteMonitor: http://headlamp.headlamp:80 + statusStyle: dot + - Hubble: + icon: cilium.png + description: Network monitoring for Cilium + href: https://hubble.alexlebens.net + siteMonitor: http://hubble-ui.kube-system:80 + statusStyle: dot + - Grafana: + icon: grafana.png + description: Dashboard + href: https://grafana.alexlebens.net + siteMonitor: https://grafana.alexlebens.net + statusStyle: dot + - Prometheus: + icon: prometheus.png + description: Metrics database + href: https://prometheus.alexlebens.net + siteMonitor: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090 + statusStyle: dot + widget: + type: prometheus + url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090 + - Alertmanager: + icon: alertmanager.png + description: Alerting and notification + href: https://alertmanager.alexlebens.net + siteMonitor: http://kube-prometheus-stack-alertmanager.kube-prometheus-stack:9093 + statusStyle: dot + - Services: + - Authentik: + icon: authentik.png + description: Identity management and provider + href: https://authentik.alexlebens.net + siteMonitor: http://authentik-server.authentik:80 + statusStyle: dot + - Authentik (.dev): + icon: authentik.png + description: Identity management and provider + href: https://auth.alexlebens.dev + siteMonitor: https://auth.alexlebens.dev + statusStyle: dot + - Traefik - cl01tl: + icon: traefik.png + description: Reverse proxy + href: https://traefik-cl01tl.alexlebens.net/dashboard/#/ + siteMonitor: https://traefik-cl01tl.alexlebens.net/dashboard/#/ + statusStyle: dot + widget: + type: traefik + url: https://traefik-cl01tl.alexlebens.net + - Traefik - ps08rp: + icon: traefik.png + description: Reverse proxy + href: https://traefik-ps08rp.alexlebens.net/dashboard/#/ + siteMonitor: https://traefik-ps08rp.alexlebens.net/dashboard/#/ + statusStyle: dot + - Traefik - ps09rp: + icon: traefik.png + description: Reverse proxy + href: https://traefik-ps09rp.alexlebens.net/dashboard/#/ + siteMonitor: https://traefik-ps09rp.alexlebens.net/dashboard/#/ + statusStyle: dot + - Technitium - ps08rp: + icon: technitium.png + description: DNS + href: https://technitium-ps08rp.alexlebens.net + siteMonitor: https://technitium-ps08rp.alexlebens.net + statusStyle: dot + - Technitium - ps09rp: + icon: technitium.png + description: DNS + href: https://technitium-ps09rp.alexlebens.net + siteMonitor: https://technitium-ps09rp.alexlebens.net + statusStyle: dot + - Hardware: + - Unifi: + icon: unifi.png + description: Manager network hardware + href: https://unifi.alexlebens.net + siteMonitor: https://unifi.alexlebens.net + statusStyle: dot + - Synology: + icon: synology.png + description: Network Attached Storage + href: https://synology.alexlebens.net + siteMonitor: https://synology.alexlebens.net + statusStyle: dot + widget: + type: diskstation + url: https://synology.alexlebens.net + username: '{{HOMEPAGE_VAR_SYNOLOGY_USER}}' + password: '{{HOMEPAGE_VAR_SYNOLOGY_PASSWORD}}' + volume: volume_2 + - HD Homerun Flex: + icon: hdhomerun.png + description: TV Tuner + href: http://hdhr.alexlebens.net + siteMonitor: http://hdhr.alexlebens.net + statusStyle: dot + - Pi KVM: + icon: pikvm.png + description: IP KVM + href: https://pikvm.alexlebens.net + siteMonitor: https://pikvm.alexlebens.net + statusStyle: dot + - Storage: + - Ceph: + icon: ceph.png + description: Clustered storage + href: https://ceph.alexlebens.net + siteMonitor: http://rook-ceph-mgr-dashboard.rook-ceph:7000 + statusStyle: dot + - PGAdmin: + icon: pgadmin.png + description: Postgresql console + href: https://pgadmin.alexlebens.net + siteMonitor: http://pgadmin-pgadmin4.pgadmin:80 + statusStyle: dot + - Vault: + icon: vault.png + description: Secret management + href: https://vault.alexlebens.net + siteMonitor: http://vault.vault:8200 + statusStyle: dot + - Minio: + icon: minio.png + description: Operator for Minio S3 storage + href: https://minio.alexlebens.net + siteMonitor: http://console.minio-operator:9090 + statusStyle: dot + - Minio - Outline: + icon: minio.png + description: Tenant for Outline S3 storage + href: https://minio-outline.alexlebens.net + siteMonitor: http://minio-outline-console.outline:9090 + statusStyle: dot + - Minio - Penpot: + icon: minio.png + description: Tenant for Penpot S3 storage + href: https://minio-penpot.alexlebens.net + siteMonitor: http://minio-penpot-console.penpot:9090 + statusStyle: dot + bookmarks: + - External Services: + - Github: + - abbr: GH + href: https://github.com/alexlebens/alexlebens-net + - Renovate: + - abbr: RN + href: https://developer.mend.io/[platform]/alexlebens/alexlebens-net + - AWS: + - abbr: AW + href: https://aws.amazon.com/console/ + - Cloudflare: + - abbr: CF + href: https://dash.cloudflare.com/b76e303258b84076ee01fd0f515c0768 + - Tailscale: + - abbr: TS + href: https://login.tailscale.com/admin/machines + - ProtonVPN: + - abbr: PV + href: https://account.protonvpn.com/ + - Pushover: + - abbr: PO + href: https://pushover.net + - ReCaptcha: + - abbr: RC + href: https://www.google.com/recaptcha/admin/site/698983587 + - Dashboard Icons: + - abbr: DI + href: https://github.com/walkxcode/dashboard-icons/tree/main/png + settings: + favicon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png + headerStyle: clean + hideVersion: true + color: slate + background: + image: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/background.jpg + theme: dark + disableCollapse: true + layout: + - Media: + tab: Apps + icon: mdi-multimedia-#ffffff + - Applications: + tab: Apps + icon: mdi-application-#ffffff + - Code: + tab: Tools + icon: mdi-code-braces-box-#ffffff + - Monitoring: + tab: Tools + icon: mdi-chart-bar-#ffffff + - Management: + tab: Tools + icon: mdi-content-save-cog-#ffffff + - Services: + tab: Services + icon: mdi-server-network-#ffffff + - Hardware: + tab: Services + icon: mdi-lan-connect-#ffffff + - Storage: + tab: Services + icon: mdi-harddisk-#ffffff + - External Services: + tab: Bookmarks + icon: mdi-cloud-#ffffff diff --git a/clusters/cl01tl/applications/jellyfin/Chart.yaml b/clusters/cl01tl/applications/jellyfin/Chart.yaml new file mode 100644 index 000000000..d6b26fc3b --- /dev/null +++ b/clusters/cl01tl/applications/jellyfin/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: jellyfin +version: 0.0.1 +sources: + - https://github.com/jellyfin/jellyfin + - https://github.com/loeken/helm-charts/tree/main/charts/jellyfin +dependencies: + - name: jellyfin + version: 10.9.1 + repository: https://loeken.github.io/helm-charts +appVersion: 10.8.13 diff --git a/clusters/cl01tl/applications/jellyfin/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/jellyfin/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..4ce8dcd64 --- /dev/null +++ b/clusters/cl01tl/applications/jellyfin/templates/persistent-volume-claim.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jellyfin-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: jellyfin-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jellyfin-youtube-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: jellyfin-youtube-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadOnlyMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/jellyfin/templates/persistent-volume.yaml b/clusters/cl01tl/applications/jellyfin/templates/persistent-volume.yaml new file mode 100644 index 000000000..84f11ec49 --- /dev/null +++ b/clusters/cl01tl/applications/jellyfin/templates/persistent-volume.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: jellyfin-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.storage.nfs.path }} + server: {{ .Values.storage.storage.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: jellyfin-youtube-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadOnlyMany + nfs: + path: {{ .Values.storage.youtube.nfs.path }} + server: {{ .Values.storage.youtube.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/jellyfin/values.yaml b/clusters/cl01tl/applications/jellyfin/values.yaml new file mode 100644 index 000000000..1345a9030 --- /dev/null +++ b/clusters/cl01tl/applications/jellyfin/values.yaml @@ -0,0 +1,55 @@ +jellyfin: + env: + TZ: US/Central + ingress: + main: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: jellyfin.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: jellyfin-secret-tls + hosts: + - jellyfin.alexlebens.net + persistence: + config: + enabled: true + mountPath: /config + accessMode: ReadWriteOnce + size: 40Gi + cache: + enabled: true + mountPath: /cache + accessMode: ReadWriteOnce + size: 40Gi + media: + enabled: true + mountPath: /mnt/store + type: pvc + existingClaim: jellyfin-nfs-storage + youtube: + enabled: true + mountPath: /youtube + type: pvc + existingClaim: jellyfin-youtube-nfs-storage + resources: + requests: + gpu.intel.com/i915: 1 + limits: + gpu.intel.com/i915: 1 +storage: + storage: + nfs: + path: /volume2/Storage + server: synologybond.alexlebens.net + youtube: + nfs: + path: /volume2/Storage/YouTube + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/kyoo/Chart.yaml b/clusters/cl01tl/applications/kyoo/Chart.yaml new file mode 100644 index 000000000..b0a128ed3 --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/Chart.yaml @@ -0,0 +1,32 @@ +apiVersion: v2 +name: kyoo +version: 1.0.0 +description: A Helm chart for deploying Kyoo +keywords: + - kyoo + - media +sources: + - https://github.com/zoriya/Kyoo + - https://github.com/rabbitmq/rabbitmq-server + - https://github.com/bitnami/charts/tree/main/bitnami/rabbitmq + - https://github.com/meilisearch/meilisearch + - https://github.com/meilisearch/meilisearch-kubernetes/tree/main/charts/meilisearch + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +maintainers: + - name: alexlebens +dependencies: + - name: app-template + repository: https://bjw-s.github.io/helm-charts/ + version: 3.1.0 + - name: rabbitmq + version: 14.1.4 + repository: https://charts.bitnami.com/bitnami + - name: meilisearch + version: 0.7.0 + repository: https://meilisearch.github.io/meilisearch-kubernetes + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +icon: https://raw.githubusercontent.com/zoriya/Kyoo/master/icons/icon-256x256.png +appVersion: v4.5.0 diff --git a/clusters/cl01tl/applications/kyoo/templates/external-secret.yaml b/clusters/cl01tl/applications/kyoo/templates/external-secret.yaml new file mode 100644 index 000000000..fc7fea9de --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/templates/external-secret.yaml @@ -0,0 +1,183 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-key-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/authentication + metadataPolicy: None + property: key + - secretKey: kyoo + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/authentication + metadataPolicy: None + property: kyoo + - secretKey: tmdb + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/authentication + metadataPolicy: None + property: tmdb + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-api-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-api-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: kyoo + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/api + metadataPolicy: None + property: kyoo + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/kyoo + metadataPolicy: None + property: client + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/kyoo + metadataPolicy: None + property: secret + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-rabbitmq-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-rabbitmq-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: rabbitmq + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/rabbitmq + metadataPolicy: None + property: password + - secretKey: erlang + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/rabbitmq + metadataPolicy: None + property: erlang + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-meilisearch-master-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-meilisearch-master-key-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: meilisearch + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: MEILI_MASTER_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /kyoo/meilisearch + metadataPolicy: None + property: MEILI_MASTER_KEY + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kyoo-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-kyoo-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-kyoo-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/kyoo/templates/ingress-route.yaml b/clusters/cl01tl/applications/kyoo/templates/ingress-route.yaml new file mode 100644 index 000000000..5b491403a --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/templates/ingress-route.yaml @@ -0,0 +1,32 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: kyoo + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + entryPoints: + - websecure + routes: + - kind: Rule + match: Host(`kyoo.alexlebens.net`) + priority: 10 + services: + - kind: Service + name: kyoo-front + port: 8901 + - kind: Rule + match: Host(`kyoo.alexlebens.net`) && PathPrefix(`/api/`) + middlewares: + - name: kyoo-strip-prefix + namespace: {{ .Release.Namespace }} + priority: 15 + services: + - kind: Service + name: kyoo-back + port: 5000 diff --git a/clusters/cl01tl/applications/kyoo/templates/middleware.yaml b/clusters/cl01tl/applications/kyoo/templates/middleware.yaml new file mode 100644 index 000000000..e1833cf3a --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/templates/middleware.yaml @@ -0,0 +1,15 @@ +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: kyoo-strip-prefix + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-strip-prefix + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + stripPrefix: + prefixes: + - /api/ diff --git a/clusters/cl01tl/applications/kyoo/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/kyoo/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..6cf0d014a --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/templates/persistent-volume-claim.yaml @@ -0,0 +1,229 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-anime-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-anime-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-anime-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-anime-movies-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-anime-movies-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-anime-movies-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-documentaries-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-documentaries-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-documentaries-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-documentary-shows-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-documentary-shows-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-documentary-shows-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-movies-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-movies-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-movies-4k-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-4k-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-movies-4k-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-movies-classics-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-classics-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-movies-classics-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-movies-foreign-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-foreign-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-movies-foreign-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-stand-up-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-stand-up-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-stand-up-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-tv-shows-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-tv-shows-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-tv-shows-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kyoo-tv-shows-4k-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-tv-shows-4k-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: kyoo-tv-shows-4k-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/kyoo/templates/persistent-volume.yaml b/clusters/cl01tl/applications/kyoo/templates/persistent-volume.yaml new file mode 100644 index 000000000..d9e3b6d8a --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/templates/persistent-volume.yaml @@ -0,0 +1,295 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-anime-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-anime-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: /volume2/Storage/Anime + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-anime-movies-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-anime-movies-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Anime Movies" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-documentaries-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-documentaries-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: /volume2/Storage/Documentaries + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-documentary-shows-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-documentary-shows-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Documentary Shows" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-movies-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: /volume2/Storage/Movies + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-movies-4k-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-4k-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Movies 4K" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-movies-classics-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-classics-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Movies Classics" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-movies-foreign-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-movies-foreign-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Movies Foreign" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-stand-up-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-stand-up-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/Stand Up" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-tv-shows-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-tv-shows-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/TV Shows" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac + +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: kyoo-tv-shows-4k-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kyoo-tv-shows-4k-nfs-storage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: "/volume2/Storage/TV Shows 4K" + server: synologybond.alexlebens.net + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/kyoo/values.yaml b/clusters/cl01tl/applications/kyoo/values.yaml new file mode 100644 index 000000000..e150791f7 --- /dev/null +++ b/clusters/cl01tl/applications/kyoo/values.yaml @@ -0,0 +1,590 @@ +app-template: + controllers: + autosync: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_autosync + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: RABBITMQ_HOST + value: kyoo-rabbitmq + - name: RABBITMQ_DEFAULT_USER + value: kyoo + - name: RABBITMQ_DEFAULT_PASS + valueFrom: + secretKeyRef: + name: kyoo-rabbitmq-secret + key: password + resources: + limits: + cpu: 100m + memory: 512Mi + requests: + cpu: 10m + memory: 128Mi + back: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + initContainers: + migrations: + image: + repository: ghcr.io/zoriya/kyoo_migrations + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: password + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: dbname + - name: POSTGRES_SERVER + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: host + - name: POSTGRES_PORT + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: port + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 256Mi + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_back + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: REQUIRE_ACCOUNT_VERIFICATION + value: "false" + - name: UNLOGGED_PERMISSIONS + value: overall.read + - name: DEFAULT_PERMISSIONS + value: overall.read,overall.play + - name: AUTHENTICATION_SECRET + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: key + - name: KYOO_APIKEYS + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: kyoo + - name: THEMOVIEDB_APIKEY + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: tmdb + - name: PUBLIC_URL + value: https://kyoo.alexlebens.net + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: password + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: dbname + - name: POSTGRES_SERVER + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: host + - name: POSTGRES_PORT + valueFrom: + secretKeyRef: + name: kyoo-postgresql-16-cluster-app + key: port + - name: OIDC_SERVICE_NAME + value: Authentik + - name: OIDC_SERVICE_LOGO + value: https://avatars.githubusercontent.com/u/82976448?s=200&v=4 + - name: OIDC_SERVICE_AUTHORIZATION + value: https://authentik.alexlebens.net/application/o/authorize/ + - name: OIDC_SERVICE_TOKEN + value: https://authentik.alexlebens.net/application/o/token/ + - name: OIDC_SERVICE_PROFILE + value: https://authentik.alexlebens.net/application/o/userinfo/ + - name: OIDC_SERVICE_SCOPE + value: "openid profile email" + - name: OIDC_SERVICE_CLIENTID + valueFrom: + secretKeyRef: + name: kyoo-oidc-secret + key: client + - name: OIDC_SERVICE_SECRET + valueFrom: + secretKeyRef: + name: kyoo-oidc-secret + key: secret + - name: TRANSCODER_URL + value: http://kyoo-transcoder.kyoo:7666 + - name: MEILI_HOST + value: http://kyoo-meilisearch.kyoo:7700 + - name: MEILI_MASTER_KEY + valueFrom: + secretKeyRef: + name: kyoo-meilisearch-master-key-secret + key: MEILI_MASTER_KEY + - name: RABBITMQ_HOST + value: kyoo-rabbitmq + - name: RABBITMQ_DEFAULT_USER + value: kyoo + - name: RABBITMQ_DEFAULT_PASS + valueFrom: + secretKeyRef: + name: kyoo-rabbitmq-secret + key: password + resources: + limits: + cpu: 5000m + memory: 5Gi + requests: + cpu: 100m + memory: 256Mi + front: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_front + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: KYOO_URL + value: http://kyoo-back.kyoo:5000 + - name: KYOO_APIKEYS + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: kyoo + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + matcher: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_scanner + tag: "4.5.0" + pullPolicy: IfNotPresent + args: + - matcher + env: + - name: KYOO_URL + value: http://kyoo-back.kyoo:5000 + - name: KYOO_APIKEYS + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: kyoo + - name: THEMOVIEDB_APIKEY + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: tmdb + - name: LIBRARY_LANGUAGES + value: en + - name: LIBRARY_IGNORE_PATTERN + value: .*/[dD]ownloads?/.* + - name: RABBITMQ_HOST + value: kyoo-rabbitmq + - name: RABBITMQ_DEFAULT_USER + value: kyoo + - name: RABBITMQ_DEFAULT_PASS + valueFrom: + secretKeyRef: + name: kyoo-rabbitmq-secret + key: password + resources: + limits: + cpu: 5000m + memory: 2Gi + requests: + cpu: 100m + memory: 256Mi + scanner: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_scanner + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: KYOO_URL + value: http://kyoo-back.kyoo:5000 + - name: KYOO_APIKEYS + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: kyoo + - name: THEMOVIEDB_APIKEY + valueFrom: + secretKeyRef: + name: kyoo-key-secret + key: tmdb + - name: LIBRARY_LANGUAGES + value: en + - name: LIBRARY_IGNORE_PATTERN + value: .*/[dD]ownloads?/.* + - name: RABBITMQ_HOST + value: kyoo-rabbitmq + - name: RABBITMQ_DEFAULT_USER + value: kyoo + - name: RABBITMQ_DEFAULT_PASS + valueFrom: + secretKeyRef: + name: kyoo-rabbitmq-secret + key: password + resources: + limits: + cpu: 5000m + memory: 2Gi + requests: + cpu: 100m + memory: 256Mi + transcoder: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: ghcr.io/zoriya/kyoo_transcoder + tag: "4.5.0" + pullPolicy: IfNotPresent + env: + - name: GOCODER_HWACCEL + value: qsv + - name: GOCODER_QSV_RENDERER + value: /dev/dri/renderD128 + - name: GOCODER_PRESET + value: fast + - name: GOCODER_METADATA_ROOT + value: /metadata + - name: GOCODER_CACHE_ROOT + value: /cache + resources: + limits: + cpu: 5000m + memory: 4Gi + gpu.intel.com/i915: 1 + requests: + cpu: 100m + memory: 512Mi + gpu.intel.com/i915: 1 + serviceAccount: + create: true + service: + back: + controller: back + ports: + http: + port: 5000 + targetPort: 5000 + protocol: HTTP + front: + controller: front + ports: + http: + port: 8901 + targetPort: 8901 + protocol: HTTP + transcoder: + controller: transcoder + ports: + http: + port: 7666 + targetPort: 7666 + protocol: HTTP + persistence: + back: + storageClass: ceph-block + accessMode: ReadWriteOnce + size: 50Gi + retain: true + advancedMounts: + back: + main: + - path: /metadata + readOnly: false + metadata: + storageClass: ceph-block + accessMode: ReadWriteOnce + size: 10Gi + retain: true + advancedMounts: + transcoder: + main: + - path: /metadata + readOnly: false + cache: + type: emptyDir + advancedMounts: + transcoder: + main: + - path: /cache + readOnly: false + anime: + existingClaim: kyoo-anime-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Anime" + readOnly: true + matcher: + main: + - path: "/video/Anime" + readOnly: true + transcoder: + main: + - path: "/video/Anime" + readOnly: true + anime-movies: + existingClaim: kyoo-anime-movies-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Anime Movies" + readOnly: true + matcher: + main: + - path: "/video/Anime Movies" + readOnly: true + transcoder: + main: + - path: "/video/Anime Movies" + readOnly: true + documentaries: + existingClaim: kyoo-documentaries-nfs-storage + advancedMounts: + scanner: + main: + - path: /video/Documentaries + readOnly: true + matcher: + main: + - path: /video/Documentaries + readOnly: true + transcoder: + main: + - path: /video/Documentaries + readOnly: true + documentary-shows: + existingClaim: kyoo-documentary-shows-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Documentary Shows" + readOnly: true + matcher: + main: + - path: "/video/Documentary Shows" + readOnly: true + transcoder: + main: + - path: "/video/Documentary Shows" + readOnly: true + movies: + existingClaim: kyoo-movies-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Movies" + readOnly: true + matcher: + main: + - path: "/video/Movies" + readOnly: true + transcoder: + main: + - path: "/video/Movies" + readOnly: true + movies-4k: + existingClaim: kyoo-movies-4k-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Movies 4K" + readOnly: true + matcher: + main: + - path: "/video/Movies 4K" + readOnly: true + transcoder: + main: + - path: "/video/Movies 4K" + readOnly: true + movies-classics: + existingClaim: kyoo-movies-classics-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Movies Classics" + readOnly: true + matcher: + main: + - path: "/video/Movies Classics" + readOnly: true + transcoder: + main: + - path: "/video/Movies Classics" + readOnly: true + movies-foreign: + existingClaim: kyoo-movies-foreign-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Movies Foreign" + readOnly: true + matcher: + main: + - path: "/video/Movies Foreign" + readOnly: true + transcoder: + main: + - path: "/video/Movies Foreign" + readOnly: true + stand-up: + existingClaim: kyoo-stand-up-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/Stand Up" + readOnly: true + matcher: + main: + - path: "/video/Stand Up" + readOnly: true + transcoder: + main: + - path: "/video/Stand Up" + readOnly: true + tv-shows: + existingClaim: kyoo-tv-shows-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/TV Shows" + readOnly: true + matcher: + main: + - path: "/video/TV Shows" + readOnly: true + transcoder: + main: + - path: "/video/TV Shows" + readOnly: true + tv-shows-4k: + existingClaim: kyoo-tv-shows-4k-nfs-storage + advancedMounts: + scanner: + main: + - path: "/video/TV Shows 4K" + readOnly: true + matcher: + main: + - path: "/video/TV Shows 4K" + readOnly: true + transcoder: + main: + - path: "/video/TV Shows 4K" + readOnly: true +rabbitmq: + auth: + username: kyoo + existingPasswordSecret: kyoo-rabbitmq-secret + existingSecretPasswordKey: password + existingErlangSecret: kyoo-rabbitmq-secret + existingSecretErlangKey: erlang + extraConfiguration: |- + default_vhost = / + default_permissions.configure = .* + default_permissions.read = .* + default_permissions.write = .* +meilisearch: + environment: + MEILI_NO_ANALYTICS: true + MEILI_ENV: production + auth: + existingMasterKeySecret: kyoo-meilisearch-master-key-secret + service: + type: ClusterIP + port: 7700 + persistence: + enabled: true + storageClass: ceph-block + size: 10Gi + resources: + limits: + cpu: 200m + memory: 2Gi + requests: + cpu: 10m + memory: 128Mi + serviceMonitor: + enabled: true +postgres-16-cluster: + mode: standalone + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/kyoo + endpointCredentials: kyoo-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/applications/libation/Chart.yaml b/clusters/cl01tl/applications/libation/Chart.yaml new file mode 100644 index 000000000..061d3f97a --- /dev/null +++ b/clusters/cl01tl/applications/libation/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: libation +version: 0.0.5 +sources: + - https://github.com/rmcrackan/Libation + - https://github.com/alexlebens/helm-charts/charts/libation +dependencies: + - name: libation + version: 0.0.6 + repository: http://alexlebens.github.io/helm-charts +appVersion: "11.1.0" diff --git a/clusters/cl01tl/applications/libation/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/libation/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..7fca1384b --- /dev/null +++ b/clusters/cl01tl/applications/libation/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: libation-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: libation-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/libation/templates/persistent-volume.yaml b/clusters/cl01tl/applications/libation/templates/persistent-volume.yaml new file mode 100644 index 000000000..391b19c2c --- /dev/null +++ b/clusters/cl01tl/applications/libation/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: libation-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.storage.nfs.path }} + server: {{ .Values.storage.storage.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/libation/values.yaml b/clusters/cl01tl/applications/libation/values.yaml new file mode 100644 index 000000000..92b3cb7d1 --- /dev/null +++ b/clusters/cl01tl/applications/libation/values.yaml @@ -0,0 +1,14 @@ +libation: + libation: + job: + schedule: "0 * * * *" + persistence: + config: + storageClassName: nfs-client + books: + claimName: libation-nfs-storage +storage: + storage: + nfs: + path: /volume2/Storage/Audiobooks/ + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/navidrome/Chart.yaml b/clusters/cl01tl/applications/navidrome/Chart.yaml new file mode 100644 index 000000000..e4f7296d7 --- /dev/null +++ b/clusters/cl01tl/applications/navidrome/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: navidrome +version: 0.0.2 +sources: + - https://github.com/navidrome/navidrome + - https://github.com/0xEmma/helm-charts/tree/main/charts/navidrome +dependencies: + - name: navidrome + version: 0.0.6 + repository: https://0xemma.github.io/helm-charts +appVersion: "0.51.1" \ No newline at end of file diff --git a/clusters/cl01tl/applications/navidrome/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/navidrome/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..671c2f8e9 --- /dev/null +++ b/clusters/cl01tl/applications/navidrome/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: navidrome-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: navidrome-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/navidrome/templates/persistent-volume.yaml b/clusters/cl01tl/applications/navidrome/templates/persistent-volume.yaml new file mode 100644 index 000000000..7f76a7929 --- /dev/null +++ b/clusters/cl01tl/applications/navidrome/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: navidrome-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.storage.nfs.path }} + server: {{ .Values.storage.storage.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/navidrome/values.yaml b/clusters/cl01tl/applications/navidrome/values.yaml new file mode 100644 index 000000000..c22cb1c46 --- /dev/null +++ b/clusters/cl01tl/applications/navidrome/values.yaml @@ -0,0 +1,43 @@ +navidrome: + image: + repository: deluan/navidrome + tag: "0.52.5" + ingress: + main: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: navidrome.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: navidrome-secret-tls + hosts: + - navidrome.alexlebens.net + persistence: + config: + enabled: true + mountPath: /data + accessMode: ReadWriteOnce + size: 2Gi + music: + enabled: true + mountPath: /mnt/store + type: pvc + existingClaim: navidrome-nfs-storage + env: + ND_MUSICFOLDER: /mnt/store/Music + ND_SCANSCHEDULE: 1h + ND_LOGLEVEL: info + ND_SESSIONTIMEOUT: 24h + ND_BASEURL: "/" +storage: + storage: + nfs: + path: /volume2/Storage + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/outline/Chart.yaml b/clusters/cl01tl/applications/outline/Chart.yaml new file mode 100644 index 000000000..3a26ded3f --- /dev/null +++ b/clusters/cl01tl/applications/outline/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: outline +version: 1.0.0 +sources: + - https://github.com/outline/outline + - https://github.com/minio/operator + - https://github.com/alexlebens/helm-charts/charts/outline + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: outline + version: 0.6.1 + repository: http://alexlebens.github.io/helm-charts + - name: tenant + version: 5.0.15 + alias: minio + repository: https://operator.min.io/ + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: v0.75.2 diff --git a/clusters/cl01tl/applications/outline/templates/external-secret.yaml b/clusters/cl01tl/applications/outline/templates/external-secret.yaml new file mode 100644 index 000000000..282989b7e --- /dev/null +++ b/clusters/cl01tl/applications/outline/templates/external-secret.yaml @@ -0,0 +1,176 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret-key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/key + metadataPolicy: None + property: secret-key + - secretKey: utils-key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/key + metadataPolicy: None + property: utils-key + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/outline + metadataPolicy: None + property: client + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/outline + metadataPolicy: None + property: secret + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-bucket-user-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: outline-bucket-user-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: AWS_ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/minio/auth + metadataPolicy: None + property: AWS_ACCESS_KEY_ID + - secretKey: AWS_SECRET_ACCESS_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/minio/auth + metadataPolicy: None + property: AWS_SECRET_ACCESS_KEY + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-minio-root-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: outline-bucket-auth-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: config.env + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/minio/root + metadataPolicy: None + property: config.env + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-minio-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: outline-bucket-auth-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: config.env + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /outline/minio/config + metadataPolicy: None + property: config.env + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: outline-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-outline-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-outline-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/outline/values.yaml b/clusters/cl01tl/applications/outline/values.yaml new file mode 100644 index 000000000..de178250e --- /dev/null +++ b/clusters/cl01tl/applications/outline/values.yaml @@ -0,0 +1,123 @@ +outline: + ingress: + enabled: true + className: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + host: outline.alexlebens.net + persistence: + type: s3 + s3: + credentialsSecret: outline-bucket-user-secret + region: us-east-1 + bucketName: outline + bucketUrl: https://minio-outline-api.alexlebens.net/outline + forcePathStyle: false + outline: + url: https://outline.alexlebens.net + secretKey: + existingSecretName: outline-key-secret + existingSecretKey: secret-key + utilsSecret: + existingSecretName: outline-key-secret + existingSecretKey: utils-key + database: + usernameSecret: + existingSecretName: outline-postgresql-16-cluster-app + existingSecretKey: username + passwordSecret: + existingSecretName: outline-postgresql-16-cluster-app + existingSecretKey: password + databaseName: + existingSecretName: outline-postgresql-16-cluster-app + existingSecretKey: dbname + databaseHost: + existingSecretName: outline-postgresql-16-cluster-app + existingSecretKey: host + databasePort: + existingSecretName: outline-postgresql-16-cluster-app + existingSecretKey: port + auth: + oidc: + enabled: true + clientId: + existingSecretName: outline-oidc-secret + existingSecretKey: client + clientSecret: + existingSecretName: outline-oidc-secret + existingSecretKey: secret + authUri: https://authentik.alexlebens.net/application/o/authorize/ + tokenUri: https://authentik.alexlebens.net/application/o/token/ + userinfoUri: https://authentik.alexlebens.net/application/o/userinfo/ + usernameClaim: email + displayName: Authentik + scopes: openid profile email +minio: + existingSecret: + name: outline-minio-root-secret + tenant: + name: minio-outline + configuration: + name: outline-minio-config-secret + pools: + - servers: 3 + name: pool + volumesPerServer: 2 + size: 10Gi + storageClassName: ceph-block + mountPath: /export + subPath: /data + metrics: + enabled: true + port: 9000 + protocol: http + certificate: + requestAutoCert: false + ingress: + api: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + tls: + - secretName: minio-outline-api-secret-tls + hosts: + - minio-outline-api.alexlebens.net + host: minio-outline-api.alexlebens.net + path: / + pathType: Prefix + console: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + tls: + - secretName: minio-outline-console-secret-tls + hosts: + - minio-outline.alexlebens.net + host: minio-outline.alexlebens.net + path: / + pathType: Prefix +postgres-16-cluster: + mode: standalone + kubernetesClusterName: cl01tl + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/outline + endpointCredentials: outline-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/applications/penpot/Chart.yaml b/clusters/cl01tl/applications/penpot/Chart.yaml new file mode 100644 index 000000000..58da2c956 --- /dev/null +++ b/clusters/cl01tl/applications/penpot/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +name: penpot +version: 1.0.0 +sources: + - https://github.com/penpot/penpot + - https://github.com/minio/operator + - https://github.com/bitnami/charts/tree/main/bitnami/redis + - https://github.com/alexlebens/helm-charts/charts/penpot + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: penpot + version: 0.1.0 + repository: http://alexlebens.github.io/helm-charts + - name: redis + version: 19.3.2 + repository: https://charts.bitnami.com/bitnami + - name: tenant + version: 5.0.15 + alias: minio + repository: https://operator.min.io/ + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: 2.0.0 diff --git a/clusters/cl01tl/applications/penpot/templates/external-secret.yaml b/clusters/cl01tl/applications/penpot/templates/external-secret.yaml new file mode 100644 index 000000000..9c5e50fed --- /dev/null +++ b/clusters/cl01tl/applications/penpot/templates/external-secret.yaml @@ -0,0 +1,169 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-key-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /penpot/key + metadataPolicy: None + property: key + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/penpot + metadataPolicy: None + property: client + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/penpot + metadataPolicy: None + property: secret + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-bucket-user-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-bucket-user-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: AWS_ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /penpot/minio/auth + metadataPolicy: None + property: AWS_ACCESS_KEY_ID + - secretKey: AWS_SECRET_ACCESS_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /penpot/minio/auth + metadataPolicy: None + property: AWS_SECRET_ACCESS_KEY + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-minio-root-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-bucket-auth-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: config.env + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /penpot/minio/root + metadataPolicy: None + property: config.env + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-minio-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-minio-config-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: config.env + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /penpot/minio/config + metadataPolicy: None + property: config.env + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: penpot-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: penpot-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-penpot-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-penpot-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/penpot/values.yaml b/clusters/cl01tl/applications/penpot/values.yaml new file mode 100644 index 000000000..e179316e7 --- /dev/null +++ b/clusters/cl01tl/applications/penpot/values.yaml @@ -0,0 +1,135 @@ +penpot: + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: penpot.alexlebens.net + tls: + - secretName: penpot-secret-tls + hosts: + - penpot.alexlebens.net + persistence: + enabled: true + storageClass: ceph-block + size: 8Gi + accessModes: + - ReadWriteOnce + config: + publicURI: https://penpot.alexlebens.net + flags: enable-registration enable-insecure-register enable-login enable-login-with-oidc disable-demo-users disable-demo-warning + apiSecretKey: + existingSecretName: penpot-key-secret + existingSecretKey: key + postgresql: + host: penpot-postgresql-16-cluster-rw.penpot.svc.cluster.local + port: 5432 + database: app + existingSecret: penpot-postgresql-16-cluster-app + secretKeys: + usernameKey: username + passwordKey: password + redis: + host: penpot-redis-headless.penpot.svc.cluster.local + port: 6379 + database: 0 + assets: + storageBackend: assets-s3 + s3: + region: us-east-1 + bucket: penpot + endpointURI: https://minio-penpot-api.alexlebens.net/penpot + existingSecret: penpot-bucket-user-secret + secretKeys: + accessKeyIDKey: AWS_ACCESS_KEY_ID + secretAccessKey: AWS_SECRET_ACCESS_KEY + telemetryEnabled: false + providers: + oidc: + enabled: true + baseURI: https://authentik.alexlebens.net/application/o/ + authURI: https://authentik.alexlebens.net/application/o/authorize/ + tokenURI: https://authentik.alexlebens.net/application/o/token/ + userURI: https://authentik.alexlebens.net/application/o/userinfo/ + roles: "" + rolesAttribute: "" + scopes: "openid profile email" + nameAttribute: preferred_username + emailAttribute: email + existingSecret: penpot-oidc-secret + secretKeys: + oidcClientIDKey: client + oidcClientSecretKey: secret +redis: + architecture: standalone + auth: + enabled: false +minio: + existingSecret: + name: penpot-minio-root-secret + tenant: + name: minio-penpot + configuration: + name: penpot-minio-config-secret + pools: + - servers: 3 + name: pool + volumesPerServer: 2 + size: 10Gi + storageClassName: ceph-block + mountPath: /export + subPath: /data + metrics: + enabled: true + port: 9000 + protocol: http + certificate: + requestAutoCert: false + ingress: + api: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + tls: + - secretName: minio-penpot-api-secret-tls + hosts: + - minio-penpot-api.alexlebens.net + host: minio-penpot-api.alexlebens.net + path: / + pathType: Prefix + console: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + tls: + - secretName: minio-penpot-console-secret-tls + hosts: + - minio-penpot.alexlebens.net + host: minio-penpot.alexlebens.net + path: / + pathType: Prefix +postgres-16-cluster: + mode: standalone + kubernetesClusterName: cl01tl + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/penpot + endpointCredentials: penpot-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/applications/plex/Chart.yaml b/clusters/cl01tl/applications/plex/Chart.yaml new file mode 100644 index 000000000..7fba3e774 --- /dev/null +++ b/clusters/cl01tl/applications/plex/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: plex +version: 0.0.1 +sources: + - https://www.plex.tv/ + - https://github.com/k8s-home-lab/helm-charts/tree/master/charts/stable/plex +dependencies: + - name: plex + version: 7.1.4 + repository: https://k8s-home-lab.github.io/helm-charts/ +appVersion: 1.40.0.7998-c29d4c0c8 diff --git a/clusters/cl01tl/applications/plex/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/plex/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..7f6ca9641 --- /dev/null +++ b/clusters/cl01tl/applications/plex/templates/persistent-volume-claim.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: plex-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: plex-config + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.storage.config.storageSize }} + storageClassName: {{ .Values.storage.config.storageClassName }} + volumeMode: {{ .Values.storage.config.volumeMode }} diff --git a/clusters/cl01tl/applications/plex/templates/persistent-volume.yaml b/clusters/cl01tl/applications/plex/templates/persistent-volume.yaml new file mode 100644 index 000000000..67b69e467 --- /dev/null +++ b/clusters/cl01tl/applications/plex/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: plex-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.media.nfs.path }} + server: {{ .Values.storage.media.nfs.server }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/plex/values.yaml b/clusters/cl01tl/applications/plex/values.yaml new file mode 100644 index 000000000..d865a6724 --- /dev/null +++ b/clusters/cl01tl/applications/plex/values.yaml @@ -0,0 +1,78 @@ +plex: + image: + repository: ghcr.io/onedr0p/plex + tag: 1.40.2.8395-c67dce28e + env: + ADVERTISE_IP: "https://plex.alexlebens.net:443/" + ALLOWED_NETWORKS: "10.0.0.0/8,192.168.1.0/24" + service: + main: + primary: true + type: LoadBalancer + annotations: + metallb.universe.tf/allow-shared-ip: "external" + externalIPs: + - 192.168.1.17 + - 192.168.1.16 + - 192.168.1.15 + ports: + http: + port: 32400 + ingress: + main: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: plex.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: plex-secret-tls + hosts: + - plex.alexlebens.net + hostNetwork: false + persistence: + config: + enabled: true + existingClaim: plex-config + transcode: + enabled: true + type: emptyDir + media: + enabled: true + mountPath: /mnt/store + type: pvc + existingClaim: plex-nfs-storage + podSecurityContext: + runAsUser: 568 + runAsGroup: 568 + fsGroup: 568 + fsGroupChangePolicy: "OnRootMismatch" + supplementalGroups: + - 44 + - 100 + - 109 + - 65539 + resources: + requests: + gpu.intel.com/i915: 1 + cpu: 100m + memory: 256Mi + limits: + gpu.intel.com/i915: 1 + cpu: 4000m + memory: 4096Mi +storage: + config: + storageClassName: ceph-block + storageSize: 80Gi + volumeMode: Filesystem + media: + nfs: + path: /volume2/Storage + server: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/taiga/Chart.yaml b/clusters/cl01tl/applications/taiga/Chart.yaml new file mode 100644 index 000000000..8edfc14c6 --- /dev/null +++ b/clusters/cl01tl/applications/taiga/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: taiga +version: 1.0.0 +sources: + - https://github.com/taigaio + - https://github.com/rabbitmq/rabbitmq-server + - https://github.com/alexlebens/helm-charts/charts/taiga + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: taiga + version: 0.2.2 + repository: http://alexlebens.github.io/helm-charts + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: 6.7.7 diff --git a/clusters/cl01tl/applications/taiga/templates/external-secret.yaml b/clusters/cl01tl/applications/taiga/templates/external-secret.yaml new file mode 100644 index 000000000..c5ed5f665 --- /dev/null +++ b/clusters/cl01tl/applications/taiga/templates/external-secret.yaml @@ -0,0 +1,200 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: taiga-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: taiga-key-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /taiga/key + metadataPolicy: None + property: key + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: taiga-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: taiga-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: client + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: secret + - secretKey: scopes + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: scopes + - secretKey: signatureAlgorithm + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: signatureAlgorithm + - secretKey: baseUrl + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: baseUrl + - secretKey: jwksEndpoint + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: jwksEndpoint + - secretKey: authorizationEndpoint + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: authorizationEndpoint + - secretKey: tokenEndpoint + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: tokenEndpoint + - secretKey: userEndpoint + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/taiga + metadataPolicy: None + property: userEndpoint + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: taiga-async-rabbitmq-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: taiga-async-rabbitmq-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /taiga/rabbitmq/async + metadataPolicy: None + property: password + - secretKey: erlang + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /taiga/rabbitmq/async + metadataPolicy: None + property: erlang + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: taiga-events-rabbitmq-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: taiga-events-rabbitmq-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /taiga/rabbitmq/events + metadataPolicy: None + property: password + - secretKey: erlang + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /taiga/rabbitmq/events + metadataPolicy: None + property: erlang + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: taiga-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: taiga-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-taiga-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-taiga-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/taiga/values.yaml b/clusters/cl01tl/applications/taiga/values.yaml new file mode 100644 index 000000000..b03654b6f --- /dev/null +++ b/clusters/cl01tl/applications/taiga/values.yaml @@ -0,0 +1,152 @@ +taiga: + serviceAccount: + create: true + secretKey: + existingSecretName: taiga-key-secret + existingSecretKey: key + createInitialUser: false + enableTelemetry: false + publicRegisterEnabled: false + postgresql: + existingSecretName: taiga-postgresql-16-cluster-app + usernameKey: username + passwordKey: password + databaseNameKey: dbname + hostKey: host + portKey: port + oidc: + enabled: true + existingSecretName: taiga-oidc-secret + scopesKey: scopes + signatureAlgorithmKey: signatureAlgorithm + clientIdKey: client + clientSecretKey: secret + baseUrlKey: baseUrl + jwksEndpointKey: jwksEndpoint + authorizationEndpointKey: authorizationEndpoint + tokenEndpointKey: tokenEndpoint + userEndpointKey: userEndpoint + back: + image: + repository: ghcr.io/alexlebens/taiga-back-docker-oidc + tag: latest + pullPolicy: Always + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + livenessProbe: + enabled: true + readinessProbe: + enabled: true + async: + image: + repository: ghcr.io/alexlebens/taiga-back-docker-oidc + tag: latest + pullPolicy: Always + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + livenessProbe: + enabled: true + readinessProbe: + enabled: true + async-rabbitmq: + auth: + username: taiga + existingPasswordSecret: taiga-async-rabbitmq-secret + existingSecretPasswordKey: password + existingErlangSecret: taiga-async-rabbitmq-secret + existingSecretErlangKey: erlang + events: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + livenessProbe: + enabled: false + readinessProbe: + enabled: false + events-rabbitmq: + auth: + username: taiga + existingPasswordSecret: taiga-events-rabbitmq-secret + existingSecretPasswordKey: password + existingErlangSecret: taiga-events-rabbitmq-secret + existingSecretErlangKey: erlang + protected: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + livenessProbe: + enabled: false + readinessProbe: + enabled: false + front: + image: + repository: ghcr.io/alexlebens/taiga-front-docker-oidc + tag: latest + pullPolicy: Always + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + livenessProbe: + enabled: true + readinessProbe: + enabled: true + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + className: traefik + host: taiga.alexlebens.net + persistence: + static: + enabled: true + storageClass: nfs-client + accessMode: ReadWriteMany + size: 1Gi + media: + enabled: true + storageClass: nfs-client + accessMode: ReadWriteMany + size: 1Gi +postgres-16-cluster: + mode: standalone + kubernetesClusterName: cl01tl + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + prometheusRule: + enabled: false + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/taiga + endpointCredentials: taiga-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/applications/tubearchivist/Chart.yaml b/clusters/cl01tl/applications/tubearchivist/Chart.yaml new file mode 100644 index 000000000..3b2fccecb --- /dev/null +++ b/clusters/cl01tl/applications/tubearchivist/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: tubearchivist +version: 0.0.7 +sources: + - https://github.com/tubearchivist/tubearchivist + - https://github.com/alexlebens/helm-charts/charts/tubearchivist + - https://github.com/tubearchivist/tubearchivist-jf + - https://github.com/alexlebens/helm-charts/charts/tubearchivist-to-jellyfin +dependencies: + - name: tubearchivist + version: 0.2.7 + repository: http://alexlebens.github.io/helm-charts +appVersion: v0.4.6 diff --git a/clusters/cl01tl/applications/tubearchivist/templates/external-secret.yaml b/clusters/cl01tl/applications/tubearchivist/templates/external-secret.yaml new file mode 100644 index 000000000..11dc8ea1d --- /dev/null +++ b/clusters/cl01tl/applications/tubearchivist/templates/external-secret.yaml @@ -0,0 +1,83 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: tubearchivist-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ELASTIC_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: ELASTIC_PASSWORD + - secretKey: ES_URL + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: ES_URL + - secretKey: REDIS_HOST + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: REDIS_HOST + - secretKey: TA_HOST + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: TA_HOST + - secretKey: TA_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: TA_PASSWORD + - secretKey: TA_USERNAME + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: TA_USERNAME + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: tubearchivist-elasticsearch-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ELASTIC_PASSWORD + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tubearchivist/env + metadataPolicy: None + property: ELASTIC_PASSWORD diff --git a/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume-claim.yaml b/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..99b7073dc --- /dev/null +++ b/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: tubearchivist-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeName: tubearchivist-nfs-storage + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume.yaml b/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume.yaml new file mode 100644 index 000000000..042f2107f --- /dev/null +++ b/clusters/cl01tl/applications/tubearchivist/templates/persistent-volume.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: tubearchivist-nfs-storage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs-client + capacity: + storage: 1Gi + accessModes: + - ReadWriteMany + nfs: + path: {{ .Values.storage.youtube.nfsPath }} + server: {{ .Values.storage.youtube.nfsServer }} + mountOptions: + - vers=4 + - minorversion=1 + - noac diff --git a/clusters/cl01tl/applications/tubearchivist/values.yaml b/clusters/cl01tl/applications/tubearchivist/values.yaml new file mode 100644 index 000000000..37fade027 --- /dev/null +++ b/clusters/cl01tl/applications/tubearchivist/values.yaml @@ -0,0 +1,46 @@ +tubearchivist: + deployment: + env: + TZ: US/Central + envFrom: + - secretRef: + name: tubearchivist-config-secret + resources: + limits: + memory: 2Gi + cpu: 1000m + ingress: + enabled: true + className: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + host: tubearchivist.alexlebens.net + persistence: + cache: + enabled: true + storageClassName: ceph-block + storageSize: 80Gi + youtube: + claimName: tubearchivist-nfs-storage + elasticsearch: + global: + storageClass: ceph-block + extraEnvVarsSecret: tubearchivist-elasticsearch-secret + extraConfig: + path: + repo: /usr/share/elasticsearch/data/snapshot + extraVolumes: + - name: snapshot + nfs: + path: /volume2/Storage/TubeArchivist + server: synologybond.alexlebens.net + extraVolumeMounts: + - name: snapshot + mountPath: /usr/share/elasticsearch/data/snapshot + snapshotRepoPath: /usr/share/elasticsearch/data/snapshot +storage: + youtube: + nfsPath: /volume2/Storage/YouTube + nfsServer: synologybond.alexlebens.net diff --git a/clusters/cl01tl/applications/vikunja/Chart.yaml b/clusters/cl01tl/applications/vikunja/Chart.yaml new file mode 100644 index 000000000..92f16b1f8 --- /dev/null +++ b/clusters/cl01tl/applications/vikunja/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: vikunja +version: 1.0.0 +sources: + - https://kolaente.dev/vikunja/vikunja + - https://kolaente.dev/vikunja/helm-chart + - https://github.com/bitnami/charts/tree/main/bitnami/redis + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: vikunja + version: 0.4.3 + repository: oci://kolaente.dev/vikunja + - name: redis + version: 19.3.2 + repository: https://charts.bitnami.com/bitnami + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: v0.22.1 diff --git a/clusters/cl01tl/applications/vikunja/templates/external-secret.yaml b/clusters/cl01tl/applications/vikunja/templates/external-secret.yaml new file mode 100644 index 000000000..b6e1d8ade --- /dev/null +++ b/clusters/cl01tl/applications/vikunja/templates/external-secret.yaml @@ -0,0 +1,62 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vikunja-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: config.yml + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /vikunja/config + metadataPolicy: None + property: config.yml + - secretKey: redis-password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /vikunja/config + metadataPolicy: None + property: redis-password + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vikunja-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vikunja-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-vikunja-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-vikunja-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/applications/vikunja/values.yaml b/clusters/cl01tl/applications/vikunja/values.yaml new file mode 100644 index 000000000..ca35a74b0 --- /dev/null +++ b/clusters/cl01tl/applications/vikunja/values.yaml @@ -0,0 +1,117 @@ +vikunja: + api: + enabled: true + image: + repository: vikunja/api + tag: 0.22.1 + persistence: + data: + enabled: true + size: 10Gi + mountPath: /app/vikunja/files + storageClass: ceph-block + config: + type: secret + name: vikunja-config-secret + configMaps: + config: + enabled: false + ingress: + main: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + hosts: + - host: vikunja.alexlebens.net + paths: + - path: /api/v1/ + tls: + - hosts: + - vikunja.alexlebens.net + secretName: vikunja-secret-tls + env: + VIKUNJA_SERVICE_FRONTENDURL: https://vikunja.alexlebens.net + VIKUNJA_SERVICE_ENABLEREGISTRATION: "true" + VIKUNJA_SERVICE_TIMEZONE: US/Central + VIKUNJA_REDIS_ENABLED: "true" + VIKUNJA_REDIS_HOST: vikunja-redis-headless:6379 + VIKUNJA_REDIS_PASSWORD: + valueFrom: + secretKeyRef: + name: vikunja-config-secret + key: redis-password + VIKUNJA_DATABASE_USER: + valueFrom: + secretKeyRef: + name: vikunja-postgresql-16-cluster-app + key: user + VIKUNJA_DATABASE_DATABASE: + valueFrom: + secretKeyRef: + name: vikunja-postgresql-16-cluster-app + key: dbname + VIKUNJA_DATABASE_HOST: + valueFrom: + secretKeyRef: + name: vikunja-postgresql-16-cluster-app + key: host + VIKUNJA_DATABASE_PASSWORD: + valueFrom: + secretKeyRef: + name: vikunja-postgresql-16-cluster-app + key: password + frontend: + enabled: true + image: + repository: vikunja/frontend + tag: 0.22.1 + env: + VIKUNJA_API_URL: https://vikunja.alexlebens.net/api/v1/ + ingress: + main: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + hosts: + - host: vikunja.alexlebens.net + paths: + - path: / + tls: + - hosts: + - vikunja.alexlebens.net + secretName: vikunja-secret-tls + postgresql: + enabled: false + redis: + enabled: false + typesense: + enabled: false +redis: + architecture: standalone + auth: + enabled: true + existingSecret: vikunja-config-secret + existingSecretPasswordKey: redis-password +postgres-16-cluster: + mode: standalone + kubernetesClusterName: cl01tl + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/vikunja + endpointCredentials: vikunja-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/deployment/argo-rollouts/Chart.yaml b/clusters/cl01tl/deployment/argo-rollouts/Chart.yaml new file mode 100644 index 000000000..ec5c99536 --- /dev/null +++ b/clusters/cl01tl/deployment/argo-rollouts/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: argo-rollouts +version: 1.0.0 +sources: + - https://github.com/argoproj/argo-rollouts + - https://github.com/argoproj/argo-helm/tree/main/charts +dependencies: + - name: argo-rollouts + version: 2.35.2 + repository: https://argoproj.github.io/argo-helm +appVersion: v1.6.6 diff --git a/clusters/cl01tl/deployment/argo-rollouts/values.yaml b/clusters/cl01tl/deployment/argo-rollouts/values.yaml new file mode 100644 index 000000000..4a3a562bc --- /dev/null +++ b/clusters/cl01tl/deployment/argo-rollouts/values.yaml @@ -0,0 +1,45 @@ +argo-rollouts: + controller: + metrics: + enabled: true + serviceMonitor: + enabled: true + namespace: argocd + dashboard: + enabled: true + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + ingressClassName: traefik + hosts: + - argo-rollouts.alexlebens.net + tls: + - secretName: argo-rollouts-secret-tls + hosts: + - argo-rollouts.alexlebens.net + + notifications: + notifiers: {} + # service.slack: | + # token: $slack-token + + # -- Notification templates + templates: {} + # template.my-purple-template: | + # message: | + # Rollout {{.rollout.metadata.name}} has purple image + # slack: + # attachments: | + # [{ + # "title": "{{ .rollout.metadata.name}}", + # "color": "#800080" + # }] + + # -- The trigger defines the condition when the notification should be sent + triggers: {} + # trigger.on-purple: | + # - send: [my-purple-template] + # when: rollout.spec.template.spec.containers[0].image == 'argoproj/rollouts-demo:purple' diff --git a/clusters/cl01tl/deployment/argo-workflows/Chart.yaml b/clusters/cl01tl/deployment/argo-workflows/Chart.yaml new file mode 100644 index 000000000..0cb2c5990 --- /dev/null +++ b/clusters/cl01tl/deployment/argo-workflows/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: argo-workflows +version: 1.0.0 +sources: + - https://github.com/argoproj/argo-workflows + - https://github.com/argoproj/argo-events + - https://github.com/argoproj/argo-helm/tree/main/charts + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: argo-workflows + version: 0.41.4 + repository: https://argoproj.github.io/argo-helm + - name: argo-events + version: 2.4.4 + repository: https://argoproj.github.io/argo-helm + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: v3.5.6 diff --git a/clusters/cl01tl/deployment/argo-workflows/templates/external-secret.yaml b/clusters/cl01tl/deployment/argo-workflows/templates/external-secret.yaml new file mode 100644 index 000000000..3af13e402 --- /dev/null +++ b/clusters/cl01tl/deployment/argo-workflows/templates/external-secret.yaml @@ -0,0 +1,62 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argo-workflows-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: argo-workflows-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/argo-workflows + metadataPolicy: None + property: secret + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/argo-workflows + metadataPolicy: None + property: client + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argo-workflows-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: argo-workflows-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-argo-workflows-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-argo-workflows-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/deployment/argo-workflows/values.yaml b/clusters/cl01tl/deployment/argo-workflows/values.yaml new file mode 100644 index 000000000..d56195a9a --- /dev/null +++ b/clusters/cl01tl/deployment/argo-workflows/values.yaml @@ -0,0 +1,121 @@ +argo-workflows: + controller: + metricsConfig: + enabled: true + persistence: + connectionPool: + maxIdleConns: 100 + maxOpenConns: 0 + nodeStatusOffLoad: true + archive: true + postgresql: + host: argo-workflows-postgresql-16-cluster-rw + port: 5432 + database: app + tableName: app + userNameSecret: + name: argo-workflows-postgresql-16-cluster-app + key: username + passwordSecret: + name: argo-workflows-postgresql-16-cluster-app + key: password + ssl: false + sslMode: disable + workflowWorkers: 2 + workflowTTLWorkers: 1 + podCleanupWorkers: 1 + cronWorkflowWorkers: 1 + telemetryConfig: + enabled: true + serviceMonitor: + enabled: true + name: workflow-controller + workflowNamespaces: + - argocd + server: + authModes: + - sso + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + ingressClassName: traefik + hosts: + - argo-workflows.alexlebens.net + tls: + - secretName: argoworkflows-example-tls + hosts: + - argo-workflows.alexlebens.net + sso: + enabled: true + issuer: https://authentik.alexlebens.net/application/o/argo-workflows/ + clientId: + name: argo-workflows-oidc-secret + key: client + clientSecret: + name: argo-workflows-oidc-secret + key: secret + redirectUrl: https://argo-workflows.alexlebens.net/oauth2/callback + rbac: + enabled: false + scopes: + - openid + - email + - profile + useStaticCredentials: true + artifactRepository: + archiveLogs: false + s3: {} + # accessKeySecret: + # name: "{{ .Release.Name }}-minio" + # key: accesskey + # secretKeySecret: + # name: "{{ .Release.Name }}-minio" + # key: secretkey + # insecure: true + # bucket: + # endpoint: + # region: + # encryptionOptions: + # enableEncryption: true + +argo-events: + global: + image: + repository: quay.io/argoproj/argo-events + tag: v1.9.1 + controller: + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + metrics: + enabled: true + serviceMonitor: + enabled: true + namespace: argocd + webhook: + enabled: true +postgres-16-cluster: + mode: standalone + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + prometheusRule: + enabled: true + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/argo-workflows + endpointCredentials: argo-workflows-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/deployment/argocd/Chart.yaml b/clusters/cl01tl/deployment/argocd/Chart.yaml new file mode 100644 index 000000000..694cf95d4 --- /dev/null +++ b/clusters/cl01tl/deployment/argocd/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: argocd +version: 0.1.0 +home: https://outline.alexlebens.net/doc/argo-cd-qLEdrgdwOD +sources: + - https://github.com/argoproj/argo-cd + - https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd +dependencies: + - name: argo-cd + version: 6.9.3 + repository: https://argoproj.github.io/argo-helm +appVersion: v2.10.8 diff --git a/clusters/cl01tl/deployment/argocd/templates/external-secret.yaml b/clusters/cl01tl/deployment/argocd/templates/external-secret.yaml new file mode 100644 index 000000000..005c2440d --- /dev/null +++ b/clusters/cl01tl/deployment/argocd/templates/external-secret.yaml @@ -0,0 +1,110 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "{{ .Release.Name }}-server" + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: server + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/argocd + metadataPolicy: None + property: secret + - secretKey: client + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/argocd + metadataPolicy: None + property: client + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-cluster-cl02do-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "{{ .Release.Name }}-server" + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: server + app.kubernetes.io/part-of: {{ .Release.Name }} + argocd.argoproj.io/secret-type: cluster +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: name + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/cluster/cl02do + metadataPolicy: None + property: name + - secretKey: server + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/cluster/cl02do + metadataPolicy: None + property: server + - secretKey: config + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/cluster/cl02do + metadataPolicy: None + property: config + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: argocd-repo-alexlebens-dev-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: "{{ .Release.Name }}-server" + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: server + app.kubernetes.io/part-of: {{ .Release.Name }} + argocd.argoproj.io/secret-type: repository +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: type + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/repo/alexlebens-dev + metadataPolicy: None + property: type + - secretKey: url + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/repo/alexlebens-dev + metadataPolicy: None + property: url + - secretKey: sshPrivateKey + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/repo/alexlebens-dev + metadataPolicy: None + property: sshPrivateKey diff --git a/clusters/cl01tl/deployment/argocd/values.yaml b/clusters/cl01tl/deployment/argocd/values.yaml new file mode 100644 index 000000000..be53a3932 --- /dev/null +++ b/clusters/cl01tl/deployment/argocd/values.yaml @@ -0,0 +1,66 @@ +argo-cd: + crds: + install: true + configs: + cm: + admin.enabled: true + url: https://argocd.alexlebens.net + statusbadge.enabled: true + dex.config: | + connectors: + - config: + issuer: https://authentik.alexlebens.net/application/o/argocd/ + clientID: $argocd-oidc-secret:client + clientSecret: $argocd-oidc-secret:secret + insecureEnableGroups: true + scopes: + - openid + - profile + - email + - groups + name: authentik + type: oidc + id: authentik + rbac: + policy.csv: | + g, ArgoCD Admins, role:admin + params: + server.insecure: true + server: + replicas: 2 + ingress: + enabled: true + controller: generic + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hostname: argocd.alexlebens.net + tls: true + metrics: + enabled: true + serviceMonitor: + enabled: true + dex: + enabled: true + redis-ha: + enabled: true + controller: + replicas: 1 + metrics: + enabled: true + serviceMonitor: + enabled: true + repoServer: + replicas: 2 + metrics: + enabled: true + serviceMonitor: + enabled: true + applicationSet: + replicas: 2 + metrics: + enabled: true + serviceMonitor: + enabled: true diff --git a/clusters/cl01tl/deployment/kargo/Chart.yaml b/clusters/cl01tl/deployment/kargo/Chart.yaml new file mode 100644 index 000000000..652608b03 --- /dev/null +++ b/clusters/cl01tl/deployment/kargo/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: kargo +version: 1.0.0 +sources: + - https://github.com/akuity/kargo + - https://github.com/akuity/kargo/blob/main/charts/kargo/Chart.yaml +dependencies: + - name: kargo + version: 0.6.0 + repository: oci://ghcr.io/akuity/kargo-charts +appVersion: v0.5.1 diff --git a/clusters/cl01tl/deployment/kargo/templates/external-secret.yaml b/clusters/cl01tl/deployment/kargo/templates/external-secret.yaml new file mode 100644 index 000000000..48b5cf4da --- /dev/null +++ b/clusters/cl01tl/deployment/kargo/templates/external-secret.yaml @@ -0,0 +1,56 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kargo-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kargo-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: CLIENT_SECRET + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/kargo + metadataPolicy: None + property: secret + - secretKey: CLIENT_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/kargo + metadataPolicy: None + property: client + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kargo-cluster-cl02do-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: kargo-cluster-cl02do-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + argocd.argoproj.io/secret-type: cluster +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: kubeconfig + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /argocd/credentials/cluster/cl02do + metadataPolicy: None + property: kubeconfig diff --git a/clusters/cl01tl/deployment/kargo/values.yaml b/clusters/cl01tl/deployment/kargo/values.yaml new file mode 100644 index 000000000..4085d6d33 --- /dev/null +++ b/clusters/cl01tl/deployment/kargo/values.yaml @@ -0,0 +1,120 @@ +kargo: + api: + host: kargo.alexlebens.net + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + tls: + enabled: false + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + ingressClassName: traefik + tls: + enabled: true + selfSignedCert: false + adminAccount: + enabled: false + oidc: + enabled: true + admins: + groups: ["ArgoCD Admins"] + dex: + enabled: true + image: + repository: ghcr.io/dexidp/dex + tag: v2.39.1 + env: + - name: CLIENT_ID + valueFrom: + secretKeyRef: + name: kargo-oidc-secret + key: CLIENT_ID + - name: CLIENT_SECRET + valueFrom: + secretKeyRef: + name: kargo-oidc-secret + key: CLIENT_SECRET + tls: + selfSignedCert: false + skipApprovalScreen: true + connectors: + - type: oidc + id: authentik + name: Authentik + config: + issuer: https://authentik.alexlebens.net/application/o/kargo/ + clientID: "$CLIENT_ID" + clientSecret: "$CLIENT_SECRET" + redirectURI: https://kargo.alexlebens.net/dex/callback + insecureEnableGroups: true + scopes: + - openid + - profile + - email + - groups + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + argocd: + urls: + "": https://argocd.alexlebens.net + rollouts: + integrationEnabled: true + controller: + enabled: true + gitClient: + name: "Kargo cl01tl" + email: "alexanderlebens@gmail.com" + argocd: + integrationEnabled: true + rollouts: + integrationEnabled: true + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + managementController: + enabled: true + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + webhooks: + register: true + webhooksServer: + tls: + selfSignedCert: true + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + garbageCollector: + schedule: "0 * * * *" + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi diff --git a/clusters/cl01tl/deployment/stack/Chart.yaml b/clusters/cl01tl/deployment/stack/Chart.yaml new file mode 100644 index 000000000..f62dea7ef --- /dev/null +++ b/clusters/cl01tl/deployment/stack/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: stack +version: 1.0.0 +sources: + - https://github.com/alexlebens/alexlebens-net.git +appVersion: 1.0.0 diff --git a/clusters/cl01tl/deployment/stack/templates/application-set.yaml b/clusters/cl01tl/deployment/stack/templates/application-set.yaml new file mode 100644 index 000000000..2453b0a87 --- /dev/null +++ b/clusters/cl01tl/deployment/stack/templates/application-set.yaml @@ -0,0 +1,55 @@ +{{- range $index, $stack := .Values.applicationSet }} +--- +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: {{ $stack.name }} + namespace: {{ $.Release.Namespace }} + labels: + app.kubernetes.io/name: {{ $stack.name }} + app.kubernetes.io/instance: {{ $stack.name }} + app.kubernetes.io/version: {{ $.Chart.AppVersion }} + app.kubernetes.io/component: {{ $stack.name }} + app.kubernetes.io/part-of: {{ $.Release.Name }} +spec: + syncPolicy: + applicationsSync: create-only + preserveResourcesOnDeletion: true + generators: + - git: + repoURL: {{ $.Values.git.repo }} + revision: {{ $.Values.git.revision }} + directories: + - path: "{{ $.Values.git.path }}/{{ $stack.name }}/*" + template: + metadata: + name: '{{ `{{path.basename}}` }}' + finalizers: + - resources-finalizer.argocd.argoproj.io + spec: + destination: + name: in-cluster + namespace: '{{ $stack.namespace | default `{{path.basename}}` }}' + project: default + revisionHistoryLimit: 3 + source: + repoURL: {{ $.Values.git.repo }} + targetRevision: {{ $.Values.git.revision }} + path: '{{ `{{path}}` }}' + ignoreDifferences: + {{- toYaml $stack.ignoreDifferences | nindent 8 }} + syncPolicy: + {{- if $stack.syncPolicy.automated.enabled }} + automated: + prune: {{ $stack.syncPolicy.automated.prune | default false }} + selfHeal: {{ $stack.syncPolicy.automated.selfHeal | default false }} + {{- end }} + retry: + limit: 3 + backoff: + duration: 1m + factor: 2 + maxDuration: 15m + syncOptions: + {{- toYaml $stack.syncPolicy.syncOptions | nindent 10 }} +{{- end }} diff --git a/clusters/cl01tl/deployment/stack/templates/application.yaml b/clusters/cl01tl/deployment/stack/templates/application.yaml new file mode 100644 index 000000000..39bb82815 --- /dev/null +++ b/clusters/cl01tl/deployment/stack/templates/application.yaml @@ -0,0 +1,82 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: cilium + namespace: {{ .Release.Namespace }} + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: {{ .Values.application.cilium.source.repo }} + targetRevision: {{ .Values.application.cilium.source.revision }} + path: "{{ .Values.git.path }}/{{ .Values.application.cilium.source.path }}" + destination: + name: in-cluster + namespace: {{ .Values.application.cilium.namespace }} + revisionHistoryLimit: 3 + syncPolicy: + {{- toYaml .Values.application.cilium.syncPolicy | nindent 4 }} + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: metrics-server + namespace: {{ .Release.Namespace }} + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: {{ .Values.application.metricsServer.source.repo }} + targetRevision: {{ .Values.application.metricsServer.source.revision }} + path: "{{ .Values.git.path }}/{{ .Values.application.metricsServer.source.path }}" + destination: + name: in-cluster + namespace: {{ .Values.application.metricsServer.namespace }} + revisionHistoryLimit: 3 + syncPolicy: + {{- toYaml .Values.application.metricsServer.syncPolicy | nindent 4 }} + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: kubelet-serving-cert-approver + namespace: {{ .Release.Namespace }} + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: {{ .Values.application.kubeletServingCertApprover.source.repo }} + targetRevision: {{ .Values.application.kubeletServingCertApprover.source.revision }} + path: "{{ .Values.git.path }}/{{ .Values.application.kubeletServingCertApprover.source.path }}" + destination: + name: in-cluster + namespace: {{ .Values.application.kubeletServingCertApprover.namespace }} + revisionHistoryLimit: 3 + syncPolicy: + {{- toYaml .Values.application.kubeletServingCertApprover.syncPolicy | nindent 4 }} + +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: prometheus-operator-crds + namespace: {{ .Release.Namespace }} + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: {{ .Values.application.prometheusOperatorCrds.source.repo }} + targetRevision: {{ .Values.application.prometheusOperatorCrds.source.revision }} + path: "{{ .Values.git.path }}/{{ .Values.application.prometheusOperatorCrds.source.path }}" + destination: + name: in-cluster + namespace: {{ .Values.application.prometheusOperatorCrds.namespace }} + revisionHistoryLimit: 3 + syncPolicy: + {{- toYaml .Values.application.prometheusOperatorCrds.syncPolicy | nindent 4 }} diff --git a/clusters/cl01tl/deployment/stack/values.yaml b/clusters/cl01tl/deployment/stack/values.yaml new file mode 100644 index 000000000..80d1d8675 --- /dev/null +++ b/clusters/cl01tl/deployment/stack/values.yaml @@ -0,0 +1,148 @@ +git: + repo: git@github.com:alexlebens/alexlebens-net.git + revision: HEAD + path: clusters/cl01tl +applicationSet: + - name: applications + syncPolicy: + automated: + enabled: true + prune: true + selfheal: false + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=false + - PruneLast=true + - name: deployment + namespace: argocd + syncPolicy: + automated: + enabled: true + prune: true + selfheal: false + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=false + - PruneLast=true + - name: platform + syncPolicy: + automated: + enabled: true + prune: true + selfheal: false + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=true + - PruneLast=true + - name: services + ignoreDifferences: + - group: "" + kind: Service + jqPathExpressions: + - .status.loadBalancer.ingress[].ipMode + syncPolicy: + automated: + enabled: true + prune: true + selfheal: false + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=true + - PruneLast=true + - name: storage + syncPolicy: + automated: + enabled: true + prune: true + selfheal: false + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=false + - PruneLast=true +application: + cilium: + namespace: kube-system + source: + repo: git@github.com:alexlebens/alexlebens-net.git + revision: HEAD + path: standalone/cilium + syncPolicy: + retry: + limit: 10 + backoff: + duration: 1m + factor: 2 + maxDuration: 16m + syncOptions: + - CreateNamespace=false + - ApplyOutOfSyncOnly=true + - ServerSideApply=true + - PruneLast=true + metricsServer: + namespace: kube-system + source: + repo: git@github.com:alexlebens/alexlebens-net.git + revision: HEAD + path: standalone/metrics-server + syncPolicy: + automated: + prune: true + selfHeal: true + retry: + limit: 10 + backoff: + duration: 1m + factor: 2 + maxDuration: 16m + syncOptions: + - CreateNamespace=false + - ApplyOutOfSyncOnly=false + - ServerSideApply=true + - PruneLast=true + kubeletServingCertApprover: + namespace: kubelet-serving-cert-approver + source: + repo: git@github.com:alexlebens/alexlebens-net.git + revision: HEAD + path: standalone/kubelet-serving-cert-approver + syncPolicy: + automated: + prune: true + selfHeal: true + retry: + limit: 10 + backoff: + duration: 1m + factor: 2 + maxDuration: 16m + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=false + - ServerSideApply=true + - PruneLast=true + prometheusOperatorCrds: + namespace: kube-system + source: + repo: git@github.com:alexlebens/alexlebens-net.git + revision: HEAD + path: standalone/prometheus-operator-crds + syncPolicy: + automated: + prune: true + selfHeal: true + retry: + limit: 10 + backoff: + duration: 1m + factor: 2 + maxDuration: 16m + syncOptions: + - CreateNamespace=false + - ApplyOutOfSyncOnly=false + - ServerSideApply=true + - PruneLast=true diff --git a/clusters/cl01tl/platform/authentik/Chart.yaml b/clusters/cl01tl/platform/authentik/Chart.yaml new file mode 100644 index 000000000..1170381d0 --- /dev/null +++ b/clusters/cl01tl/platform/authentik/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: authentik +version: 1.0.0 +sources: + - https://github.com/goauthentik/authentik + - https://github.com/goauthentik/helm + - https://github.com/bjw-s/helm-charts/tree/main/charts/other/app-template + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: authentik + version: 2024.4.2 + repository: https://charts.goauthentik.io/ + - name: app-template + alias: cloudflared + repository: https://bjw-s.github.io/helm-charts/ + version: 3.1.0 + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: "2024.4.2" diff --git a/clusters/cl01tl/platform/authentik/templates/config-map.yaml b/clusters/cl01tl/platform/authentik/templates/config-map.yaml new file mode 100644 index 000000000..ac5171752 --- /dev/null +++ b/clusters/cl01tl/platform/authentik/templates/config-map.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: authentik-custom-css + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +data: + custom.css: | + /* Change sign button color */ + .pf-c-button.pf-m-primary { + color: black; + background-color: white; + } + + /* Remove background */ + .pf-c-login__main { + background-color: rgba(3, 3, 3, 0.16); + } + + /* Remove specific height */ + .pf-c-brand { + height: auto; + } + + /* Center text */ + .pf-c-title { + text-align: center; + } + + /* Match text field to login button */ + .pf-c-form-control { + border-radius: 3px; + background-color: white; + color: black; + } + + /* Force border color */ + .pf-c-form-control { + border-color: white; + } + + /* Use default cursor on this div */ + .pf-c-form__label { + cursor: default; + } + + /* Hide required asterik */ + .pf-c-form__label-required { + display: none; + } + + /* Change link color to white */ + .a { + color: white; + } \ No newline at end of file diff --git a/clusters/cl01tl/platform/authentik/templates/external-secret.yaml b/clusters/cl01tl/platform/authentik/templates/external-secret.yaml new file mode 100644 index 000000000..901606029 --- /dev/null +++ b/clusters/cl01tl/platform/authentik/templates/external-secret.yaml @@ -0,0 +1,80 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: authentik-key-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: authentik-key-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/key + metadataPolicy: None + property: key + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: authentik-cloudflared-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: authentik-cloudflared-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: cf-tunnel-token + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/tunnels/authentik + metadataPolicy: None + property: token + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: authentik-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: authentik-postgresql-16-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-authentik-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-authentik-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/platform/authentik/values.yaml b/clusters/cl01tl/platform/authentik/values.yaml new file mode 100644 index 000000000..bab8e22b0 --- /dev/null +++ b/clusters/cl01tl/platform/authentik/values.yaml @@ -0,0 +1,118 @@ +authentik: + global: + env: + - name: AUTHENTIK_SECRET_KEY + valueFrom: + secretKeyRef: + name: authentik-key-secret + key: key + - name: AUTHENTIK_POSTGRESQL__HOST + valueFrom: + secretKeyRef: + name: authentik-postgresql-16-cluster-app + key: host + - name: AUTHENTIK_POSTGRESQL__NAME + valueFrom: + secretKeyRef: + name: authentik-postgresql-16-cluster-app + key: dbname + - name: AUTHENTIK_POSTGRESQL__USER + valueFrom: + secretKeyRef: + name: authentik-postgresql-16-cluster-app + key: user + - name: AUTHENTIK_POSTGRESQL__PASSWORD + valueFrom: + secretKeyRef: + name: authentik-postgresql-16-cluster-app + key: password + server: + name: server + replicas: 1 + volumes: + - name: custom-css + configMap: + name: authentik-custom-css + volumeMounts: + - name: custom-css + mountPath: /web/dist/custom.css + subPath: custom.css + metrics: + enabled: true + serviceMonitor: + enabled: true + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + ingressClassName: traefik + hosts: + - auth.alexlebens.net + - authentik.alexlebens.net + tls: + - secretName: authentik-secret-tls + hosts: + - auth.alexlebens.net + - authentik.alexlebens.net + worker: + name: worker + replicas: 1 + prometheus: + rules: + enabled: true + postgresql: + enabled: false + redis: + enabled: true +cloudflared: + global: + nameOverride: cloudflared + controllers: + main: + type: deployment + strategy: Recreate + containers: + main: + image: + repository: cloudflare/cloudflared + tag: "2024.5.0" + pullPolicy: IfNotPresent + args: + - tunnel + - --no-autoupdate + - run + - --token + - $(CF_MANAGED_TUNNEL_TOKEN) + env: + - name: CF_MANAGED_TUNNEL_TOKEN + valueFrom: + secretKeyRef: + name: authentik-cloudflared-secret + key: cf-tunnel-token + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi +postgres-16-cluster: + mode: standalone + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + prometheusRule: + enabled: false + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/authentik + endpointCredentials: authentik-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/platform/external-secrets/Chart.yaml b/clusters/cl01tl/platform/external-secrets/Chart.yaml new file mode 100644 index 000000000..ca2e35244 --- /dev/null +++ b/clusters/cl01tl/platform/external-secrets/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: external-secrets +version: 0.0.1 +sources: + - https://github.com/external-secrets/external-secrets + - https://github.com/external-secrets/external-secrets/tree/main/deploy/charts/external-secrets +dependencies: + - name: external-secrets + version: 0.9.18 + repository: https://charts.external-secrets.io +appVersion: 0.9.13 diff --git a/clusters/cl01tl/platform/external-secrets/templates/cluster-secret-store.yaml b/clusters/cl01tl/platform/external-secrets/templates/cluster-secret-store.yaml new file mode 100644 index 000000000..42ade8596 --- /dev/null +++ b/clusters/cl01tl/platform/external-secrets/templates/cluster-secret-store.yaml @@ -0,0 +1,21 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ClusterSecretStore +metadata: + name: vault + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + provider: + vault: + server: http://vault-internal.vault:8200 + path: secret + auth: + tokenSecretRef: + namespace: vault + name: vault-token + key: token diff --git a/clusters/cl01tl/platform/gitea/Chart.yaml b/clusters/cl01tl/platform/gitea/Chart.yaml new file mode 100644 index 000000000..875f0744d --- /dev/null +++ b/clusters/cl01tl/platform/gitea/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: gitea +version: 1.0.0 +sources: + - https://github.com/go-gitea/gitea + - https://gitea.com/gitea/helm-chart + - https://github.com/alexlebens/helm-charts/charts/postgres-cluster +dependencies: + - name: gitea + version: 10.1.4 + repository: https://dl.gitea.io/charts/ + - name: postgres-cluster + alias: postgres-16-cluster + version: 3.0.0 + repository: http://alexlebens.github.io/helm-charts +appVersion: "1.21.7" diff --git a/clusters/cl01tl/platform/gitea/templates/external-secret.yaml b/clusters/cl01tl/platform/gitea/templates/external-secret.yaml new file mode 100644 index 000000000..f25147a85 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/external-secret.yaml @@ -0,0 +1,94 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-admin-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: username + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /gitea/auth/admin + metadataPolicy: None + property: username + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /gitea/auth/admin + metadataPolicy: None + property: password + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/gitea + metadataPolicy: None + property: secret + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/gitea + metadataPolicy: None + property: client + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-postgresql-16-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-gitea-postgresql + metadataPolicy: None + property: access_key + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /aws/keys/cl01tl-gitea-postgresql + metadataPolicy: None + property: secret_key diff --git a/clusters/cl01tl/platform/gitea/values.yaml b/clusters/cl01tl/platform/gitea/values.yaml new file mode 100644 index 000000000..768a94632 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/values.yaml @@ -0,0 +1,96 @@ +gitea: + ingress: + enabled: true + className: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: gitea.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: gitea-secret-tls + hosts: + - gitea.alexlebens.net + gitea: + admin: + existingSecret: gitea-admin-secret + metrics: + enabled: true + serviceMonitor: + enabled: true + config: + server: + LANDING_PAGE: explore + ROOT_URL: https://gitea.alexlebens.net + ENABLE_PPROF: true + webhook: + ALLOWED_HOST_LIST: private + scopes: email profile + service: + DISABLE_REGISTRATION: true + SHOW_REGISTRATION_BUTTON: false + explore: + REQUIRE_SIGNIN_VIEW: true + database: + DB_TYPE: postgres + SCHEMA: public + additionalConfigFromEnvs: + - name: GITEA__DATABASE__HOST + valueFrom: + secretKeyRef: + name: gitea-postgresql-16-cluster-app + key: host + - name: GITEA__DATABASE__NAME + valueFrom: + secretKeyRef: + name: gitea-postgresql-16-cluster-app + key: dbname + - name: GITEA__DATABASE__USER + valueFrom: + secretKeyRef: + name: gitea-postgresql-16-cluster-app + key: user + - name: GITEA__DATABASE__PASSWD + valueFrom: + secretKeyRef: + name: gitea-postgresql-16-cluster-app + key: password + oauth: + - name: Authentik + provider: openidConnect + existingSecret: gitea-oidc-secret + autoDiscoverUrl: "https://authentik.alexlebens.net/application/o/gitea/.well-known/openid-configuration" + iconUrl: https://goauthentik.io/img/icon.png + scopes: "email profile" + persistence: + storageClass: ceph-block + postgresql: + enabled: false + postgresql-ha: + enabled: false + redis-cluster: + enabled: true + persistence: + enabled: false +postgres-16-cluster: + mode: standalone + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + prometheusRule: + enabled: false + backup: + enabled: true + endpointURL: https://s3.us-east-2.amazonaws.com + destinationPath: s3://cl01tl-postgresql-backups/gitea + endpointCredentials: gitea-postgresql-16-cluster-backup-secret + backupIndex: 1 + retentionPolicy: 14d diff --git a/clusters/cl01tl/platform/grafana/Chart.yaml b/clusters/cl01tl/platform/grafana/Chart.yaml new file mode 100644 index 000000000..1a859a8a9 --- /dev/null +++ b/clusters/cl01tl/platform/grafana/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: grafana +version: 0.0.1 +sources: + - https://github.com/grafana/grafana + - https://github.com/grafana/helm-charts/tree/main/charts/grafana +dependencies: + - name: grafana + version: 7.3.11 + repository: https://grafana.github.io/helm-charts +appVersion: "10.4.0" diff --git a/clusters/cl01tl/platform/grafana/templates/external-secret.yaml b/clusters/cl01tl/platform/grafana/templates/external-secret.yaml new file mode 100644 index 000000000..f33e76e0d --- /dev/null +++ b/clusters/cl01tl/platform/grafana/templates/external-secret.yaml @@ -0,0 +1,62 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: grafana-auth-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: admin-user + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /grafana/auth + metadataPolicy: None + property: admin-user + - secretKey: admin-password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /grafana/auth + metadataPolicy: None + property: admin-password + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: grafana-oauth-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: GF_AUTH_GENERIC_OAUTH_CLIENT_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/grafana + metadataPolicy: None + property: client + - secretKey: GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/grafana + metadataPolicy: None + property: secret diff --git a/clusters/cl01tl/platform/grafana/values.yaml b/clusters/cl01tl/platform/grafana/values.yaml new file mode 100644 index 000000000..aa7c626f2 --- /dev/null +++ b/clusters/cl01tl/platform/grafana/values.yaml @@ -0,0 +1,142 @@ +grafana: + deploymentStrategy: + type: Recreate + createConfigmap: true + serviceMonitor: + enabled: true + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - grafana.alexlebens.net + tls: + - secretName: grafana-secret-tls + hosts: + - grafana.alexlebens.net + persistence: + enabled: true + storageClassName: ceph-block + admin: + existingSecret: grafana-auth-secret + userKey: admin-user + passwordKey: admin-password + envFromSecret: grafana-oauth-secret + plugins: + - grafana-clock-panel + - vonage-status-panel + - grafana-worldmap-panel + datasources: + datasources.yaml: + apiVersion: 1 + datasources: + - name: Prometheus + type: prometheus + uid: prometheus + url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090/ + access: proxy + isDefault: true + jsonData: + timeInterval: 30s + - name: Loki + type: loki + url: http://loki.loki:3100 + jsonData: + httpHeaderName1: "X-Scope-OrgID" + secureJsonData: + httpHeaderValue1: "1" + dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: "default" + orgId: 1 + folder: "" + type: file + disableDeletion: false + editable: true + options: + path: /var/lib/grafana/dashboards/default + dashboards: + default: + node-exporter: + gnetId: 1860 + revision: 33 + datasource: Prometheus + coredns: + gnetId: 14981 + revision: 2 + datasource: Prometheus + loki: + gnetId: 14055 + revision: 5 + datasource: Prometheus + argocd: + gnetId: 14584 + revision: 1 + datasource: Prometheus + cert-manager: + gnetId: 11001 + revision: 1 + datasource: Prometheus + traefik: + gnetId: 17346 + revision: 7 + datasource: Prometheus + kubernetes-nodes: + gnetId: 8171 + revision: 1 + datasource: Prometheus + vault: + gnetId: 12904 + revision: 2 + datasource: Prometheus + ceph: + gnetId: 2842 + revision: 17 + datasource: Prometheus + alertmanager: + gnetId: 9578 + revision: 4 + datasource: Prometheus + sonarr: + gnetId: 12530 + revision: 2 + datasource: Prometheus + radarr: + gnetId: 12896 + revision: 1 + datasource: Prometheus + unpoller: + gnetId: 11315 + revision: 9 + datasource: Prometheus + etcd: + gnetId: 3070 + revision: 3 + datasource: Prometheus + grafana.ini: + analytics: + check_for_updates: false + server: + domain: alexlebens.net + root_url: https://grafana.alexlebens.net + users: + auto_assign_org: true + auto_assign_org_id: 1 + auth: + disable_login_form: true + oauth_auto_login: true + signout_redirect_url: https://authentik.alexlebens.net/application/o/grafana/end-session/ + auth.generic_oauth: + enabled: true + name: Authentik + allow_sign_up: true + scopes: openid profile email + auth_url: https://authentik.alexlebens.net/application/o/authorize/ + token_url: https://authentik.alexlebens.net/application/o/token/ + api_url: https://authentik.alexlebens.net/application/o/userinfo/ + role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer' diff --git a/clusters/cl01tl/platform/headlamp/Chart.yaml b/clusters/cl01tl/platform/headlamp/Chart.yaml new file mode 100644 index 000000000..d3729d3ea --- /dev/null +++ b/clusters/cl01tl/platform/headlamp/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: headlamp +version: 0.0.1 +sources: + - https://github.com/headlamp-k8s/headlamp + - https://github.com/headlamp-k8s/headlamp/tree/main/charts/headlamp +dependencies: + - name: headlamp + version: 0.21.0 + repository: https://headlamp-k8s.github.io/headlamp/ +appVersion: 0.23.1 diff --git a/clusters/cl01tl/platform/headlamp/templates/cluster-role-binding.yaml b/clusters/cl01tl/platform/headlamp/templates/cluster-role-binding.yaml new file mode 100644 index 000000000..846bedf87 --- /dev/null +++ b/clusters/cl01tl/platform/headlamp/templates/cluster-role-binding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-admin-oidc + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: User + name: alexanderlebens@gmail.com + apiGroup: rbac.authorization.k8s.io diff --git a/clusters/cl01tl/platform/headlamp/templates/external-secret.yaml b/clusters/cl01tl/platform/headlamp/templates/external-secret.yaml new file mode 100644 index 000000000..21e523f65 --- /dev/null +++ b/clusters/cl01tl/platform/headlamp/templates/external-secret.yaml @@ -0,0 +1,30 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: headlamp-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: HEADLAMP_CONFIG_OIDC_CLIENT_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/headlamp + metadataPolicy: None + property: client + - secretKey: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/headlamp + metadataPolicy: None + property: secret diff --git a/clusters/cl01tl/platform/headlamp/values.yaml b/clusters/cl01tl/platform/headlamp/values.yaml new file mode 100644 index 000000000..4ca7212b3 --- /dev/null +++ b/clusters/cl01tl/platform/headlamp/values.yaml @@ -0,0 +1,48 @@ +headlamp: + config: + oidc: + secret: + create: true + name: headlamp-oidc-generated-secret + env: + - name: HEADLAMP_CONFIG_OIDC_CLIENT_ID + valueFrom: + secretKeyRef: + key: HEADLAMP_CONFIG_OIDC_CLIENT_ID + name: headlamp-oidc-secret + - name: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET + valueFrom: + secretKeyRef: + key: HEADLAMP_CONFIG_OIDC_CLIENT_SECRET + name: headlamp-oidc-secret + - name: HEADLAMP_CONFIG_OIDC_IDP_ISSUER_URL + value: https://authentik.alexlebens.net/application/o/headlamp/ + persistentVolumeClaim: + enabled: true + accessModes: + - ReadWriteOnce + size: 10Gi + storageClassName: ceph-block + volumeMode: Filesystem + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: headlamp.alexlebens.net + paths: + - path: / + type: ImplementationSpecific + tls: + - secretName: headlamp-secret-tls + hosts: + - headlamp.alexlebens.net + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 100m + memory: 256Mi diff --git a/clusters/cl01tl/platform/pgadmin/Chart.yaml b/clusters/cl01tl/platform/pgadmin/Chart.yaml new file mode 100644 index 000000000..a006d2073 --- /dev/null +++ b/clusters/cl01tl/platform/pgadmin/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: pgadmin4 +version: 0.0.3 +sources: + - https://github.com/pgadmin-org/pgadmin4 + - https://github.com/rowanruseler/helm-charts +dependencies: + - name: pgadmin4 + version: 1.25.1 + repository: https://helm.runix.net +appVersion: "8.4" diff --git a/clusters/cl01tl/platform/pgadmin/templates/external-secret.yaml b/clusters/cl01tl/platform/pgadmin/templates/external-secret.yaml new file mode 100644 index 000000000..4adb330c4 --- /dev/null +++ b/clusters/cl01tl/platform/pgadmin/templates/external-secret.yaml @@ -0,0 +1,62 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: pgadmin-password-secret + namespace: {{ .Release.Namespace | quote }} + labels: + app.kubernetes.io/name: {{ .Release.Name | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name | quote }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: pgadmin-password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pgadmin/auth + metadataPolicy: None + property: pgadmin-password + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: pgadmin-env-secret + namespace: {{ .Release.Namespace | quote }} + labels: + app.kubernetes.io/name: {{ .Release.Name | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name | quote }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: PGADMIN_CONFIG_AUTHENTICATION_SOURCES + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pgadmin/env + metadataPolicy: None + property: PGADMIN_CONFIG_AUTHENTICATION_SOURCES + - secretKey: PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pgadmin/env + metadataPolicy: None + property: PGADMIN_CONFIG_OAUTH2_AUTO_CREATE_USER + - secretKey: PGADMIN_CONFIG_OAUTH2_CONFIG + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pgadmin/env + metadataPolicy: None + property: PGADMIN_CONFIG_OAUTH2_CONFIG diff --git a/clusters/cl01tl/platform/pgadmin/values.yaml b/clusters/cl01tl/platform/pgadmin/values.yaml new file mode 100644 index 000000000..eb2f3cb1e --- /dev/null +++ b/clusters/cl01tl/platform/pgadmin/values.yaml @@ -0,0 +1,40 @@ +pgadmin4: + image: + repository: dpage/pgadmin4 + tag: "8.6" + serviceAccount: + create: true + automountServiceAccountToken: true + strategy: + type: Recreate + serverDefinitions: + enabled: false + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: pgadmin.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: pgadmin-secret-tls + hosts: + - pgadmin.alexlebens.net + existingSecret: pgadmin-password-secret + secretKeys: + pgadminPasswordKey: pgadmin-password + env: + email: alexanderlebens@gmail.com + envVarsFromSecrets: + - pgadmin-env-secret + persistentVolume: + enabled: true + accessModes: + - ReadWriteOnce + size: 5Gi + storageClass: ceph-block diff --git a/clusters/cl01tl/platform/portainer/Chart.yaml b/clusters/cl01tl/platform/portainer/Chart.yaml new file mode 100644 index 000000000..eb3266b0a --- /dev/null +++ b/clusters/cl01tl/platform/portainer/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: portainer +version: 0.0.1 +sources: + - https://github.com/portainer/portainer + - https://github.com/portainer/k8s +dependencies: + - name: portainer + version: "1.0.51" + repository: https://portainer.github.io/k8s/ +appVersion: "2.19.3" diff --git a/clusters/cl01tl/platform/portainer/values.yaml b/clusters/cl01tl/platform/portainer/values.yaml new file mode 100644 index 000000000..c2d53b959 --- /dev/null +++ b/clusters/cl01tl/platform/portainer/values.yaml @@ -0,0 +1,35 @@ +portainer: + replicaCount: 1 + enterpriseEdition: + enabled: false + image: + repository: portainer/portainer-ce + tag: 2.20.2 + serviceAccount: + name: portainer-sa-clusteradmin + service: + type: ClusterIP + tls: + force: false + mtls: + enable: false + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - host: portainer.alexlebens.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: portainer-secret-tls + hosts: + - portainer.alexlebens.net + persistence: + enabled: true + size: 5Gi + storageClass: ceph-block diff --git a/clusters/cl01tl/platform/vault/Chart.yaml b/clusters/cl01tl/platform/vault/Chart.yaml new file mode 100644 index 000000000..30e809fa7 --- /dev/null +++ b/clusters/cl01tl/platform/vault/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: vault +version: 0.0.1 +sources: + - https://github.com/hashicorp/vault + - https://github.com/hashicorp/vault-helm +dependencies: + - name: vault + version: "0.28.0" + repository: https://helm.releases.hashicorp.com +appVersion: 1.15.5 diff --git a/clusters/cl01tl/platform/vault/templates/cron-job.yaml b/clusters/cl01tl/platform/vault/templates/cron-job.yaml new file mode 100644 index 000000000..04a89e7f6 --- /dev/null +++ b/clusters/cl01tl/platform/vault/templates/cron-job.yaml @@ -0,0 +1,64 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: vault-snapshot-cronjob + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-snapshot-cronjob + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + schedule: "@every 24h" + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: snapshot + image: hashicorp/vault:1.16.2 + imagePullPolicy: IfNotPresent + command: + - /bin/ash + args: + - -ec + - | + apk add --no-cache jq; + export VAULT_TOKEN=$(vault write auth/approle/login role_id=$VAULT_APPROLE_ROLE_ID secret_id=$VAULT_APPROLE_SECRET_ID -format=json | jq -r .auth.client_token); + vault operator raft snapshot save /opt/backup/vault-snapshot-latest.snap; + cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; + cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-s3.snap; + envFrom: + - secretRef: + name: vault-snapshot-agent-token + env: + - name: VAULT_ADDR + value: http://vault-active.vault.svc.cluster.local:8200 + volumeMounts: + - mountPath: /opt/backup + name: backup + - name: upload + image: amazon/aws-cli:2.15.42 + imagePullPolicy: IfNotPresent + command: + - /bin/sh + args: + - -ec + - | + until [ -f /opt/backup/vault-snapshot-s3.snap ]; do sleep 5; done; + aws s3 cp /opt/backup/vault-snapshot-s3.snap s3://cl01tl-vault-snapshots/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; + rm /opt/backup/vault-snapshot-s3.snap; + envFrom: + - secretRef: + name: vault-snapshot-s3 + volumeMounts: + - mountPath: /opt/backup + name: backup + volumes: + - name: backup + persistentVolumeClaim: + claimName: vault-nfs-storage-backup diff --git a/clusters/cl01tl/platform/vault/templates/ingress.yaml b/clusters/cl01tl/platform/vault/templates/ingress.yaml new file mode 100644 index 000000000..a34338b78 --- /dev/null +++ b/clusters/cl01tl/platform/vault/templates/ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tailscale-cl01tl-vault-ui + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: tailscale-cl01tl-vault-ui + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: tailscale + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + ingressClassName: tailscale + tls: + - hosts: + - vault-cl01tl + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: vault-ui + port: + name: http diff --git a/clusters/cl01tl/platform/vault/templates/persistent-volume-claim.yaml b/clusters/cl01tl/platform/vault/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..1d6024213 --- /dev/null +++ b/clusters/cl01tl/platform/vault/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: vault-nfs-storage-backup + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-nfs-storage-backup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeMode: Filesystem + storageClassName: nfs-client + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/platform/vault/values.yaml b/clusters/cl01tl/platform/vault/values.yaml new file mode 100644 index 000000000..28fe401df --- /dev/null +++ b/clusters/cl01tl/platform/vault/values.yaml @@ -0,0 +1,170 @@ +vault: + global: + enabled: true + tlsDisable: true + psp: + enable: false + serverTelemetry: + prometheusOperator: true + injector: + enabled: false + server: + enabled: true + image: + repository: "hashicorp/vault" + tag: "1.16.2" + updateStrategyType: "OnDelete" + logLevel: debug + logFormat: standard + resources: + requests: + memory: 256Mi + cpu: 250m + limits: + memory: 256Mi + cpu: 250m + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + ingressClassName: traefik + pathType: Prefix + activeService: true + hosts: + - host: vault.alexlebens.net + paths: + - / + tls: + - secretName: vault-secret-tls + hosts: + - vault.alexlebens.net + route: + enabled: false + authDelegator: + enabled: false + readinessProbe: + enabled: true + port: 8200 + livenessProbe: + enabled: false + volumes: + - name: vault-nfs-storage-backup + persistentVolumeClaim: + claimName: vault-nfs-storage-backup + volumeMounts: + - mountPath: /opt/backups/ + name: vault-nfs-storage-backup + readOnly: false + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + networkPolicy: + enabled: false + service: + enabled: true + active: + enabled: true + standby: + enabled: false + type: ClusterIP + port: 8200 + targetPort: 8200 + dataStorage: + enabled: true + size: 10Gi + mountPath: "/vault/data" + accessMode: ReadWriteOnce + auditStorage: + enabled: false + size: 10Gi + mountPath: "/vault/audit" + accessMode: ReadWriteOnce + dev: + enabled: false + standalone: + enabled: false + ha: + enabled: true + replicas: 3 + raft: + enabled: true + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + telemetry { + unauthenticated_metrics_access = "true" + } + } + + storage "raft" { + path = "/vault/data" + retry_join { + leader_api_addr = "http://vault-0.vault-internal:8200" + } + retry_join { + leader_api_addr = "http://vault-1.vault-internal:8200" + } + retry_join { + leader_api_addr = "http://vault-2.vault-internal:8200" + } + } + + service_registration "kubernetes" {} + + telemetry { + prometheus_retention_time = "30s" + disable_hostname = true + } + + disruptionBudget: + enabled: true + maxUnavailable: null + serviceAccount: + create: true + serviceDiscovery: + enabled: true + hostNetwork: false + ui: + enabled: true + publishNotReadyAddresses: true + activeVaultPodOnly: false + serviceType: "ClusterIP" + serviceNodePort: null + externalPort: 8200 + targetPort: 8200 + csi: + enabled: false + serverTelemetry: + serviceMonitor: + enabled: true + interval: 30s + scrapeTimeout: 10s + prometheusRules: + enabled: true + rules: + - alert: vault-HighResponseTime + annotations: + message: The response time of Vault is over 500ms on average over the last 5 minutes. + expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 500 + for: 5m + labels: + severity: warning + - alert: vault-HighResponseTime + annotations: + message: The response time of Vault is over 1s on average over the last 5 minutes. + expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 1000 + for: 5m + labels: + severity: critical diff --git a/clusters/cl01tl/services/cert-manager/Chart.yaml b/clusters/cl01tl/services/cert-manager/Chart.yaml new file mode 100644 index 000000000..2db7a471f --- /dev/null +++ b/clusters/cl01tl/services/cert-manager/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cert-manager +version: 1.0.0 +sources: + - https://github.com/cert-manager/cert-manager + - https://github.com/cert-manager/cert-manager/tree/master/deploy/charts/cert-manager +dependencies: + - name: cert-manager + version: v1.14.5 + repository: https://charts.jetstack.io +appVersion: v1.14.3 diff --git a/clusters/cl01tl/services/cert-manager/templates/cluster-issuer.yaml b/clusters/cl01tl/services/cert-manager/templates/cluster-issuer.yaml new file mode 100644 index 000000000..a5d9a90b9 --- /dev/null +++ b/clusters/cl01tl/services/cert-manager/templates/cluster-issuer.yaml @@ -0,0 +1,21 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-issuer +spec: + acme: + email: alexanderlebens@gmail.com + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-issuer-account-key + solvers: + - selector: + dnsZones: + - "alexlebens.net" + - "*.alexlebens.net" + dns01: + cloudflare: + email: alexanderlebens@gmail.com + apiTokenSecretRef: + name: cloudflare-api-token + key: api-token diff --git a/clusters/cl01tl/services/cert-manager/values.yaml b/clusters/cl01tl/services/cert-manager/values.yaml new file mode 100644 index 000000000..78d5b3bf9 --- /dev/null +++ b/clusters/cl01tl/services/cert-manager/values.yaml @@ -0,0 +1,11 @@ +cert-manager: + installCRDs: true + replicaCount: 2 + prometheus: + enabled: true + servicemonitor: + enabled: true + honorLabels: true + cainjector: + enabled: true + replicaCount: 2 diff --git a/clusters/cl01tl/services/intel-device-plugin/Chart.yaml b/clusters/cl01tl/services/intel-device-plugin/Chart.yaml new file mode 100644 index 000000000..e2a091992 --- /dev/null +++ b/clusters/cl01tl/services/intel-device-plugin/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: node-feature-discovery +version: 1.0.0 +sources: + - https://github.com/intel/intel-device-plugins-for-kubernetes +dependencies: + - name: intel-device-plugins-operator + version: 0.30.0 + repository: https://intel.github.io/helm-charts/ + - name: intel-device-plugins-gpu + version: 0.30.0 + repository: https://intel.github.io/helm-charts/ +appVersion: 0.29.0 diff --git a/clusters/cl01tl/services/intel-device-plugin/values.yaml b/clusters/cl01tl/services/intel-device-plugin/values.yaml new file mode 100644 index 000000000..4cbcad143 --- /dev/null +++ b/clusters/cl01tl/services/intel-device-plugin/values.yaml @@ -0,0 +1,28 @@ +intel-device-plugins-operator: + nodeSelector: + kubernetes.io/arch: amd64 + manager: + image: + hub: intel + kubeRbacProxy: + image: + hub: gcr.io + resources: + limits: + cpu: 100m + memory: 120Mi + requests: + cpu: 100m + memory: 100Mi +intel-device-plugins-gpu: + name: gpudeviceplugin + image: + hub: intel + sharedDevNum: 5 + logLevel: 2 + resourceManager: false + enableMonitoring: true + allocationPolicy: "none" + nodeSelector: + intel.feature.node.kubernetes.io/gpu: 'true' + nodeFeatureRule: false diff --git a/clusters/cl01tl/services/kube-prometheus-stack/Chart.yaml b/clusters/cl01tl/services/kube-prometheus-stack/Chart.yaml new file mode 100644 index 000000000..23bdc0734 --- /dev/null +++ b/clusters/cl01tl/services/kube-prometheus-stack/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: kube-prometheus-stack +version: 1.0.0 +sources: + - https://github.com/prometheus/prometheus + - https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack +dependencies: + - name: kube-prometheus-stack + version: 58.5.3 + repository: https://prometheus-community.github.io/helm-charts +appVersion: v0.72.0 diff --git a/clusters/cl01tl/services/kube-prometheus-stack/templates/external-secret.yaml b/clusters/cl01tl/services/kube-prometheus-stack/templates/external-secret.yaml new file mode 100644 index 000000000..84c7c6aa0 --- /dev/null +++ b/clusters/cl01tl/services/kube-prometheus-stack/templates/external-secret.yaml @@ -0,0 +1,37 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: alertmanager-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: discord_webhook + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /discord/alertmanager + metadataPolicy: None + property: webhook + - secretKey: pushover_token + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pushover/key + metadataPolicy: None + property: alertmanager_key + - secretKey: user_key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /pushover/key + metadataPolicy: None + property: user_key diff --git a/clusters/cl01tl/services/kube-prometheus-stack/values.yaml b/clusters/cl01tl/services/kube-prometheus-stack/values.yaml new file mode 100644 index 000000000..ae0f2ffc8 --- /dev/null +++ b/clusters/cl01tl/services/kube-prometheus-stack/values.yaml @@ -0,0 +1,140 @@ +kube-prometheus-stack: + crds: + enabled: false + defaultRules: + create: true + rules: + kubeControllerManager: false + kubeSchedulerAlerting: false + kubeSchedulerRecording: false + global: + rbac: + create: true + createAggregateClusterRoles: true + alertmanager: + enabled: true + config: + route: + group_by: ["namespace","alertname"] + group_wait: 30s + group_interval: 5m + repeat_interval: 24h + receiver: discord + routes: + - receiver: "null" + matchers: + - alertname = "Watchdog" + - receiver: 'pushover' + group_wait: 10s + group_interval: 5m + repeat_interval: 24h + matchers: + - severity = "critical" + receivers: + - name: "null" + - name: discord + discord_configs: + - send_resolved: true + webhook_url: https://discord.com/api/webhooks/1215465356315983922/CSaWG3SygslTNQo0uw07FB-0eKGl9nw2kDAqbAfH7JMe1ExVin8UvjlP4qkJoEyjDawz + - name: pushover + pushover_configs: + - send_resolved: true + user_key_file: /etc/alertmanager/secrets/alertmanager-config-secret/user_key + token_file: /etc/alertmanager/secrets/alertmanager-config-secret/pushover_token + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - alertmanager.alexlebens.net + tls: + - secretName: alertmanager-secret-tls + hosts: + - alertmanager.alexlebens.net + alertmanagerSpec: + secrets: + - alertmanager-config-secret + replicas: 1 + externalUrl: https://alertmanager.alexlebens.net + grafana: + enabled: false + kubeApiServer: + tlsConfig: + insecureSkipVerify: true + kubeControllerManager: + enabled: false + kubeScheduler: + enabled: false + kubeProxy: + enabled: false + kube-state-metrics: + selfMonitor: + enabled: true + nodeExporter: + operatingSystems: + darwin: + enabled: false + prometheusOperator: + admissionWebhooks: + enabled: true + namespaces: + releaseNamespace: true + additional: + - kube-system + - argocd + - authentik + - cert-manager + - cloudnative-pg + - freshrss + - gitea + - grafana + - home-assistant + - local-static-provisioner + - loki + - matrix-synapse + - outline + - rook-ceph + - speedtest-exporter + - unpoller + - vault + - vikunja + - lidarr2 + - qbittorrent + - radarr5 + - radarr5-4k + - readarr-audiobooks + - readarr-books + - sonarr4 + - sonarr4-4k + - tdarr + prometheus: + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + hosts: + - prometheus.alexlebens.net + tls: + - secretName: prometheus-secret-tls + hosts: + - prometheus.alexlebens.net + prometheusSpec: + scrapeInterval: 30s + retention: 30d + externalUrl: https://prometheus.alexlebens.net + serviceMonitorSelectorNilUsesHelmValues: false + podMonitorSelectorNilUsesHelmValues: false + storageSpec: + volumeClaimTemplate: + spec: + storageClassName: nfs-client + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/services/kubernetes-cloudflare-ddns/Chart.yaml b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/Chart.yaml new file mode 100644 index 000000000..92900b253 --- /dev/null +++ b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: kubernetes-cloudflare-ddns +version: 0.0.1 +sources: + - https://github.com/kubitodev/kubernetes-cloudflare-ddns + - https://github.com/kubitodev/helm/tree/main/charts/kubernetes-cloudflare-ddns +dependencies: + - name: kubernetes-cloudflare-ddns + version: 1.0.6 + repository: https://charts.kubito.dev +appVersion: "1.0.1" diff --git a/clusters/cl01tl/services/kubernetes-cloudflare-ddns/templates/external-secret.yaml b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/templates/external-secret.yaml new file mode 100644 index 000000000..7e7731c3e --- /dev/null +++ b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/templates/external-secret.yaml @@ -0,0 +1,44 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: kubernetes-cloudflare-ddns-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: AUTH_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/alexlebens-net + metadataPolicy: None + property: auth-key + - secretKey: NAME + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/alexlebens-net + metadataPolicy: None + property: name + - secretKey: RECORD_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/alexlebens-net + metadataPolicy: None + property: record-id + - secretKey: ZONE_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/alexlebens-net + metadataPolicy: None + property: zone-id diff --git a/clusters/cl01tl/services/kubernetes-cloudflare-ddns/values.yaml b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/values.yaml new file mode 100644 index 000000000..2b94ba7c0 --- /dev/null +++ b/clusters/cl01tl/services/kubernetes-cloudflare-ddns/values.yaml @@ -0,0 +1,12 @@ +kubernetes-cloudflare-ddns: + image: + repository: kubitodev/kubernetes-cloudflare-ddns + tag: "2.0.0" + cron: + job: + schedule: '"0 0 * * *"' + successfulJobsHistoryLimit: 1 + pod: + restartPolicy: OnFailure + secret: + existingSecret: kubernetes-cloudflare-ddns-secret diff --git a/clusters/cl01tl/services/loki/Chart.yaml b/clusters/cl01tl/services/loki/Chart.yaml new file mode 100644 index 000000000..d511aa6e6 --- /dev/null +++ b/clusters/cl01tl/services/loki/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v2 +name: loki +version: 1.0.0 +sources: + - https://github.com/grafana/loki + - https://github.com/grafana/helm-charts +dependencies: + - name: loki + version: 6.5.2 + repository: https://grafana.github.io/helm-charts + - name: promtail + version: 6.15.5 + repository: https://grafana.github.io/helm-charts +appVersion: 3.0.0 diff --git a/clusters/cl01tl/services/loki/values.yaml b/clusters/cl01tl/services/loki/values.yaml new file mode 100644 index 000000000..76d901883 --- /dev/null +++ b/clusters/cl01tl/services/loki/values.yaml @@ -0,0 +1,48 @@ +loki: + deploymentMode: SingleBinary + loki: + auth_enabled: true + commonConfig: + replication_factor: 1 + limits_config: + allow_structured_metadata: false + storage: + type: filesystem + schemaConfig: + configs: + - from: "2024-01-11" + store: boltdb-shipper + object_store: filesystem + schema: v13 + index: + period: 24h + enterprise: + enabled: false + gateway: + enabled: true + basicAuth: + enabled: false + singleBinary: + replicas: 1 + persistence: + enableStatefulSetAutoDeletePVC: true + enabled: true + size: 10Gi + storageClass: ceph-block + write: + replicas: 0 + read: + replicas: 0 + backend: + replicas: 0 +promtail: + daemonset: + enabled: true + serviceMonitor: + enabled: true + prometheusRule: + enabled: false + config: + clients: + - url: http://loki-gateway/loki/api/v1/push + tenant_id: 1 diff --git a/clusters/cl01tl/services/metallb/Chart.yaml b/clusters/cl01tl/services/metallb/Chart.yaml new file mode 100644 index 000000000..a9a44d0e0 --- /dev/null +++ b/clusters/cl01tl/services/metallb/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: metallb +version: 1.0.0 +sources: + - https://github.com/metallb/metallb + - https://github.com/metallb/metallb/tree/main/charts/metallb +dependencies: + - name: metallb + version: 0.14.5 + repository: https://metallb.github.io/metallb +appVersion: 0.15.1 diff --git a/clusters/cl01tl/services/metallb/templates/ip-address-pool.yaml b/clusters/cl01tl/services/metallb/templates/ip-address-pool.yaml new file mode 100644 index 000000000..5614edd41 --- /dev/null +++ b/clusters/cl01tl/services/metallb/templates/ip-address-pool.yaml @@ -0,0 +1,16 @@ +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: default + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: network + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + addresses: + - 192.168.1.17/32 + - 192.168.1.16/32 + - 192.168.1.15/32 diff --git a/clusters/cl01tl/services/metallb/templates/namespace.yaml b/clusters/cl01tl/services/metallb/templates/namespace.yaml new file mode 100644 index 000000000..89c0c8fec --- /dev/null +++ b/clusters/cl01tl/services/metallb/templates/namespace.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: metallb + labels: + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/warn: privileged + pod-security.kubernetes.io/audit: privileged diff --git a/clusters/cl01tl/services/metallb/values.yaml b/clusters/cl01tl/services/metallb/values.yaml new file mode 100644 index 000000000..49c2f2488 --- /dev/null +++ b/clusters/cl01tl/services/metallb/values.yaml @@ -0,0 +1,15 @@ +metallb: + controller: + metrics: + enabled: true + serviceMonitor: + enabled: true + speaker: + metrics: + enabled: true + serviceMonitor: + enabled: true + labels: + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: privileged diff --git a/clusters/cl01tl/services/node-feature-discovery/Chart.yaml b/clusters/cl01tl/services/node-feature-discovery/Chart.yaml new file mode 100644 index 000000000..0667d04e9 --- /dev/null +++ b/clusters/cl01tl/services/node-feature-discovery/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: node-feature-discovery +version: 1.0.0 +sources: + - https://github.com/kubernetes-sigs/node-feature-discovery +dependencies: + - name: node-feature-discovery + version: 0.15.4 + repository: https://kubernetes-sigs.github.io/node-feature-discovery/charts +appVersion: 0.15.1 diff --git a/clusters/cl01tl/services/node-feature-discovery/values.yaml b/clusters/cl01tl/services/node-feature-discovery/values.yaml new file mode 100644 index 000000000..92b23b432 --- /dev/null +++ b/clusters/cl01tl/services/node-feature-discovery/values.yaml @@ -0,0 +1,256 @@ +node-feature-discovery: + enableNodeFeatureApi: true + master: + enable: true + config: ### + # noPublish: false + # autoDefaultNs: true + # extraLabelNs: ["added.ns.io","added.kubernets.io","intel.com","devicetree.org"] + # denyLabelNs: ["denied.ns.io","denied.kubernetes.io"] + # resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"] + # enableTaints: false + # labelWhiteList: "foo" + # resyncPeriod: "2h" + # klog: + # addDirHeader: false + # alsologtostderr: false + # logBacktraceAt: + # logtostderr: true + # skipHeaders: false + # stderrthreshold: 2 + # v: 0 + # vmodule: + ## NOTE: the following options are not dynamically run-time configurable + ## and require a nfd-master restart to take effect after being changed + # logDir: + # logFile: + # logFileMaxSize: 1800 + # skipLogHeaders: false + # leaderElection: + # leaseDuration: 15s + # # this value has to be lower than leaseDuration and greater than retryPeriod*1.2 + # renewDeadline: 10s + # # this value has to be greater than 0 + # retryPeriod: 2s + # nfdApiParallelism: 10 + ### + port: 8080 + metricsPort: 8081 + instance: + featureApi: + resyncPeriod: + denyLabelNs: [] + extraLabelNs: [] + resourceLabels: [] + enableTaints: false + crdController: null + featureRulesController: null + nfdApiParallelism: null + deploymentAnnotations: {} + replicaCount: 1 + podSecurityContext: {} + # fsGroup: 2000 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + readOnlyRootFilesystem: true + runAsNonRoot: true + # runAsUser: 1000 + serviceAccount: + create: true + name: + rbac: + create: true + service: + type: ClusterIP + port: 8080 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + tolerations: + - key: "node-role.kubernetes.io/control-plane" + operator: "Equal" + value: "" + effect: "NoSchedule" + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: "node-role.kubernetes.io/control-plane" + operator: In + values: [""] + worker: + enable: true + config: ### + #core: + # labelWhiteList: + # noPublish: false + # sleepInterval: 60s + # featureSources: [all] + # labelSources: [all] + # klog: + # addDirHeader: false + # alsologtostderr: false + # logBacktraceAt: + # logtostderr: true + # skipHeaders: false + # stderrthreshold: 2 + # v: 0 + # vmodule: + ## NOTE: the following options are not dynamically run-time configurable + ## and require a nfd-worker restart to take effect after being changed + # logDir: + # logFile: + # logFileMaxSize: 1800 + # skipLogHeaders: false + sources: + cpu: + cpuid: + attributeWhitelist: + - "AVX512BW" + - "AVX512CD" + - "AVX512DQ" + - "AVX512F" + - "AVX512VL" + kernel: + configOpts: + - "NO_HZ" + - "X86" + - "DMI" + usb: + deviceClassWhitelist: + - "02" + - "03" + - "0e" + - "ef" + - "fe" + - "ff" + deviceLabelFields: + - "vendor" + - "device" + - "class" + pci: + deviceClassWhitelist: + - "0200" + - "01" + - "08" + - "0300" + - "0302" + deviceLabelFields: + - "vendor" + - "device" + - "class" + custom: + - # Intel integrated GPU + name: "intel-gpu" + labels: + intel.feature.node.kubernetes.io/gpu: 'true' + matchOn: + - pciId: + class: ["0300"] + vendor: ["8086"] + - # Google Coral USB Accelerator + name: google.coral + labels: + google.feature.node.kubernetes.io/coral: "true" + matchFeatures: + - feature: usb.device + matchExpressions: + vendor: { op: In, value: ["1a6e", "18d1"] } + - # Aeotec Z-Stick Gen5+ + name: aeotec.zwave + labels: + aeotec.feature.node.kubernetes.io/zwave: "true" + matchFeatures: + - feature: usb.device + matchExpressions: + class: { op: In, value: ["02"] } + vendor: { op: In, value: ["0658"] } + device: { op: In, value: ["0200"] } + ### + metricsPort: 8081 + podSecurityContext: {} + # fsGroup: 2000 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + readOnlyRootFilesystem: true + runAsNonRoot: true + # runAsUser: 1000 + serviceAccount: + create: true + name: + rbac: + create: true + mountUsrSrc: false + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + topologyUpdater: + config: ### + ## key = node name, value = list of resources to be excluded. + ## use * to exclude from all nodes. + ## an example for how the exclude list should looks like + #excludeList: + # node1: [cpu] + # node2: [memory, example/deviceA] + # *: [hugepages-2Mi] + ### + enable: true + createCRDs: true + serviceAccount: + create: true + name: + rbac: + create: true + metricsPort: 8081 + updateInterval: 60s + watchNamespace: "*" + kubeletStateDir: /var/lib/kubelet + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + readOnlyRootFilesystem: true + runAsUser: 0 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + gc: + enable: true + replicaCount: 1 + serviceAccount: + create: true + name: + rbac: + create: true + interval: 1h + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + metricsPort: 8081 + tls: + enable: false + certManager: false + prometheus: + enable: false diff --git a/clusters/cl01tl/services/reloader/Chart.yaml b/clusters/cl01tl/services/reloader/Chart.yaml new file mode 100644 index 000000000..18cd2ff32 --- /dev/null +++ b/clusters/cl01tl/services/reloader/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: reloader +version: 1.0.0 +sources: + - https://github.com/stakater/Reloader + - https://github.com/stakater/Reloader/blob/master/deployments/kubernetes/chart/reloader/Chart.yaml +dependencies: + - name: reloader + version: 1.0.97 + repository: https://stakater.github.io/stakater-charts +appVersion: 1.0.80 diff --git a/clusters/cl01tl/services/reloader/values.yaml b/clusters/cl01tl/services/reloader/values.yaml new file mode 100644 index 000000000..e4bb46cc5 --- /dev/null +++ b/clusters/cl01tl/services/reloader/values.yaml @@ -0,0 +1,5 @@ +reloader: + reloader: + serviceMonitor: + enabled: true + namespace: reloader diff --git a/clusters/cl01tl/services/speedtest-exporter/Chart.yaml b/clusters/cl01tl/services/speedtest-exporter/Chart.yaml new file mode 100644 index 000000000..9f6e16c37 --- /dev/null +++ b/clusters/cl01tl/services/speedtest-exporter/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: speedtest-exporter +version: 1.0.0 +sources: + - https://github.com/MiguelNdeCarvalho/speedtest-exporter + - https://gitlab.com/alexander-chernov/helm/speedtest-exporter +dependencies: + - name: speedtest-exporter + version: 0.1.1 + repository: https://charts.alekc.dev +appVersion: v3.5.4 diff --git a/clusters/cl01tl/services/speedtest-exporter/values.yaml b/clusters/cl01tl/services/speedtest-exporter/values.yaml new file mode 100644 index 000000000..c81ef25b7 --- /dev/null +++ b/clusters/cl01tl/services/speedtest-exporter/values.yaml @@ -0,0 +1,16 @@ +speedtest-exporter: + image: + repository: ghcr.io/miguelndecarvalho/speedtest-exporter + tag: v3.5.4 + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + serviceMonitor: + enabled: true + namespace: speedtest-exporter + interval: "60m" + scrapeTimeout: "2m" diff --git a/clusters/cl01tl/services/tailscale-operator/Chart.yaml b/clusters/cl01tl/services/tailscale-operator/Chart.yaml new file mode 100644 index 000000000..ae8a9b016 --- /dev/null +++ b/clusters/cl01tl/services/tailscale-operator/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: tailscale-operator +version: 1.0.0 +sources: + - https://github.com/tailscale/tailscale/tree/main/cmd/k8s-operator/deploy + - https://github.com/tailscale/tailscale/tree/main/cmd/k8s-operator/deploy/chart +dependencies: + - name: tailscale-operator + version: 1.66.3 + repository: https://pkgs.tailscale.com/helmcharts +appVersion: v1.64.2 diff --git a/clusters/cl01tl/services/tailscale-operator/templates/external-secrets.yaml b/clusters/cl01tl/services/tailscale-operator/templates/external-secrets.yaml new file mode 100644 index 000000000..4a744aea8 --- /dev/null +++ b/clusters/cl01tl/services/tailscale-operator/templates/external-secrets.yaml @@ -0,0 +1,30 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: operator-oauth + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: operator-oauth + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: client_id + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tailscale/operator/oauth + metadataPolicy: None + property: clientId + - secretKey: client_secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /tailscale/operator/oauth + metadataPolicy: None + property: clientSecret diff --git a/clusters/cl01tl/services/tailscale-operator/values.yaml b/clusters/cl01tl/services/tailscale-operator/values.yaml new file mode 100644 index 000000000..f5b80fda9 --- /dev/null +++ b/clusters/cl01tl/services/tailscale-operator/values.yaml @@ -0,0 +1,22 @@ +tailscale-operator: + oauth: {} + installCRDs: true + operatorConfig: + defaultTags: + - "tag:k8s-operator" + image: + repo: tailscale/k8s-operator + tag: v1.64.2 + pullPolicy: Always + logging: info + hostname: tailscale-operator-cl01tl + nodeSelector: + kubernetes.io/os: linux + proxyConfig: + image: + repo: tailscale/tailscale + tag: v1.64.2 + defaultTags: "tag:k8s" + firewallMode: auto + apiServerProxyConfig: + mode: "false" diff --git a/clusters/cl01tl/services/traefik/Chart.yaml b/clusters/cl01tl/services/traefik/Chart.yaml new file mode 100644 index 000000000..626a90fb6 --- /dev/null +++ b/clusters/cl01tl/services/traefik/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: traefik +version: 1.0.0 +sources: + - https://github.com/traefik/traefik + - https://github.com/traefik/traefik-helm-chart +dependencies: + - name: traefik + version: 28.0.0 + repository: https://traefik.github.io/charts +appVersion: v3.0.0 diff --git a/clusters/cl01tl/services/traefik/templates/certificate.yaml b/clusters/cl01tl/services/traefik/templates/certificate.yaml new file mode 100644 index 000000000..53b030523 --- /dev/null +++ b/clusters/cl01tl/services/traefik/templates/certificate.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: traefik-certificate + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretName: traefik-secret-tls + dnsNames: + - "alexlebens.net" + - "*.alexlebens.net" + issuerRef: + name: letsencrypt-issuer + kind: ClusterIssuer diff --git a/clusters/cl01tl/services/traefik/values.yaml b/clusters/cl01tl/services/traefik/values.yaml new file mode 100644 index 000000000..ee611f78e --- /dev/null +++ b/clusters/cl01tl/services/traefik/values.yaml @@ -0,0 +1,82 @@ +traefik: + deployment: + kind: DaemonSet + ingressClass: + enabled: true + isDefaultClass: true + ingressRoute: + dashboard: + enabled: true + matchRule: (Host(`traefik-cl01tl.alexlebens.net`) && (PathPrefix(`/api/`) || PathPrefix(`/dashboard/`))) + entryPoints: ["websecure"] + providers: + kubernetesCRD: + allowCrossNamespace: true + allowEmptyServices: true + kubernetesIngress: + allowEmptyServices: true + publishedService: + enabled: true + metrics: + service: + enabled: true + globalArguments: [] + ports: + web: + expose: + default: true + exposedPort: 80 + redirectTo: + port: websecure + priority: 10 + forwardedHeaders: + trustedIPs: + - 10.0.0.0/8 + - 172.16.0.0/16 + - 192.168.0.0/16 + - fc00::/7 + insecure: false + proxyProtocol: + trustedIPs: + - 10.0.0.0/8 + - 172.16.0.0/16 + - 192.168.0.0/16 + - fc00::/7 + insecure: false + websecure: + port: 8443 + expose: + default: true + exposedPort: 443 + forwardedHeaders: + trustedIPs: + - 10.0.0.0/8 + - 172.16.0.0/16 + - 192.168.0.0/16 + - fc00::/7 + insecure: false + proxyProtocol: + trustedIPs: + - 10.0.0.0/8 + - 172.16.0.0/16 + - 192.168.0.0/16 + - fc00::/7 + insecure: false + tls: + enabled: true + metrics: + expose: + default: false + tlsStore: + default: + defaultCertificate: + secretName: traefik-secret-tls + service: + enabled: true + type: LoadBalancer + annotations: + metallb.universe.tf/allow-shared-ip: "external" + externalIPs: + - 192.168.1.17 + - 192.168.1.16 + - 192.168.1.15 diff --git a/clusters/cl01tl/services/unpoller/Chart.yaml b/clusters/cl01tl/services/unpoller/Chart.yaml new file mode 100644 index 000000000..4ad62e7d7 --- /dev/null +++ b/clusters/cl01tl/services/unpoller/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: unpoller +version: 1.0.0 +sources: + - https://github.com/unpoller/unpoller + - https://github.com/homeylab/helm-charts/tree/main/charts/unpoller +dependencies: + - name: unpoller + version: 2.1.0 + repository: https://homeylab.github.io/helm-charts/ +appVersion: "v2.10.0" diff --git a/clusters/cl01tl/services/unpoller/templates/external-secret.yaml b/clusters/cl01tl/services/unpoller/templates/external-secret.yaml new file mode 100644 index 000000000..4dd8fe680 --- /dev/null +++ b/clusters/cl01tl/services/unpoller/templates/external-secret.yaml @@ -0,0 +1,30 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: unpoller-unifi-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: UP_UNIFI_CONTROLLER_0_USER + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /unifi/auth + metadataPolicy: None + property: user + - secretKey: UP_UNIFI_CONTROLLER_0_PASS + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /unifi/auth + metadataPolicy: None + property: password diff --git a/clusters/cl01tl/services/unpoller/values.yaml b/clusters/cl01tl/services/unpoller/values.yaml new file mode 100644 index 000000000..e3b0b5863 --- /dev/null +++ b/clusters/cl01tl/services/unpoller/values.yaml @@ -0,0 +1,33 @@ +unpoller: + replicaCount: 1 + image: + name: unpoller/unpoller + tag: "v2.10.0" + updateStrategy: + type: Recreate + service: + type: ClusterIP + port: 9130 + protocol: TCP + name: metrics + metrics: + enabled: true + serviceMonitor: + enabled: true + interval: 30s + scrapeTimeout: 10s + prometheusRule: + enabled: true + existingSecret: unpoller-unifi-secret + settings: + unifi: + config: + url: https://unifi.alexlebens.net/ + save_sites: true + verify_ssl: false + prometheus: + namespace: unpoller + http_listen: "0.0.0.0:9130" + unpoller: + debug: false + quiet: false diff --git a/clusters/cl01tl/standalone/cilium/Chart.yaml b/clusters/cl01tl/standalone/cilium/Chart.yaml new file mode 100644 index 000000000..7400fa541 --- /dev/null +++ b/clusters/cl01tl/standalone/cilium/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cilium +version: 1.0.0 +sources: + - https://github.com/cilium/cilium + - https://github.com/cilium/charts +dependencies: + - name: cilium + version: 1.15.5 + repository: https://helm.cilium.io/ +appVersion: 1.15.0 diff --git a/clusters/cl01tl/standalone/cilium/values.yaml b/clusters/cl01tl/standalone/cilium/values.yaml new file mode 100644 index 000000000..2b8ff7c82 --- /dev/null +++ b/clusters/cl01tl/standalone/cilium/values.yaml @@ -0,0 +1,71 @@ +cilium: + k8sServiceHost: "localhost" + k8sServicePort: "7445" + securityContext: + capabilities: + ciliumAgent: + - CHOWN + - KILL + - NET_ADMIN + - NET_RAW + - IPC_LOCK + - SYS_ADMIN + - SYS_RESOURCE + - DAC_OVERRIDE + - FOWNER + - SETGID + - SETUID + cleanCiliumState: + - NET_ADMIN + - SYS_ADMIN + - SYS_RESOURCE + enableK8sEndpointSlice: true + enableCiliumEndpointSlice: false + hubble: + enabled: true + metrics: + serviceMonitor: + enabled: true + relay: + enabled: true + metrics: + serviceMonitor: + enabled: true + ui: + enabled: true + ingress: + enabled: true + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + className: traefik + hosts: + - hubble.alexlebens.net + tls: + - secretName: hubble-secret-tls + hosts: + - hubble.alexlebens.net + ipam: + mode: "kubernetes" + ipv4: + enabled: true + ipv6: + enabled: false + kubeProxyReplacement: "true" + prometheus: + enabled: true + port: 9962 + serviceMonitor: + enabled: true + operator: + enabled: true + prometheus: + enabled: true + port: 9963 + serviceMonitor: + enabled: true + cgroup: + autoMount: + enabled: false + hostRoot: /sys/fs/cgroup diff --git a/clusters/cl01tl/standalone/kubelet-serving-cert-approver/Chart.yaml b/clusters/cl01tl/standalone/kubelet-serving-cert-approver/Chart.yaml new file mode 100644 index 000000000..dd8b7979d --- /dev/null +++ b/clusters/cl01tl/standalone/kubelet-serving-cert-approver/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: kubelet-serving-cert-approver +version: 0.0.3 +sources: + - https://github.com/alex1989hu/kubelet-serving-cert-approver + - https://github.com/alexlebens/helm-charts/charts/homepage +dependencies: + - name: kubelet-serving-cert-approver + version: 0.0.4 + repository: http://alexlebens.github.io/helm-charts +appVersion: 0.8.1 diff --git a/clusters/cl01tl/standalone/metrics-server/Chart.yaml b/clusters/cl01tl/standalone/metrics-server/Chart.yaml new file mode 100644 index 000000000..1146ae7b6 --- /dev/null +++ b/clusters/cl01tl/standalone/metrics-server/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: metrics-server +version: 1.0.0 +sources: + - https://github.com/kubernetes-sigs/metrics-server + - https://github.com/kubernetes-sigs/metrics-server/tree/master/charts/metrics-server +dependencies: + - name: metrics-server + version: 3.12.1 + repository: https://kubernetes-sigs.github.io/metrics-server/ +appVersion: v0.7.0 diff --git a/clusters/cl01tl/standalone/metrics-server/values.yaml b/clusters/cl01tl/standalone/metrics-server/values.yaml new file mode 100644 index 000000000..f12d39eb1 --- /dev/null +++ b/clusters/cl01tl/standalone/metrics-server/values.yaml @@ -0,0 +1,12 @@ +metrics-server: + replicas: 2 + metrics: + enabled: true + serviceMonitor: + enabled: true + defaultArgs: + - --cert-dir=/tmp + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-insecure-tls diff --git a/clusters/cl01tl/standalone/prometheus-operator-crds/Chart.yaml b/clusters/cl01tl/standalone/prometheus-operator-crds/Chart.yaml new file mode 100644 index 000000000..b9174c7df --- /dev/null +++ b/clusters/cl01tl/standalone/prometheus-operator-crds/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: prometheus-operator-crds +version: 1.0.0 +sources: + - https://github.com/prometheus-operator/prometheus-operator + - https://github.com/prometheus-community/helm-charts/ +dependencies: + - name: prometheus-operator-crds + version: 11.0.0 + repository: https://prometheus-community.github.io/helm-charts +appVersion: v0.72.0 diff --git a/clusters/cl01tl/storage/cloudnative-pg/Chart.yaml b/clusters/cl01tl/storage/cloudnative-pg/Chart.yaml new file mode 100644 index 000000000..92dcefc34 --- /dev/null +++ b/clusters/cl01tl/storage/cloudnative-pg/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cloudnative-pg +version: 0.0.1 +sources: + - https://github.com/cloudnative-pg/cloudnative-pg + - https://github.com/cloudnative-pg/charts +dependencies: + - name: cloudnative-pg + version: 0.21.2 + repository: https://cloudnative-pg.io/charts/ +appVersion: "1.23.1" diff --git a/clusters/cl01tl/storage/cloudnative-pg/values.yaml b/clusters/cl01tl/storage/cloudnative-pg/values.yaml new file mode 100644 index 000000000..41e79b909 --- /dev/null +++ b/clusters/cl01tl/storage/cloudnative-pg/values.yaml @@ -0,0 +1,4 @@ +cloudnative-pg: + replicaCount: 2 + monitoring: + podMonitorEnabled: true diff --git a/clusters/cl01tl/storage/democratic-csi-synology-iscsi/Chart.yaml b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/Chart.yaml new file mode 100644 index 000000000..f4235e3c0 --- /dev/null +++ b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: democratic-csi-synology-iscsi +version: 0.0.1 +sources: + - https://github.com/democratic-csi/democratic-csi + - https://github.com/democratic-csi/charts +dependencies: + - name: democratic-csi + repository: https://democratic-csi.github.io/charts/ + version: 0.14.6 +appVersion: 0.14.5 diff --git a/clusters/cl01tl/storage/democratic-csi-synology-iscsi/templates/external-secret.yaml b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/templates/external-secret.yaml new file mode 100644 index 000000000..35f2f21e9 --- /dev/null +++ b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/templates/external-secret.yaml @@ -0,0 +1,23 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: synology-iscsi-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: driver-config-file.yaml + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /synology/config + metadataPolicy: None + property: driver-config-file.yaml diff --git a/clusters/cl01tl/storage/democratic-csi-synology-iscsi/values.yaml b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/values.yaml new file mode 100644 index 000000000..345d467d4 --- /dev/null +++ b/clusters/cl01tl/storage/democratic-csi-synology-iscsi/values.yaml @@ -0,0 +1,37 @@ +democratic-csi: + driver: + existingConfigSecret: synology-iscsi-config-secret + config: + driver: synology-iscsi + csiDriver: + name: "org.democratic-csi.iscsi-synology" + controller: + enabled: true + rbac: + enabled: true + replicaCount: 2 + storageClasses: + - name: synology-iscsi-delete + defaultClass: false + reclaimPolicy: Delete + volumeBindingMode: Immediate + allowVolumeExpansion: true + parameters: + fsType: ext4 + - name: synology-iscsi-retain + defaultClass: false + reclaimPolicy: Retain + volumeBindingMode: Immediate + allowVolumeExpansion: true + parameters: + fsType: ext4 + node: + hostPID: true + driver: + extraEnv: + - name: ISCSIADM_HOST_STRATEGY + value: nsenter + - name: ISCSIADM_HOST_PATH + value: /usr/local/sbin/iscsiadm + iscsiDirHostPath: /usr/local/etc/iscsi + iscsiDirHostPathType: "" diff --git a/clusters/cl01tl/storage/local-path-provisioner/Chart.yaml b/clusters/cl01tl/storage/local-path-provisioner/Chart.yaml new file mode 100644 index 000000000..7bded02f1 --- /dev/null +++ b/clusters/cl01tl/storage/local-path-provisioner/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: local-path-provisioner +version: 1.0.0 +sources: + - https://github.com/rancher/local-path-provisioner + - https://github.com/rancher/local-path-provisioner/tree/master/deploy/chart/local-path-provisioner +dependencies: + - name: local-path-provisioner + version: 0.0.26 + repository: https://charts.containeroo.ch +appVersion: 0.0.26 diff --git a/clusters/cl01tl/storage/local-path-provisioner/values.yaml b/clusters/cl01tl/storage/local-path-provisioner/values.yaml new file mode 100644 index 000000000..9d436423a --- /dev/null +++ b/clusters/cl01tl/storage/local-path-provisioner/values.yaml @@ -0,0 +1,42 @@ +local-static-provisioner: + image: + repository: rancher/local-path-provisioner + tag: v0.0.26 + storageClass: + create: true + defaultClass: false + defaultVolumeType: hostPath + name: local-path + reclaimPolicy: Delete + volumeBindingMode: WaitForFirstConsumer + nodePathMap: + - node: talos-di4-2sr + paths: + - /var/local-path-provisioner + - node: talos-pqo-s7t + paths: + - /var/local-path-provisioner + - node: talos-89d-c5v + paths: + - /var/local-path-provisioner + affinity: + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - talos-di4-2sr + - talos-pqo-s7t + - talos-89d-c5v + configmap: + name: local-path-config + setup: |- + #!/bin/sh + set -eu + mkdir -m 0777 -p "$VOL_DIR" + teardown: |- + #!/bin/sh + set -eu + rm -rf "$VOL_DIR" diff --git a/clusters/cl01tl/storage/minio-operator/Chart.yaml b/clusters/cl01tl/storage/minio-operator/Chart.yaml new file mode 100644 index 000000000..68c36cbef --- /dev/null +++ b/clusters/cl01tl/storage/minio-operator/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: minio-operator +version: 1.0.0 +sources: + - https://github.com/minio/operator + - https://github.com/minio/operator/blob/master/helm/operator/Chart.yaml +dependencies: + - name: operator + version: 5.0.15 + repository: https://operator.min.io +appVersion: v5.0.14 diff --git a/clusters/cl01tl/storage/minio-operator/values.yaml b/clusters/cl01tl/storage/minio-operator/values.yaml new file mode 100644 index 000000000..14d37b533 --- /dev/null +++ b/clusters/cl01tl/storage/minio-operator/values.yaml @@ -0,0 +1,24 @@ +operator: + operator: + env: + - name: OPERATOR_STS_ENABLED + value: "off" + - name: MINIO_CONSOLE_TLS_ENABLE + value: "off" + console: + enabled: true + ingress: + enabled: true + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + tls: + - secretName: minio-secret-tls + hosts: + - minio.alexlebens.net + host: minio.alexlebens.net + path: / + pathType: Prefix + number: 9090 diff --git a/clusters/cl01tl/storage/nfs/Chart.yaml b/clusters/cl01tl/storage/nfs/Chart.yaml new file mode 100644 index 000000000..35e57c999 --- /dev/null +++ b/clusters/cl01tl/storage/nfs/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: nfs-subdir-external-provisioner +version: 0.0.1 +sources: + - https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner + - https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/charts/nfs-subdir-external-provisioner +dependencies: + - name: nfs-subdir-external-provisioner + version: 4.0.18 + repository: https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ +appVersion: 4.0.18 diff --git a/clusters/cl01tl/storage/nfs/values.yaml b/clusters/cl01tl/storage/nfs/values.yaml new file mode 100644 index 000000000..feaf1d472 --- /dev/null +++ b/clusters/cl01tl/storage/nfs/values.yaml @@ -0,0 +1,8 @@ +nfs-subdir-external-provisioner: + nfs: + server: 192.168.1.194 + path: /volume2/Talos + mountOptions: + - hard + - vers=4 + - minorversion=1 diff --git a/clusters/cl01tl/storage/rook-ceph/Chart.yaml b/clusters/cl01tl/storage/rook-ceph/Chart.yaml new file mode 100644 index 000000000..53986fb4f --- /dev/null +++ b/clusters/cl01tl/storage/rook-ceph/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v2 +name: rook-ceph +version: 0.0.3 +sources: + - https://github.com/rook/rook + - https://github.com/rook/rook/tree/master/deploy/charts +dependencies: + - name: rook-ceph + version: v1.14.3 + repository: https://charts.rook.io/release + - name: rook-ceph-cluster + version: v1.14.3 + repository: https://charts.rook.io/release +appVersion: v1.14.0 diff --git a/clusters/cl01tl/storage/rook-ceph/values.yaml b/clusters/cl01tl/storage/rook-ceph/values.yaml new file mode 100644 index 000000000..c147cbdad --- /dev/null +++ b/clusters/cl01tl/storage/rook-ceph/values.yaml @@ -0,0 +1,192 @@ +rook-ceph: + crds: + enabled: true + csi: + enableRbdDriver: true + enableCephfsDriver: true + enableCSIHostNetwork: true + enableCephfsSnapshotter: true + enableNFSSnapshotter: true + enableRBDSnapshotter: true + enablePluginSelinuxHostMount: false + enableCSIEncryption: false + enableMetadata: true + provisionerReplicas: 3 + clusterName: + logLevel: 0 + serviceMonitor: + enabled: true + interval: 5s + csiAddons: + enabled: false + nfs: + enabled: false + topology: + enabled: false + enableDiscoveryDaemon: true + scaleDownOperator: false + monitoring: + enabled: true + +rook-ceph-cluster: + operatorNamespace: rook-ceph + toolbox: + enabled: true + monitoring: + enabled: true + createPrometheusRules: true + pspEnable: false + cephClusterSpec: + cephVersion: + # https://quay.io/repository/ceph/ceph?tab=tags + image: quay.io/ceph/ceph:v18.2.2-20240311 + allowUnsupported: false + dataDirHostPath: /var/lib/rook + skipUpgradeChecks: false + continueUpgradeAfterChecksEvenIfNotHealthy: false + waitTimeoutForHealthyOSDInMinutes: 10 + mon: + count: 3 + allowMultiplePerNode: false + mgr: + count: 1 + allowMultiplePerNode: false + modules: + - name: pg_autoscaler + enabled: true + - name: rook + enabled: true + dashboard: + enabled: true + ssl: false + network: + connections: + encryption: + enabled: true + compression: + enabled: true + requireMsgr2: true + crashCollector: + disable: false + logCollector: + enabled: true + periodicity: daily + maxLogSize: 500M + cleanupPolicy: + confirmation: "" + placement: + all: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/rook-osd-node + operator: Exists + mon: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/rook-control-node + operator: Exists + - key: node-role.kubernetes.io/control-plane + operator: Exists + tolerations: + - key: node-role.kubernetes.io/rook-control-node + operator: Exists + - key: node-role.kubernetes.io/control-plane + operator: Exists + resources: + mgr: + limits: + cpu: "1000m" + memory: "1Gi" + requests: + cpu: "500m" + memory: "1Gi" + mon: + limits: + cpu: "2000m" + memory: "2Gi" + requests: + cpu: "1000m" + memory: "2Gi" + osd: + limits: + cpu: "2000m" + memory: "4Gi" + requests: + cpu: "1000m" + memory: "4Gi" + prepareosd: + requests: + cpu: "500m" + memory: "50Mi" + removeOSDsIfOutAndSafeToRemove: false + storage: + useAllNodes: true + useAllDevices: true + deviceFilter: sda + config: + osdsPerDevice: "1" + csi: + readAffinity: + enabled: true + ingress: + dashboard: + ingressClassName: traefik + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: letsencrypt-issuer + host: + name: ceph.alexlebens.net + path: / + tls: + - secretName: rook-secret-tls + hosts: + - ceph.alexlebens.net + rules: + - host: ceph.alexlebens.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: rook-ceph-mgr-dashboard + port: + name: http-dashboard + cephBlockPools: + - name: ceph-blockpool + spec: + failureDomain: host + replicated: + size: 3 + enableRBDStats: false + storageClass: + enabled: true + name: ceph-block + isDefault: true + reclaimPolicy: Retain + allowVolumeExpansion: true + volumeBindingMode: "Immediate" + parameters: + imageFormat: "2" + imageFeatures: layering,exclusive-lock,object-map,fast-diff + csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner + csi.storage.k8s.io/provisioner-secret-namespace: "{{ .Release.Namespace }}" + csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner + csi.storage.k8s.io/controller-expand-secret-namespace: "{{ .Release.Namespace }}" + csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node + csi.storage.k8s.io/node-stage-secret-namespace: "{{ .Release.Namespace }}" + csi.storage.k8s.io/fstype: ext4 + cephBlockPoolsVolumeSnapshotClass: + enabled: true + name: ceph-blockpool-snapshot + isDefault: false + deletionPolicy: Retain + cephFileSystems: + cephFileSystemVolumeSnapshotClass: + enabled: false + cephObjectStores: diff --git a/hosts/ps08rp/portainer-agent/docker-compose.yml b/hosts/ps08rp/portainer-agent/docker-compose.yml new file mode 100644 index 000000000..55a721a44 --- /dev/null +++ b/hosts/ps08rp/portainer-agent/docker-compose.yml @@ -0,0 +1,11 @@ +services: + portainer: + container_name: portainer-agent + image: portainer/agent:latest + ports: + - 9001:9001 + privileged: true + restart: always + volumes: + - /var/lib/docker/volumes:/var/lib/docker/volumes + - /var/run/docker.sock:/var/run/docker.sock diff --git a/hosts/ps08rp/tailscale/.env b/hosts/ps08rp/tailscale/.env new file mode 100644 index 000000000..ab9e9b04f --- /dev/null +++ b/hosts/ps08rp/tailscale/.env @@ -0,0 +1,4 @@ +TS_AUTHKEY="" +TS_HOSTNAME=ps08rp +TS_ROUTES=192.168.1.0/24 +TS_STATE_DIR=/var/lib/tailscale \ No newline at end of file diff --git a/hosts/ps08rp/tailscale/docker-compose.yml b/hosts/ps08rp/tailscale/docker-compose.yml new file mode 100644 index 000000000..85fa275e8 --- /dev/null +++ b/hosts/ps08rp/tailscale/docker-compose.yml @@ -0,0 +1,24 @@ +services: + tailscaled: + cap_add: + - NET_ADMIN + - NET_RAW + container_name: tailscaled + env_file: + - .env + hostname: ps08rp + image: tailscale/tailscale:stable + network_mode: host + privileged: true + restart: always + volumes: + - tailscale:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + +volumes: + tailscale: + driver: local + driver_opts: + type: none + o: bind + device: /opt/tailscale diff --git a/hosts/ps08rp/technitium/.env b/hosts/ps08rp/technitium/.env new file mode 100644 index 000000000..43d6c3dcd --- /dev/null +++ b/hosts/ps08rp/technitium/.env @@ -0,0 +1,3 @@ +DNS_SERVER_DOMAIN=alexlebens.net +DNS_SERVER_ADMIN_PASSWORD="" +DNS_SERVER_FORWARDERS=1.1.1.1, 1.0.0.1 \ No newline at end of file diff --git a/hosts/ps08rp/technitium/docker-compose.yaml b/hosts/ps08rp/technitium/docker-compose.yaml new file mode 100644 index 000000000..8d51f1294 --- /dev/null +++ b/hosts/ps08rp/technitium/docker-compose.yaml @@ -0,0 +1,37 @@ +services: + technitium: + container_name: technitium + env_file: + - .env + image: technitium/dns-server:latest + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.technitium.entrypoints: websecure + traefik.http.routers.technitium.rule: Host(`technitium-ps08rp.alexlebens.net`) + traefik.http.routers.technitium.service: technitium + traefik.http.services.technitium.loadbalancer.server.port: 5380 + networks: + traefik: null + ports: + - 53:53/udp + - 53:53/tcp + - 67:67/udp + restart: always + sysctls: + - net.ipv4.ip_local_port_range=1024 65000 + volumes: + - config:/etc/dns + +networks: + traefik: + name: traefik + external: true + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /opt/technitium/config \ No newline at end of file diff --git a/hosts/ps08rp/traefik/.env b/hosts/ps08rp/traefik/.env new file mode 100644 index 000000000..b0de019a7 --- /dev/null +++ b/hosts/ps08rp/traefik/.env @@ -0,0 +1,3 @@ +CF_API_EMAIL=alexanderlebens@gmail.com +CF_API_KEY="" +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ No newline at end of file diff --git a/hosts/ps08rp/traefik/docker-compose.yaml b/hosts/ps08rp/traefik/docker-compose.yaml new file mode 100644 index 000000000..4d4ec7874 --- /dev/null +++ b/hosts/ps08rp/traefik/docker-compose.yaml @@ -0,0 +1,45 @@ +services: + traefik: + command: traefik + container_name: traefik + env_file: + - .env + image: docker.io/traefik:v3.0 + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.dashboard.entrypoints: websecure + traefik.http.routers.dashboard.rule: (Host(`traefik-ps08rp.alexlebens.net`) && (PathPrefix(`/api/`) || PathPrefix(`/dashboard/`))) + traefik.http.routers.dashboard.service: api@internal + traefik.http.routers.dashboard.tls: true + traefik.http.routers.dashboard.tls.certresolver: cloudflare + networks: + traefik: null + ports: + - 80:80 + - 443:443 + privileged: true + restart: always + volumes: + - config:/etc/traefik + - log:/log + - /var/run/docker.sock:/var/run/docker.sock:ro + +networks: + traefik: + name: traefik + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /opt/traefik/config + + log: + driver: local + driver_opts: + type: none + o: bind + device: /opt/traefik/log \ No newline at end of file diff --git a/hosts/ps08rp/traefik/traefik_config/conf/iplocal.yml b/hosts/ps08rp/traefik/traefik_config/conf/iplocal.yml new file mode 100644 index 000000000..a70c101bd --- /dev/null +++ b/hosts/ps08rp/traefik/traefik_config/conf/iplocal.yml @@ -0,0 +1,15 @@ +http: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" + +tcp: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" diff --git a/hosts/ps08rp/traefik/traefik_config/conf/metrics.yml b/hosts/ps08rp/traefik/traefik_config/conf/metrics.yml new file mode 100644 index 000000000..cd777dcc4 --- /dev/null +++ b/hosts/ps08rp/traefik/traefik_config/conf/metrics.yml @@ -0,0 +1,8 @@ +http: + routers: + prometheus: + rule: "(Host(`traefik-ps08rp.alexlebens.net`) && Path(`/metrics`))" + entryPoints: websecure + service: prometheus@internal + middlewares: + - "ip-local@file" diff --git a/hosts/ps08rp/traefik/traefik_config/traefik.yml b/hosts/ps08rp/traefik/traefik_config/traefik.yml new file mode 100644 index 000000000..83918c923 --- /dev/null +++ b/hosts/ps08rp/traefik/traefik_config/traefik.yml @@ -0,0 +1,113 @@ +################################################################ +# Global +################################################################ + +global: + checkNewVersion: true + sendAnonymousUsage: false + +################################################################ +# EntryPoints +################################################################ + +entryPoints: + web: + address: :80 + http: + redirections: + entryPoint: + to: websecure + scheme: https + + websecure: + address: :443 + forwardedHeaders: + trustedIPs: + - "192.168.1.1/16" + proxyProtocol: + trustedIPs: + - "192.168.1.1/16" + http: + tls: + options: default + certResolver: cloudflare + domains: + - main: "*.alexlebens.net" + sans: + - "alexlebens.net" + middlewares: + - ip-local@file + +################################################################ +# Certificate Resolvers +################################################################ + +certificatesResolvers: + cloudflare: + acme: + email: alexanderlebens@gmail.com + storage: /etc/traefik/acme/acme.json + preferredChain: "ISRG Root X1" + dnsChallenge: + provider: cloudflare + delayBeforeCheck: "3" + resolvers: + - "1.1.1.1" + - "1.0.0.1" + +################################################################ +# Traefik logs +################################################################ + +log: + level: INFO + +################################################################ +# Access logs +################################################################ + +accessLog: {} + +################################################################ +# API and Dashboard +################################################################ + +api: + insecure: false + dashboard: true + +################################################################ +# Ping +################################################################ + +# ping: + +################################################################ +# Metrics +################################################################ + +metrics: + prometheus: + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + buckets: + - 0.1 + - 0.3 + - 1.2 + - 5.0 + entryPoint: websecure + manualRouting: true + +################################################################ +# Providers +################################################################ + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + + file: + directory: "/etc/traefik/conf" + watch: true diff --git a/hosts/ps08rp/watchtower/.env b/hosts/ps08rp/watchtower/.env new file mode 100644 index 000000000..111805fbb --- /dev/null +++ b/hosts/ps08rp/watchtower/.env @@ -0,0 +1,5 @@ +TZ=US/Central +WATCHTOWER_HTTP_API_METRICS=true +WATCHTOWER_HTTP_API_TOKEN=token +WATCHTOWER_CLEANUP=true +WATCHTOWER_POLL_INTERVAL=3600 \ No newline at end of file diff --git a/hosts/ps08rp/watchtower/docker-compose.yml b/hosts/ps08rp/watchtower/docker-compose.yml new file mode 100644 index 000000000..74733707b --- /dev/null +++ b/hosts/ps08rp/watchtower/docker-compose.yml @@ -0,0 +1,10 @@ +services: + watchtower: + container_name: watchtower + env_file: + - .env + image: containrrr/watchtower:latest + privileged: true + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock diff --git a/hosts/ps09rp/portainer-agent/docker-compose.yml b/hosts/ps09rp/portainer-agent/docker-compose.yml new file mode 100644 index 000000000..55a721a44 --- /dev/null +++ b/hosts/ps09rp/portainer-agent/docker-compose.yml @@ -0,0 +1,11 @@ +services: + portainer: + container_name: portainer-agent + image: portainer/agent:latest + ports: + - 9001:9001 + privileged: true + restart: always + volumes: + - /var/lib/docker/volumes:/var/lib/docker/volumes + - /var/run/docker.sock:/var/run/docker.sock diff --git a/hosts/ps09rp/tailscale/.env b/hosts/ps09rp/tailscale/.env new file mode 100644 index 000000000..6627d1d8e --- /dev/null +++ b/hosts/ps09rp/tailscale/.env @@ -0,0 +1,11 @@ +TS_AUTHKEY="" +TS_HOSTNAME=ps09rp +TS_ROUTES=192.168.1.0/24 +TS_STATE_DIR=/var/lib/tailscale + + + + + + + diff --git a/hosts/ps09rp/tailscale/docker-compose.yml b/hosts/ps09rp/tailscale/docker-compose.yml new file mode 100644 index 000000000..5cc9a2849 --- /dev/null +++ b/hosts/ps09rp/tailscale/docker-compose.yml @@ -0,0 +1,24 @@ +services: + tailscaled: + cap_add: + - NET_ADMIN + - NET_RAW + container_name: tailscaled + env_file: + - .env + hostname: ps09rp + image: tailscale/tailscale:stable + network_mode: host + privileged: true + restart: always + volumes: + - tailscale:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + +volumes: + tailscale: + driver: local + driver_opts: + type: none + o: bind + device: /opt/tailscale diff --git a/hosts/ps09rp/technitium/.env b/hosts/ps09rp/technitium/.env new file mode 100644 index 000000000..43d6c3dcd --- /dev/null +++ b/hosts/ps09rp/technitium/.env @@ -0,0 +1,3 @@ +DNS_SERVER_DOMAIN=alexlebens.net +DNS_SERVER_ADMIN_PASSWORD="" +DNS_SERVER_FORWARDERS=1.1.1.1, 1.0.0.1 \ No newline at end of file diff --git a/hosts/ps09rp/technitium/docker-compose.yaml b/hosts/ps09rp/technitium/docker-compose.yaml new file mode 100644 index 000000000..a730d2fc0 --- /dev/null +++ b/hosts/ps09rp/technitium/docker-compose.yaml @@ -0,0 +1,37 @@ +services: + technitium: + container_name: technitium + env_file: + - .env + image: technitium/dns-server:latest + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.technitium.entrypoints: websecure + traefik.http.routers.technitium.rule: Host(`technitium-ps09rp.alexlebens.net`) + traefik.http.routers.technitium.service: technitium + traefik.http.services.technitium.loadbalancer.server.port: 5380 + networks: + traefik: null + ports: + - 53:53/udp + - 53:53/tcp + - 67:67/udp + restart: always + sysctls: + - net.ipv4.ip_local_port_range=1024 65000 + volumes: + - config:/etc/dns + +networks: + traefik: + name: traefik + external: true + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /opt/technitium/config \ No newline at end of file diff --git a/hosts/ps09rp/traefik/.env b/hosts/ps09rp/traefik/.env new file mode 100644 index 000000000..b0de019a7 --- /dev/null +++ b/hosts/ps09rp/traefik/.env @@ -0,0 +1,3 @@ +CF_API_EMAIL=alexanderlebens@gmail.com +CF_API_KEY="" +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ No newline at end of file diff --git a/hosts/ps09rp/traefik/docker-compose.yaml b/hosts/ps09rp/traefik/docker-compose.yaml new file mode 100644 index 000000000..fbe1ac40e --- /dev/null +++ b/hosts/ps09rp/traefik/docker-compose.yaml @@ -0,0 +1,45 @@ +services: + traefik: + command: traefik + container_name: traefik + env_file: + - .env + image: docker.io/traefik:v3.0 + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.dashboard.entrypoints: websecure + traefik.http.routers.dashboard.rule: (Host(`traefik-ps09rp.alexlebens.net`) && (PathPrefix(`/api/`) || PathPrefix(`/dashboard/`))) + traefik.http.routers.dashboard.service: api@internal + traefik.http.routers.dashboard.tls: true + traefik.http.routers.dashboard.tls.certresolver: cloudflare + networks: + traefik: null + ports: + - 80:80 + - 443:443 + privileged: true + restart: always + volumes: + - config:/etc/traefik + - log:/log + - /var/run/docker.sock:/var/run/docker.sock:ro + +networks: + traefik: + name: traefik + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /opt/traefik/config + + log: + driver: local + driver_opts: + type: none + o: bind + device: /opt/traefik/log \ No newline at end of file diff --git a/hosts/ps09rp/traefik/traefik_config/conf/iplocal.yml b/hosts/ps09rp/traefik/traefik_config/conf/iplocal.yml new file mode 100644 index 000000000..a70c101bd --- /dev/null +++ b/hosts/ps09rp/traefik/traefik_config/conf/iplocal.yml @@ -0,0 +1,15 @@ +http: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" + +tcp: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" diff --git a/hosts/ps09rp/traefik/traefik_config/conf/metrics.yml b/hosts/ps09rp/traefik/traefik_config/conf/metrics.yml new file mode 100644 index 000000000..a117c8b72 --- /dev/null +++ b/hosts/ps09rp/traefik/traefik_config/conf/metrics.yml @@ -0,0 +1,8 @@ +http: + routers: + prometheus: + rule: "(Host(`traefik-ps09rp.alexlebens.net`) && Path(`/metrics`))" + entryPoints: websecure + service: prometheus@internal + middlewares: + - "ip-local@file" diff --git a/hosts/ps09rp/traefik/traefik_config/traefik.yml b/hosts/ps09rp/traefik/traefik_config/traefik.yml new file mode 100644 index 000000000..83918c923 --- /dev/null +++ b/hosts/ps09rp/traefik/traefik_config/traefik.yml @@ -0,0 +1,113 @@ +################################################################ +# Global +################################################################ + +global: + checkNewVersion: true + sendAnonymousUsage: false + +################################################################ +# EntryPoints +################################################################ + +entryPoints: + web: + address: :80 + http: + redirections: + entryPoint: + to: websecure + scheme: https + + websecure: + address: :443 + forwardedHeaders: + trustedIPs: + - "192.168.1.1/16" + proxyProtocol: + trustedIPs: + - "192.168.1.1/16" + http: + tls: + options: default + certResolver: cloudflare + domains: + - main: "*.alexlebens.net" + sans: + - "alexlebens.net" + middlewares: + - ip-local@file + +################################################################ +# Certificate Resolvers +################################################################ + +certificatesResolvers: + cloudflare: + acme: + email: alexanderlebens@gmail.com + storage: /etc/traefik/acme/acme.json + preferredChain: "ISRG Root X1" + dnsChallenge: + provider: cloudflare + delayBeforeCheck: "3" + resolvers: + - "1.1.1.1" + - "1.0.0.1" + +################################################################ +# Traefik logs +################################################################ + +log: + level: INFO + +################################################################ +# Access logs +################################################################ + +accessLog: {} + +################################################################ +# API and Dashboard +################################################################ + +api: + insecure: false + dashboard: true + +################################################################ +# Ping +################################################################ + +# ping: + +################################################################ +# Metrics +################################################################ + +metrics: + prometheus: + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + buckets: + - 0.1 + - 0.3 + - 1.2 + - 5.0 + entryPoint: websecure + manualRouting: true + +################################################################ +# Providers +################################################################ + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + + file: + directory: "/etc/traefik/conf" + watch: true diff --git a/hosts/ps09rp/watchtower/.env b/hosts/ps09rp/watchtower/.env new file mode 100644 index 000000000..111805fbb --- /dev/null +++ b/hosts/ps09rp/watchtower/.env @@ -0,0 +1,5 @@ +TZ=US/Central +WATCHTOWER_HTTP_API_METRICS=true +WATCHTOWER_HTTP_API_TOKEN=token +WATCHTOWER_CLEANUP=true +WATCHTOWER_POLL_INTERVAL=3600 \ No newline at end of file diff --git a/hosts/ps09rp/watchtower/docker-compose.yml b/hosts/ps09rp/watchtower/docker-compose.yml new file mode 100644 index 000000000..74733707b --- /dev/null +++ b/hosts/ps09rp/watchtower/docker-compose.yml @@ -0,0 +1,10 @@ +services: + watchtower: + container_name: watchtower + env_file: + - .env + image: containrrr/watchtower:latest + privileged: true + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock diff --git a/hosts/ps10rp/cloudflare-ddns/.env b/hosts/ps10rp/cloudflare-ddns/.env new file mode 100644 index 000000000..de9cdb6a8 --- /dev/null +++ b/hosts/ps10rp/cloudflare-ddns/.env @@ -0,0 +1,3 @@ +API_KEY="" +ZONE=lebens-home.net +PROXIED=false \ No newline at end of file diff --git a/hosts/ps10rp/cloudflare-ddns/docker-compose.yml b/hosts/ps10rp/cloudflare-ddns/docker-compose.yml new file mode 100644 index 000000000..9ae969a33 --- /dev/null +++ b/hosts/ps10rp/cloudflare-ddns/docker-compose.yml @@ -0,0 +1,6 @@ +services: + cloudflare_ddns: + container_name: cloudflare_ddns + env_file: + - .env + image: docker.io/oznu/cloudflare-ddns:latest diff --git a/hosts/ps10rp/gitea/.env b/hosts/ps10rp/gitea/.env new file mode 100644 index 000000000..11139ecbc --- /dev/null +++ b/hosts/ps10rp/gitea/.env @@ -0,0 +1,8 @@ +USER_UID=1000 +USER_GID=1000 +GITEA__database__DB_TYPE=postgres +GITEA__database__HOST=gitea-postgres:5432 +GITEA__database__NAME=gitea +GITEA__database__USER=gitea +GITEA__database__PASSWD="" +GITEA__webhook__ALLOWED_HOST_LIST="*.lebens-home.net, 192.168.*.*, 172.27.*.*" \ No newline at end of file diff --git a/hosts/ps10rp/gitea/.postgresql.env b/hosts/ps10rp/gitea/.postgresql.env new file mode 100644 index 000000000..c6c4688a4 --- /dev/null +++ b/hosts/ps10rp/gitea/.postgresql.env @@ -0,0 +1,3 @@ +POSTGRES_USER=gitea +POSTGRES_PASSWORD="" +POSTGRES_DB=gitea \ No newline at end of file diff --git a/hosts/ps10rp/gitea/docker-compose.yml b/hosts/ps10rp/gitea/docker-compose.yml new file mode 100644 index 000000000..16142f49c --- /dev/null +++ b/hosts/ps10rp/gitea/docker-compose.yml @@ -0,0 +1,51 @@ +services: + gitea: + container_name: gitea + depends_on: + - postgres + env_file: + - .env + image: docker.io/gitea/gitea:latest + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.gitea.entrypoints: websecure + traefik.http.routers.gitea.rule: Host(`gitea.lebens-home.net`) + traefik.http.routers.gitea.service: gitea + traefik.http.services.gitea.loadbalancer.server.port: 3000 + networks: + traefik: null + volumes: + - gitea_data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + + postgresql: + container_name: gitea-postgresql + env_file: + - .postgresql.env + image: docker.io/postgres:16 + networks: + traefik: null + volumes: + - postgressql:/var/lib/postgresql/data + +networks: + traefik: + name: traefik + external: true + +volumes: + postgressql: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/gitea/postgresql + + gitea_data: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/gitea/data diff --git a/hosts/ps10rp/homepage/Files/homepage_config/bookmarks.yaml b/hosts/ps10rp/homepage/Files/homepage_config/bookmarks.yaml new file mode 100644 index 000000000..73b314ff7 --- /dev/null +++ b/hosts/ps10rp/homepage/Files/homepage_config/bookmarks.yaml @@ -0,0 +1 @@ +--- \ No newline at end of file diff --git a/hosts/ps10rp/homepage/Files/homepage_config/docker.yaml b/hosts/ps10rp/homepage/Files/homepage_config/docker.yaml new file mode 100644 index 000000000..2f94a6913 --- /dev/null +++ b/hosts/ps10rp/homepage/Files/homepage_config/docker.yaml @@ -0,0 +1,4 @@ +--- +ps10rp-docker: + host: homepage-dockerproxy + port: 2375 diff --git a/hosts/ps10rp/homepage/Files/homepage_config/services.yaml b/hosts/ps10rp/homepage/Files/homepage_config/services.yaml new file mode 100644 index 000000000..520c0ce1b --- /dev/null +++ b/hosts/ps10rp/homepage/Files/homepage_config/services.yaml @@ -0,0 +1,33 @@ +--- +- Applications: + - Gitea: + icon: gitea.png + description: Code repository + href: https://gitea.lebens-home.net + siteMonitor: http://gitea:3000 + statusStyle: dot + server: ps10rp-docker + container: gitea + - Pi-hole: + icon: pi-hole.png + description: DNS based ad blocker + href: https://pihole.lebens-home.net/admin + siteMonitor: http://pihole:8080/admin + statusStyle: dot + server: ps10rp-docker + container: pihole + widget: + type: pihole + url: http://pihole:8080 + key: "" + - Traefik: + icon: traefik.png + description: Reverse proxy + href: https://traefik-ps10rp.lebens-home.net/dashboard/# + siteMonitor: https://traefik-ps10rp.lebens-home.net/dashboard/#/ + statusStyle: dot + server: ps10rp-docker + container: traefik + widget: + type: traefik + url: https://traefik-ps10rp.lebens-home.net \ No newline at end of file diff --git a/hosts/ps10rp/homepage/Files/homepage_config/settings.yaml b/hosts/ps10rp/homepage/Files/homepage_config/settings.yaml new file mode 100644 index 000000000..e95923439 --- /dev/null +++ b/hosts/ps10rp/homepage/Files/homepage_config/settings.yaml @@ -0,0 +1,9 @@ +--- +favicon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png +headerStyle: clean +hideVersion: true +color: slate +background: + image: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/background.jpg +theme: dark +disableCollapse: true diff --git a/hosts/ps10rp/homepage/Files/homepage_config/widgets.yaml b/hosts/ps10rp/homepage/Files/homepage_config/widgets.yaml new file mode 100644 index 000000000..489a1d593 --- /dev/null +++ b/hosts/ps10rp/homepage/Files/homepage_config/widgets.yaml @@ -0,0 +1,15 @@ +--- +- logo: + icon: https://alexlebens-dev.nyc3.digitaloceanspaces.com/cl02do/assets/icon_white.png +- datetime: + text_size: xl + format: + dateStyle: long + timeStyle: short + hour12: true +- openmeteo: + label: Stacy + latitude: 45.398 + longitude: -92.9874 + units: imperial + cache: 5 diff --git a/hosts/ps10rp/homepage/docker-compose.yml b/hosts/ps10rp/homepage/docker-compose.yml new file mode 100644 index 000000000..8a114ec3e --- /dev/null +++ b/hosts/ps10rp/homepage/docker-compose.yml @@ -0,0 +1,56 @@ +services: + homepage: + container_name: homepage + image: ghcr.io/benphelps/homepage:latest + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.homepage.entrypoints: websecure + traefik.http.routers.homepage.rule: Host(`www.lebens-home.net`) + traefik.http.routers.homepage.service: homepage + traefik.http.services.homepage.loadbalancer.server.port: 3000 + networks: + traefik: null + volumes: + - config:/app/config + - images:/app/public/images + - icons:/app/public/icons + + dockerproxy: + container_name: homepage-dockerproxy + environment: + - CONTAINERS=1 + - POST=0 + image: ghcr.io/tecnativa/docker-socket-proxy:latest + networks: + traefik: null + privileged: true + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + +networks: + traefik: + name: traefik + external: true + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/homepage/config + + images: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/homepage/images + + icons: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/homepage/icons \ No newline at end of file diff --git a/hosts/ps10rp/pihole/.env b/hosts/ps10rp/pihole/.env new file mode 100644 index 000000000..cd3972910 --- /dev/null +++ b/hosts/ps10rp/pihole/.env @@ -0,0 +1,5 @@ +TZ=US/Central +WEBPASSWORD="" +RATE_LIMIT=0/0 +FTLCONF_MAXDBDAYS=14 +WEB_PORT=8080 \ No newline at end of file diff --git a/hosts/ps10rp/pihole/.exporter.env b/hosts/ps10rp/pihole/.exporter.env new file mode 100644 index 000000000..fc226e722 --- /dev/null +++ b/hosts/ps10rp/pihole/.exporter.env @@ -0,0 +1,6 @@ +PIHOLE_HOSTNAME=pihole +PIHOLE_API_TOKEN="" +PIHOLE_PROTOCOL=http +PIHOLE_PORT=8080 +INTERVAL=90s +PORT=9617 \ No newline at end of file diff --git a/hosts/ps10rp/pihole/docker-compose.yml b/hosts/ps10rp/pihole/docker-compose.yml new file mode 100644 index 000000000..00156b080 --- /dev/null +++ b/hosts/ps10rp/pihole/docker-compose.yml @@ -0,0 +1,61 @@ +services: + pihole: + container_name: pihole + env_file: + - .env + image: docker.io/pihole/pihole:latest + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.pihole.entrypoints: websecure + traefik.http.routers.pihole.rule: Host(`pihole.lebens-home.net`) + traefik.http.routers.pihole.service: pihole + traefik.http.services.pihole.loadbalancer.server.port: 8080 + networks: + traefik: null + ports: + - 53:53/tcp + - 53:53/udp + - 8080:8080 + privileged: true + volumes: + - config:/etc/pihole + - dnsmasq:/etc/dnsmasq.d + - logs:/var/log + + pihole_exporter: + container_name: pihole-exporter + depends_on: + - pihole + env_file: + - .exporter.env + image: docker.io/ekofr/pihole-exporter:latest + networks: + traefik: null + +networks: + traefik: + name: traefik + external: true + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/pihole/config + + dnsmasq: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/pihole/dnsmasq + + logs: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/pihole/logs diff --git a/hosts/ps10rp/portainer-agent/docker-compose.yml b/hosts/ps10rp/portainer-agent/docker-compose.yml new file mode 100644 index 000000000..098e357ee --- /dev/null +++ b/hosts/ps10rp/portainer-agent/docker-compose.yml @@ -0,0 +1,10 @@ +services: + portainer: + container_name: portainer-agent + image: docker.io/portainer/agent:latest + ports: + - 9001:9001 + privileged: true + volumes: + - /var/lib/docker/volumes:/var/lib/docker/volumes + - /var/run/docker.sock:/var/run/docker.sock diff --git a/hosts/ps10rp/tailscale/.env b/hosts/ps10rp/tailscale/.env new file mode 100644 index 000000000..1fa42f8b7 --- /dev/null +++ b/hosts/ps10rp/tailscale/.env @@ -0,0 +1,4 @@ +TS_AUTHKEY="" +TS_HOSTNAME=ps10rp +TS_ROUTES=192.168.5.0/24 +TS_STATE_DIR=/var/lib/tailscale \ No newline at end of file diff --git a/hosts/ps10rp/tailscale/docker-compose.yml b/hosts/ps10rp/tailscale/docker-compose.yml new file mode 100644 index 000000000..0d4869e19 --- /dev/null +++ b/hosts/ps10rp/tailscale/docker-compose.yml @@ -0,0 +1,23 @@ +services: + tailscaled: + cap_add: + - NET_ADMIN + - NET_RAW + container_name: tailscaled + env_file: + - .env + hostname: ps10rp + image: docker.io/tailscale/tailscale:stable + network_mode: host + privileged: true + volumes: + - tailscale:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + +volumes: + tailscale: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/tailscale diff --git a/hosts/ps10rp/traefik/.env b/hosts/ps10rp/traefik/.env new file mode 100644 index 000000000..b0de019a7 --- /dev/null +++ b/hosts/ps10rp/traefik/.env @@ -0,0 +1,3 @@ +CF_API_EMAIL=alexanderlebens@gmail.com +CF_API_KEY="" +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ No newline at end of file diff --git a/hosts/ps10rp/traefik/docker-compose.yaml b/hosts/ps10rp/traefik/docker-compose.yaml new file mode 100644 index 000000000..e82661f1f --- /dev/null +++ b/hosts/ps10rp/traefik/docker-compose.yaml @@ -0,0 +1,44 @@ +services: + traefik: + command: traefik + container_name: traefik + env_file: + - .env + image: docker.io/traefik:v3.0 + labels: + traefik.docker.network: traefik + traefik.enable: true + traefik.http.routers.dashboard.entrypoints: websecure + traefik.http.routers.dashboard.rule: (Host(`traefik-ps10rp.lebens-home.net`) && (PathPrefix(`/api/`) || PathPrefix(`/dashboard/`))) + traefik.http.routers.dashboard.service: api@internal + traefik.http.routers.dashboard.tls: true + traefik.http.routers.dashboard.tls.certresolver: cloudflare + networks: + traefik: null + ports: + - 80:80 + - 443:443 + privileged: true + volumes: + - config:/etc/traefik + - log:/log + - /var/run/docker.sock:/var/run/docker.sock:ro + +networks: + traefik: + name: traefik + +volumes: + config: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/traefik/config + + log: + driver: local + driver_opts: + type: none + o: bind + device: /mnt/data/containers/traefik/log diff --git a/hosts/ps10rp/traefik/traefik_config/conf/iplocal.yml b/hosts/ps10rp/traefik/traefik_config/conf/iplocal.yml new file mode 100644 index 000000000..a70c101bd --- /dev/null +++ b/hosts/ps10rp/traefik/traefik_config/conf/iplocal.yml @@ -0,0 +1,15 @@ +http: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" + +tcp: + middlewares: + ip-local: + IPAllowList: + sourceRange: + - "192.168.1.1/16" + - "172.27.0.0/16" diff --git a/hosts/ps10rp/traefik/traefik_config/conf/metrics.yml b/hosts/ps10rp/traefik/traefik_config/conf/metrics.yml new file mode 100644 index 000000000..3b02e5a23 --- /dev/null +++ b/hosts/ps10rp/traefik/traefik_config/conf/metrics.yml @@ -0,0 +1,8 @@ +http: + routers: + prometheus: + rule: "(Host(`traefik-ps10rp.alexlebens.net`) && Path(`/metrics`))" + entryPoints: websecure + service: prometheus@internal + middlewares: + - "ip-local@file" diff --git a/hosts/ps10rp/traefik/traefik_config/traefik.yml b/hosts/ps10rp/traefik/traefik_config/traefik.yml new file mode 100644 index 000000000..86af6d60b --- /dev/null +++ b/hosts/ps10rp/traefik/traefik_config/traefik.yml @@ -0,0 +1,113 @@ +################################################################ +# Global +################################################################ + +global: + checkNewVersion: true + sendAnonymousUsage: false + +################################################################ +# EntryPoints +################################################################ + +entryPoints: + web: + address: :80 + http: + redirections: + entryPoint: + to: websecure + scheme: https + + websecure: + address: :443 + forwardedHeaders: + trustedIPs: + - "192.168.1.1/16" + proxyProtocol: + trustedIPs: + - "192.168.1.1/16" + http: + tls: + options: default + certResolver: cloudflare + domains: + - main: "*.lebens-home.net" + sans: + - "lebens-home.net" + middlewares: + - ip-local@file + +################################################################ +# Certificate Resolvers +################################################################ + +certificatesResolvers: + cloudflare: + acme: + email: alexanderlebens@gmail.com + storage: /etc/traefik/acme/acme.json + preferredChain: "ISRG Root X1" + dnsChallenge: + provider: cloudflare + delayBeforeCheck: "3" + resolvers: + - "1.1.1.1" + - "1.0.0.1" + +################################################################ +# Traefik logs +################################################################ + +log: + level: INFO + +################################################################ +# Access logs +################################################################ + +accessLog: {} + +################################################################ +# API and Dashboard +################################################################ + +api: + insecure: false + dashboard: true + +################################################################ +# Ping +################################################################ + +# ping: + +################################################################ +# Metrics +################################################################ + +metrics: + prometheus: + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + buckets: + - 0.1 + - 0.3 + - 1.2 + - 5.0 + entryPoint: websecure + manualRouting: true + +################################################################ +# Providers +################################################################ + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + + file: + directory: "/etc/traefik/conf" + watch: true diff --git a/hosts/ps10rp/watchtower/.env b/hosts/ps10rp/watchtower/.env new file mode 100644 index 000000000..111805fbb --- /dev/null +++ b/hosts/ps10rp/watchtower/.env @@ -0,0 +1,5 @@ +TZ=US/Central +WATCHTOWER_HTTP_API_METRICS=true +WATCHTOWER_HTTP_API_TOKEN=token +WATCHTOWER_CLEANUP=true +WATCHTOWER_POLL_INTERVAL=3600 \ No newline at end of file diff --git a/hosts/ps10rp/watchtower/docker-compose.yml b/hosts/ps10rp/watchtower/docker-compose.yml new file mode 100644 index 000000000..772d3a4ca --- /dev/null +++ b/hosts/ps10rp/watchtower/docker-compose.yml @@ -0,0 +1,9 @@ +services: + watchtower: + container_name: watchtower + env_file: + - .env + image: docker.io/containrrr/watchtower:latest + privileged: true + volumes: + - /var/run/docker.sock:/var/run/docker.sock