Reset git history for making manifests public

This commit is contained in:
2026-06-01 11:06:25 +02:00
commit 3465f139d1
381 changed files with 41241 additions and 0 deletions

131
README.md Normal file
View File

@@ -0,0 +1,131 @@
# Kubernetes Manifests Repository
This repository contains Kubernetes manifest files for a comprehensive self-hosted platform running 40+ applications across various categories. This infrastructure was created for the migration from Docker to Kubernetes (K3S).
All applications are managed using GitOps principles with ArgoCD and utilize cert-manager for automated TLS certificate management.
## Repository Structure
The repository is organized with one directory per application, containing all necessary Kubernetes resources:
```
├── argocd/ # GitOps continuous deployment
├── cert-manager/ # TLS certificate management
├── metallb/ # Load balancer
├── kubevip/ # High availability
├── longhorn/ # Distributed storage
├── cloud-native-postgres/ # PostgreSQL operator
├── envoy-gateway/ # Kubernetes Gateway API configuration
├── infisical/ # Secrets management
├── authentik/ # Identity provider and SSO
├── it-tools/ # IT utilities
├── jellyfin/ # Media server
├── immich/ # Photo and video management
├── minecraft/ # Game servers
├── gitea/ # Git service
├── jenkins/ # CI/CD automation
├── n8n/ # Workflow automation
├── react-resume/ # Resume builder application
├── passbolt/ # Password manager
├── wikijs/ # Documentation wiki
├── zipline/ # File sharing
├── gotify/ # Push notification server
├── ntfy/ # Push notifications
├── bentopdf/ # PDF conversion
├── excalidraw/ # Whiteboard / diagramming
├── searxng/ # Privacy-respecting search engine
├── uptime-kuma/ # Uptime monitoring
├── openwebui/ # Web UI for AI models
├── ollama/ # Local LLM runner
├── comfyui/ # Stable Diffusion workflow UI
├── minio-aistor/ # S3-compatible object storage
├── databasus/ # Database management
├── netbootxyz/ # Network boot service
├── technitium/ # DNS server
├── azure-ddns-python/ # Dynamic DNS updater
├── victoria-metrics/ # Metrics and monitoring
├── proxmox/ # Virtualization platform
├── unifi/ # Network controller
├── truenas/ # Storage system
└── deprecated/ # Deprecated applications
```
## Categories
### Core Infrastructure
- **ArgoCD**: GitOps continuous deployment and application management
- **cert-manager**: Automated TLS certificate provisioning using Azure DNS
- **MetalLB**: Bare-metal load balancer (IP pool: 10.8.11.100-10.8.11.150)
- **KubeVIP**: High-availability control plane
- **Longhorn**: Distributed block storage
- **Cloud Native Postgres**: PostgreSQL operator for database management
- **Envoy Gateway**: Kubernetes Gateway API implementation
- **Infisical**: Secrets management platform
- **Authentik**: Identity provider and SSO
### Media & Entertainment
- **Jellyfin**: Media streaming server
- **Immich**: Self-hosted photo and video management
- **Minecraft**: Game servers (ATM-10 and Stacia 2 Expert modpacks)
### AI & Machine Learning
- **Ollama**: Local LLM runner
- **Open WebUI**: Web interface for AI models
- **ComfyUI**: Stable Diffusion workflow UI
### Development & CI/CD
- **Gitea**: Self-hosted Git service with container registry
- **Jenkins**: Automation server for CI/CD pipelines
- **n8n**: Workflow automation platform
- **MinIO AIStor**: S3-compatible object storage
### Productivity & Collaboration
- **React-Resume**: Resume builder with MinIO and PostgreSQL
- **Passbolt**: Team password manager
- **Wiki.js**: Modern documentation platform
- **Zipline**: File sharing and screenshot service
- **Gotify**: Push notification server with REST API and WebSocket support
- **Ntfy**: Push notification service
- **BentoPDF**: PDF conversion service
- **Excalidraw**: Online whiteboard and diagramming tool
- **SearXNG**: Privacy-respecting metasearch engine
- **Databasus**: Database management UI
- **Uptime Kuma**: Uptime and status monitoring
### Administration & Monitoring
- **IT-Tools**: Collection of useful IT utilities
- **Technitium**: DNS server with web interface
- **Azure DDNS Python**: Dynamic DNS updater for Azure DNS
- **NetbootXYZ**: Network boot service for OS installation
- **VictoriaMetrics**: Metrics collection and monitoring stack
### External Service Integration
- **Proxmox**: Virtualization platform integration
- **UniFi**: Network controller integration
- **TrueNAS**: Storage system integration
### Deprecated
- **Nginx Ingress Controller**: Replaced by Envoy Gateway; dropped after upstream support ended in March 2025
- **Psono**: Self-hosted password manager; replaced by Passbolt
- **Vaultwarden**: Self-hosted Bitwarden server; no longer in use
## Infrastructure
- **Kubernetes Cluster**: K3S v1.33+
- **Ingress**: Envoy Gateway (Kubernetes Gateway API)
- **Load Balancer**: MetalLB (IP pool: 10.8.11.100-10.8.11.150)
- **Storage**: Longhorn distributed storage, separate PVCs per data type
- **TLS**: cert-manager with Azure DNS validation, domain *.jsme.be
- **Secrets**: Infisical secrets management
- **SSO**: Authentik for centralized authentication
- **RBAC**: Role-based access control for ArgoCD and service accounts
## Deployment
ArgoCD monitors this repository and automatically syncs changes to the cluster. Rollbacks are possible through Git history.
## Maintenance
- **GitOps**: All changes made through Git commits
- **Certificate Renewal**: Automated via cert-manager
- **Updates**: Managed through image tag updates in manifests

View File

@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: authentik
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: authentik
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: authentik
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: bentopdf
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: bentopdf
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: bentopdf
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- PruneLast=true
- CreateNamespace=true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: databasus
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: databasus
targetRevision: HEAD
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: databasus
syncPolicy:
automated:
prune: true
selfHeal: true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ddns
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: azure-ddns-python
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: azure-ddns
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: excalidraw
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: excalidraw
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: excalidraw
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true

View File

@@ -0,0 +1,29 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitea
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: gitea
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: gitea
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- Replace=true
- CreateNamespace=true
- PruneLast=true
ignoreDifferences:
- group: ""
kind: PersistentVolumeClaim
jsonPointers:
- /spec/volumeName

View File

@@ -0,0 +1,28 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gotify
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: gotify
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: gotify
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
ignoreDifferences:
- group: ""
kind: PersistentVolumeClaim
jsonPointers:
- /spec/volumeName

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: immich
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: immich
targetRevision: HEAD
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: immich
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
- PrunePropagationPolicy=foreground

View File

@@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infisical
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: infisical
targetRevision: HEAD
directory:
recurse: true
exclude: universal-auth-secret.yaml
destination:
server: https://kubernetes.default.svc
namespace: infisical
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
- ServerSideApply=true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: intel-gpu
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
project: default
source:
repoURL: https://github.com/intel/intel-device-plugins-for-kubernetes.git
path: deployments/gpu_plugin/overlays/nfd_labeled_nodes
targetRevision: v0.35.0
destination:
server: https://kubernetes.default.svc
namespace: kube-system
syncPolicy:
automated:
prune: true
selfHeal: true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: intel-nfd-rules
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
project: default
source:
repoURL: https://github.com/intel/intel-device-plugins-for-kubernetes.git
path: deployments/nfd/overlays/node-feature-rules
targetRevision: v0.35.0
destination:
server: https://kubernetes.default.svc
namespace: node-feature-discovery
syncPolicy:
automated:
prune: true
selfHeal: true

View File

@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: intel-nfd
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
project: default
source:
repoURL: https://github.com/intel/intel-device-plugins-for-kubernetes.git
path: deployments/nfd
targetRevision: v0.35.0
destination:
server: https://kubernetes.default.svc
namespace: node-feature-discovery
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: it-tools
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: it-tools
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: it-tools
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- Replace=true
- CreateNamespace=true
- PruneLast=true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: jellyfin
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: jellyfin
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: jellyfin
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: minio-aistor
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
targetRevision: HEAD
path: minio-aistor
destination:
server: https://kubernetes.default.svc
namespace: minio-aistor
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: netbootxyz
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: netbootxyz
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: netbootxyz
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: passbolt
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: passbolt
targetRevision: HEAD
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: passbolt
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: proxmox
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: proxmox
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: proxmox
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: reactive-resume
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: react-resume
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: resume
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -0,0 +1,28 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: searxng
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: searxng
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: searxng
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
ignoreDifferences:
- group: ""
kind: PersistentVolumeClaim
jsonPointers:
- /spec/volumeName

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: technitium
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: technitium
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: technitium
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- Replace=true
- CreateNamespace=true
- PruneLast=true

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: truenas
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: truenas
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: truenas
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- Replace=true
- CreateNamespace=true
- PruneLast=true

View File

@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: unifi
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: unifi
targetRevision: HEAD
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: unifi
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- ServerSideApply=true
- CreateNamespace=true

View File

@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: uptime-kuma
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: uptime-kuma
targetRevision: main
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: uptime-kuma
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true

View File

@@ -0,0 +1,34 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: victoria-metrics
namespace: argocd
spec:
project: default
sources:
- repoURL: https://victoriametrics.github.io/helm-charts/
chart: victoria-metrics-k8s-stack
targetRevision: 0.77.0
helm:
# Release name kept short to avoid label length >63 chars on alertmanager StatefulSet pods
releaseName: vm
valueFiles:
- $values/victoria-metrics/values.yaml
- repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
targetRevision: HEAD
ref: values
- repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
targetRevision: HEAD
path: victoria-metrics
directory:
exclude: "values.yaml"
destination:
server: https://kubernetes.default.svc
namespace: victoria-metrics
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: zipline
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.jsme.be/Jeffrey/Kubernetes-Manifests.git
path: zipline
targetRevision: HEAD
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: zipline
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

28219
argocd/argocd-install.yaml Normal file

File diff suppressed because it is too large Load Diff

46
argocd/httproute.yaml Normal file
View File

@@ -0,0 +1,46 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: argocd-route
namespace: argocd
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: argocd
hostnames:
- "argocd.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "argocd.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: argocd-server
port: 80
kind: Service
group: ""
weight: 1

51
authentik/httproute.yaml Normal file
View File

@@ -0,0 +1,51 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: authentik-route
namespace: authentik
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: authentik
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-public
namespace: envoy-gateway
sectionName: authentik
hostnames:
- "auth.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "auth.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: authentik-server
port: 80
kind: Service
group: ""
weight: 1

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: authentik-postgres-data
namespace: authentik
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: authentik-postgresql
namespace: authentik
spec:
selector:
app: authentik-postgresql
ports:
- port: 5432
targetPort: 5432

View File

@@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: authentik-postgresql
namespace: authentik
spec:
serviceName: authentik-postgresql
replicas: 1
selector:
matchLabels:
app: authentik-postgresql
template:
metadata:
labels:
app: authentik-postgresql
spec:
containers:
- name: authentik-postgresql
image: postgres:16-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_name
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_user
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
volumes:
- name: data
persistentVolumeClaim:
claimName: authentik-postgres-data

View File

@@ -0,0 +1,106 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: authentik-server
namespace: authentik
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: authentik-server
template:
metadata:
labels:
app: authentik-server
spec:
containers:
- name: authentik
image: ghcr.io/goauthentik/server:2026.2.1
command: ["ak"]
args: ["server"]
ports:
- containerPort: 9000
name: http
- containerPort: 9443
name: https
env:
- name: AUTHENTIK_POSTGRESQL__HOST
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_host
- name: AUTHENTIK_POSTGRESQL__NAME
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_name
- name: AUTHENTIK_POSTGRESQL__USER
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_user
- name: AUTHENTIK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_password
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-secrets
key: AUTHENTIK_SECRET_KEY
- name: AUTHENTIK_EMAIL__HOST
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_host
- name: AUTHENTIK_EMAIL__PORT
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_port
- name: AUTHENTIK_EMAIL__USERNAME
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_username
- name: AUTHENTIK_EMAIL__PASSWORD
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_password
- name: AUTHENTIK_EMAIL__FROM
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_from
- name: AUTHENTIK_EMAIL__USE_TLS
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_use_tls
volumeMounts:
- name: data
mountPath: /data
- name: templates
mountPath: /templates
- name: dshm
mountPath: /dev/shm
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 1Gi
volumes:
- name: data
persistentVolumeClaim:
claimName: authentik-server-data
- name: templates
emptyDir: {}
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 512Mi

12
authentik/server/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: authentik-server-data
namespace: authentik
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: authentik-server
namespace: authentik
spec:
selector:
app: authentik-server
ports:
- name: http
port: 80
targetPort: 9000
- name: https
port: 443
targetPort: 9443

View File

@@ -0,0 +1,107 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: authentik-worker
namespace: authentik
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: authentik-worker
template:
metadata:
labels:
app: authentik-worker
spec:
securityContext:
runAsUser: 0
containers:
- name: authentik
image: ghcr.io/goauthentik/server:2026.2.1
command: ["ak"]
args: ["worker"]
env:
- name: AUTHENTIK_POSTGRESQL__HOST
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_host
- name: AUTHENTIK_POSTGRESQL__NAME
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_name
- name: AUTHENTIK_POSTGRESQL__USER
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_user
- name: AUTHENTIK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: authentik-secrets
key: db_password
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-secrets
key: AUTHENTIK_SECRET_KEY
- name: AUTHENTIK_EMAIL__HOST
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_host
- name: AUTHENTIK_EMAIL__PORT
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_port
- name: AUTHENTIK_EMAIL__USERNAME
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_username
- name: AUTHENTIK_EMAIL__PASSWORD
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_password
- name: AUTHENTIK_EMAIL__FROM
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_from
- name: AUTHENTIK_EMAIL__USE_TLS
valueFrom:
secretKeyRef:
name: authentik-secrets
key: email_use_tls
volumeMounts:
- name: data
mountPath: /data
- name: certs
mountPath: /certs
- name: templates
mountPath: /templates
- name: dshm
mountPath: /dev/shm
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 1Gi
volumes:
- name: data
persistentVolumeClaim:
claimName: authentik-worker-data
- name: templates
emptyDir: {}
- name: certs
emptyDir: {}
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 512Mi

12
authentik/worker/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: authentik-worker-data
namespace: authentik
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: azure-ddns
namespace: azure-ddns
spec:
selector:
app: azure-ddns
ports:
- name: azure-ddns
port: 443
targetPort: 443
protocol: TCP
type: ClusterIP

View File

@@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: azure-ddns
namespace: azure-ddns
spec:
replicas: 1
selector:
matchLabels:
app: azure-ddns
serviceName: azure-ddns
template:
metadata:
labels:
app: azure-ddns
spec:
terminationGracePeriodSeconds: 60
containers:
- name: azure-ddns
image: gitea.jsme.be/jeffrey/azure-ddns-python:1.0.2
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
env:
- name: AZURE_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-ddns-secrets
key: TENANT_ID
- name: AZURE_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-ddns-secrets
key: CLIENT_ID
- name: AZURE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-ddns-secrets
key: CLIENT_SECRET
- name: AZURE_SUBSCRIPTION_ID
valueFrom:
secretKeyRef:
name: azure-ddns-secrets
key: SUBSCRIPTION_ID
- name: AZURE_RESOURCE_GROUP
valueFrom:
secretKeyRef:
name: azure-ddns-secrets
key: RESOURCE_GROUP
restartPolicy: Always

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: bentopdf
namespace: bentopdf
spec:
selector:
app: bentopdf
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP

29
bentopdf/bentopdf.yaml Normal file
View File

@@ -0,0 +1,29 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: bentopdf
name: bentopdf
spec:
replicas: 1
selector:
matchLabels:
app: bentopdf
template:
metadata:
labels:
app: bentopdf
spec:
restartPolicy: Always
terminationGracePeriodSeconds: 10
containers:
- name: bentopdf
image: ghcr.io/alam00000/bentopdf:v2.8.2-amd64
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
ports:
- containerPort: 8080

51
bentopdf/httproute.yaml Normal file
View File

@@ -0,0 +1,51 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: bentopdf-route
namespace: bentopdf
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: bentopdf
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-public
namespace: envoy-gateway
sectionName: bentopdf
hostnames:
- "pdf.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "pdf.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: bentopdf
port: 8080
kind: Service
group: ""
weight: 1

View File

@@ -0,0 +1,33 @@
apiVersion: v1
kind: Secret
metadata:
name: azuredns-config
namespace: cert-manager
type: Opaque
data:
client-secret:
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: azure-dns
namespace: cert-manager
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: jeffreysmeets@jsme.be
privateKeySecretRef:
name: azuredns
solvers:
- dns01:
azureDNS:
clientID: 1144257c-6893-4f34-be9b-fa2ac3f3780e
clientSecretSecretRef:
name: azuredns-config
key: client-secret
subscriptionID: 5b701352-f929-464d-9b1c-7b8ed6d23b53
tenantID: cf2466c7-c9b9-4820-b416-3bb4c380e52d
resourceGroupName: jsme.be
hostedZoneName: jsme.be
# Azure Cloud Environment, default to AzurePublicCloud
environment: AzurePublicCloud

View File

@@ -0,0 +1,692 @@
#
# Copyright © contributors to CloudNativePG, established as
# CloudNativePG a Series of LF Projects, LLC.
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0
#
# Default values for CloudNativePG.
# This is a YAML-formatted file.
# Please declare variables to be passed to your templates.
replicaCount: 1
image:
repository: ghcr.io/cloudnative-pg/cloudnative-pg
pullPolicy: IfNotPresent
# -- Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
namespaceOverride: ""
hostNetwork: false
dnsPolicy: ""
# -- Update strategy for the operator.
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
# For example:
# type: RollingUpdate
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
updateStrategy: {}
crds:
# -- Specifies whether the CRDs should be created when installing the chart.
create: true
# -- The webhook configuration.
webhook:
port: 9443
mutating:
create: true
failurePolicy: Fail
validating:
create: true
failurePolicy: Fail
livenessProbe:
initialDelaySeconds: 3
readinessProbe:
initialDelaySeconds: 3
startupProbe:
failureThreshold: 6
periodSeconds: 5
# Operator configuration.
config:
# -- Specifies whether the secret should be created.
create: true
# -- The name of the configmap/secret to use.
name: cnpg-controller-manager-config
# -- Specifies whether it should be stored in a secret, instead of a configmap.
secret: false
# -- This option determines if the operator is responsible for observing
# events across the entire Kubernetes cluster or if its focus should be
# narrowed down to the specific namespace within which it has been deployed.
clusterWide: true
# -- The content of the configmap/secret, see
# https://cloudnative-pg.io/documentation/current/operator_conf/#available-options
# for all the available options.
data: {}
# INHERITED_ANNOTATIONS: categories
# INHERITED_LABELS: environment, workload, app
# WATCH_NAMESPACE: namespace-a,namespace-b
# -- The maximum number of concurrent reconciles. Defaults to 10.
maxConcurrentReconciles: 10
# -- Additional arguments to be added to the operator's args list.
additionalArgs: []
# -- Array containing extra environment variables which can be templated.
# For example:
# - name: RELEASE_NAME
# value: "{{ .Release.Name }}"
# - name: MY_VAR
# value: "mySpecialKey"
additionalEnv: []
serviceAccount:
# -- Specifies whether the service account should be created.
create: true
# -- The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template.
name: ""
rbac:
# -- Specifies whether ClusterRole and ClusterRoleBinding should be created.
create: true
# -- Aggregate ClusterRoles to Kubernetes default user-facing roles.
# Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
aggregateClusterRoles: false
# -- Annotations to be added to all other resources.
commonAnnotations: {}
# -- Annotations to be added to the pod.
podAnnotations: {}
# -- Labels to be added to the pod.
podLabels: {}
# -- Container Security Context.
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 10001
runAsGroup: 10001
seccompProfile:
type: RuntimeDefault
capabilities:
drop:
- "ALL"
# -- Security Context for the whole pod.
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
# fsGroup: 2000
# -- Priority indicates the importance of a Pod relative to other Pods.
priorityClassName: ""
service:
type: ClusterIP
# -- DO NOT CHANGE THE SERVICE NAME as it is currently used to generate the certificate
# and can not be configured
name: cnpg-webhook-service
port: 443
# -- Set the ip family policy to configure dual-stack see [Configure dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services)
ipFamilyPolicy: ""
# -- Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. Can be IPv4 and/or IPv6.
ipFamilies: []
resources:
limits:
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
# -- Nodeselector for the operator to be installed.
nodeSelector: {}
# -- Topology Spread Constraints for the operator to be installed.
topologySpreadConstraints: []
# -- Tolerations for the operator to be installed.
tolerations: []
# -- Affinity for the operator to be installed.
affinity: {}
monitoring:
# -- Specifies whether the monitoring should be enabled. Requires Prometheus Operator CRDs.
# Disabled because Victoria Metrics doesn't have PodMonitor CRD - use VMPodScrape instead
podMonitorEnabled: false
# -- Metrics relabel configurations to apply to samples before ingestion.
podMonitorMetricRelabelings: []
# -- Relabel configurations to apply to samples before scraping.
podMonitorRelabelings: []
# -- Additional labels for the podMonitor
podMonitorAdditionalLabels: {}
grafanaDashboard:
create: true
# -- Allows overriding the namespace where the ConfigMap will be created, defaulting to the same one as the Release.
namespace: "monitoring"
# -- The name of the ConfigMap containing the dashboard.
configMapName: "cnpg-grafana-dashboard"
# -- Label that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead.
sidecarLabel: ""
# -- Label value that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead.
sidecarLabelValue: ""
# -- Labels that ConfigMaps should have to get configured in Grafana.
labels:
grafana_dashboard: "1"
# -- Annotations that ConfigMaps can have to get configured in Grafana.
annotations: {}
# Default monitoring queries
monitoringQueriesConfigMap:
# -- The name of the default monitoring configmap.
name: cnpg-default-monitoring
# -- A string representation of a YAML defining monitoring queries.
queries: |
backends:
query: |
SELECT sa.datname
, sa.usename
, sa.application_name
, states.state
, COALESCE(sa.count, 0) AS total
, COALESCE(sa.max_tx_secs, 0) AS max_tx_duration_seconds
FROM ( VALUES ('active')
, ('idle')
, ('idle in transaction')
, ('idle in transaction (aborted)')
, ('fastpath function call')
, ('disabled')
) AS states(state)
LEFT JOIN (
SELECT datname
, state
, usename
, COALESCE(application_name, '') AS application_name
, COUNT(*)
, COALESCE(EXTRACT (EPOCH FROM (max(now() - xact_start))), 0) AS max_tx_secs
FROM pg_catalog.pg_stat_activity
GROUP BY datname, state, usename, application_name
) sa ON states.state = sa.state
WHERE sa.usename IS NOT NULL
metrics:
- datname:
usage: "LABEL"
description: "Name of the database"
- usename:
usage: "LABEL"
description: "Name of the user"
- application_name:
usage: "LABEL"
description: "Name of the application"
- state:
usage: "LABEL"
description: "State of the backend"
- total:
usage: "GAUGE"
description: "Number of backends"
- max_tx_duration_seconds:
usage: "GAUGE"
description: "Maximum duration of a transaction in seconds"
backends_waiting:
query: |
SELECT count(*) AS total
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted
metrics:
- total:
usage: "GAUGE"
description: "Total number of backends that are currently waiting on other queries"
pg_database:
query: |
SELECT datname
, pg_catalog.pg_database_size(datname) AS size_bytes
, pg_catalog.age(datfrozenxid) AS xid_age
, pg_catalog.mxid_age(datminmxid) AS mxid_age
FROM pg_catalog.pg_database
WHERE datallowconn
metrics:
- datname:
usage: "LABEL"
description: "Name of the database"
- size_bytes:
usage: "GAUGE"
description: "Disk space used by the database"
- xid_age:
usage: "GAUGE"
description: "Number of transactions from the frozen XID to the current one"
- mxid_age:
usage: "GAUGE"
description: "Number of multiple transactions (Multixact) from the frozen XID to the current one"
pg_postmaster:
query: |
SELECT EXTRACT(EPOCH FROM pg_postmaster_start_time) AS start_time
FROM pg_catalog.pg_postmaster_start_time()
metrics:
- start_time:
usage: "GAUGE"
description: "Time at which postgres started (based on epoch)"
pg_replication:
query: |
SELECT CASE WHEN (
NOT pg_catalog.pg_is_in_recovery()
OR pg_catalog.pg_last_wal_receive_lsn() = pg_catalog.pg_last_wal_replay_lsn())
THEN 0
ELSE GREATEST (0,
EXTRACT(EPOCH FROM (now() - pg_catalog.pg_last_xact_replay_timestamp())))
END AS lag,
pg_catalog.pg_is_in_recovery() AS in_recovery,
EXISTS (TABLE pg_stat_wal_receiver) AS is_wal_receiver_up,
(SELECT count(*) FROM pg_catalog.pg_stat_replication) AS streaming_replicas
metrics:
- lag:
usage: "GAUGE"
description: "Replication lag behind primary in seconds"
- in_recovery:
usage: "GAUGE"
description: "Whether the instance is in recovery"
- is_wal_receiver_up:
usage: "GAUGE"
description: "Whether the instance wal_receiver is up"
- streaming_replicas:
usage: "GAUGE"
description: "Number of streaming replicas connected to the instance"
pg_replication_slots:
query: |
SELECT slot_name,
slot_type,
database,
active,
(CASE pg_catalog.pg_is_in_recovery()
WHEN TRUE THEN pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_receive_lsn(), restart_lsn)
ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), restart_lsn)
END) as pg_wal_lsn_diff
FROM pg_catalog.pg_replication_slots
WHERE NOT temporary
metrics:
- slot_name:
usage: "LABEL"
description: "Name of the replication slot"
- slot_type:
usage: "LABEL"
description: "Type of the replication slot"
- database:
usage: "LABEL"
description: "Name of the database"
- active:
usage: "GAUGE"
description: "Flag indicating whether the slot is active"
- pg_wal_lsn_diff:
usage: "GAUGE"
description: "Replication lag in bytes"
pg_stat_archiver:
query: |
SELECT archived_count
, failed_count
, COALESCE(EXTRACT(EPOCH FROM (now() - last_archived_time)), -1) AS seconds_since_last_archival
, COALESCE(EXTRACT(EPOCH FROM (now() - last_failed_time)), -1) AS seconds_since_last_failure
, COALESCE(EXTRACT(EPOCH FROM last_archived_time), -1) AS last_archived_time
, COALESCE(EXTRACT(EPOCH FROM last_failed_time), -1) AS last_failed_time
, COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_archived_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_archived_wal_start_lsn
, COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_failed_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_failed_wal_start_lsn
, EXTRACT(EPOCH FROM stats_reset) AS stats_reset_time
FROM pg_catalog.pg_stat_archiver
predicate_query: |
SELECT NOT pg_catalog.pg_is_in_recovery()
OR pg_catalog.current_setting('archive_mode') = 'always'
metrics:
- archived_count:
usage: "COUNTER"
description: "Number of WAL files that have been successfully archived"
- failed_count:
usage: "COUNTER"
description: "Number of failed attempts for archiving WAL files"
- seconds_since_last_archival:
usage: "GAUGE"
description: "Seconds since the last successful archival operation"
- seconds_since_last_failure:
usage: "GAUGE"
description: "Seconds since the last failed archival operation"
- last_archived_time:
usage: "GAUGE"
description: "Epoch of the last time WAL archiving succeeded"
- last_failed_time:
usage: "GAUGE"
description: "Epoch of the last time WAL archiving failed"
- last_archived_wal_start_lsn:
usage: "GAUGE"
description: "Archived WAL start LSN"
- last_failed_wal_start_lsn:
usage: "GAUGE"
description: "Last failed WAL LSN"
- stats_reset_time:
usage: "GAUGE"
description: "Time at which these statistics were last reset"
pg_stat_bgwriter:
runonserver: "<17.0.0"
query: |
SELECT checkpoints_timed
, checkpoints_req
, checkpoint_write_time
, checkpoint_sync_time
, buffers_checkpoint
, buffers_clean
, maxwritten_clean
, buffers_backend
, buffers_backend_fsync
, buffers_alloc
FROM pg_catalog.pg_stat_bgwriter
metrics:
- checkpoints_timed:
usage: "COUNTER"
description: "Number of scheduled checkpoints that have been performed"
- checkpoints_req:
usage: "COUNTER"
description: "Number of requested checkpoints that have been performed"
- checkpoint_write_time:
usage: "COUNTER"
description: "Total amount of time that has been spent in the portion of checkpoint processing where files are written to disk, in milliseconds"
- checkpoint_sync_time:
usage: "COUNTER"
description: "Total amount of time that has been spent in the portion of checkpoint processing where files are synchronized to disk, in milliseconds"
- buffers_checkpoint:
usage: "COUNTER"
description: "Number of buffers written during checkpoints"
- buffers_clean:
usage: "COUNTER"
description: "Number of buffers written by the background writer"
- maxwritten_clean:
usage: "COUNTER"
description: "Number of times the background writer stopped a cleaning scan because it had written too many buffers"
- buffers_backend:
usage: "COUNTER"
description: "Number of buffers written directly by a backend"
- buffers_backend_fsync:
usage: "COUNTER"
description: "Number of times a backend had to execute its own fsync call (normally the background writer handles those even when the backend does its own write)"
- buffers_alloc:
usage: "COUNTER"
description: "Number of buffers allocated"
pg_stat_bgwriter_17:
runonserver: ">=17.0.0"
name: pg_stat_bgwriter
query: |
SELECT buffers_clean
, maxwritten_clean
, buffers_alloc
, EXTRACT(EPOCH FROM stats_reset) AS stats_reset_time
FROM pg_catalog.pg_stat_bgwriter
metrics:
- buffers_clean:
usage: "COUNTER"
description: "Number of buffers written by the background writer"
- maxwritten_clean:
usage: "COUNTER"
description: "Number of times the background writer stopped a cleaning scan because it had written too many buffers"
- buffers_alloc:
usage: "COUNTER"
description: "Number of buffers allocated"
- stats_reset_time:
usage: "GAUGE"
description: "Time at which these statistics were last reset"
pg_stat_checkpointer:
runonserver: ">=17.0.0"
query: |
SELECT num_timed AS checkpoints_timed
, num_requested AS checkpoints_req
, restartpoints_timed
, restartpoints_req
, restartpoints_done
, write_time
, sync_time
, buffers_written
, EXTRACT(EPOCH FROM stats_reset) AS stats_reset_time
FROM pg_catalog.pg_stat_checkpointer
metrics:
- checkpoints_timed:
usage: "COUNTER"
description: "Number of scheduled checkpoints that have been performed"
- checkpoints_req:
usage: "COUNTER"
description: "Number of requested checkpoints that have been performed"
- restartpoints_timed:
usage: "COUNTER"
description: "Number of scheduled restartpoints due to timeout or after a failed attempt to perform it"
- restartpoints_req:
usage: "COUNTER"
description: "Number of requested restartpoints that have been performed"
- restartpoints_done:
usage: "COUNTER"
description: "Number of restartpoints that have been performed"
- write_time:
usage: "COUNTER"
description: "Total amount of time that has been spent in the portion of processing checkpoints and restartpoints where files are written to disk, in milliseconds"
- sync_time:
usage: "COUNTER"
description: "Total amount of time that has been spent in the portion of processing checkpoints and restartpoints where files are synchronized to disk, in milliseconds"
- buffers_written:
usage: "COUNTER"
description: "Number of buffers written during checkpoints and restartpoints"
- stats_reset_time:
usage: "GAUGE"
description: "Time at which these statistics were last reset"
pg_stat_database:
query: |
SELECT datname
, xact_commit
, xact_rollback
, blks_read
, blks_hit
, tup_returned
, tup_fetched
, tup_inserted
, tup_updated
, tup_deleted
, conflicts
, temp_files
, temp_bytes
, deadlocks
, blk_read_time
, blk_write_time
FROM pg_catalog.pg_stat_database
metrics:
- datname:
usage: "LABEL"
description: "Name of this database"
- xact_commit:
usage: "COUNTER"
description: "Number of transactions in this database that have been committed"
- xact_rollback:
usage: "COUNTER"
description: "Number of transactions in this database that have been rolled back"
- blks_read:
usage: "COUNTER"
description: "Number of disk blocks read in this database"
- blks_hit:
usage: "COUNTER"
description: "Number of times disk blocks were found already in the buffer cache, so that a read was not necessary (this only includes hits in the PostgreSQL buffer cache, not the operating system's file system cache)"
- tup_returned:
usage: "COUNTER"
description: "Number of rows returned by queries in this database"
- tup_fetched:
usage: "COUNTER"
description: "Number of rows fetched by queries in this database"
- tup_inserted:
usage: "COUNTER"
description: "Number of rows inserted by queries in this database"
- tup_updated:
usage: "COUNTER"
description: "Number of rows updated by queries in this database"
- tup_deleted:
usage: "COUNTER"
description: "Number of rows deleted by queries in this database"
- conflicts:
usage: "COUNTER"
description: "Number of queries canceled due to conflicts with recovery in this database"
- temp_files:
usage: "COUNTER"
description: "Number of temporary files created by queries in this database"
- temp_bytes:
usage: "COUNTER"
description: "Total amount of data written to temporary files by queries in this database"
- deadlocks:
usage: "COUNTER"
description: "Number of deadlocks detected in this database"
- blk_read_time:
usage: "COUNTER"
description: "Time spent reading data file blocks by backends in this database, in milliseconds"
- blk_write_time:
usage: "COUNTER"
description: "Time spent writing data file blocks by backends in this database, in milliseconds"
pg_stat_replication:
primary: true
query: |
SELECT usename
, COALESCE(application_name, '') AS application_name
, COALESCE(client_addr::text, '') AS client_addr
, COALESCE(client_port::text, '') AS client_port
, EXTRACT(EPOCH FROM backend_start) AS backend_start
, COALESCE(pg_catalog.age(backend_xmin), 0) AS backend_xmin_age
, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), sent_lsn) AS sent_diff_bytes
, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), write_lsn) AS write_diff_bytes
, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), flush_lsn) AS flush_diff_bytes
, COALESCE(pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), replay_lsn),0) AS replay_diff_bytes
, COALESCE((EXTRACT(EPOCH FROM write_lag)),0)::float AS write_lag_seconds
, COALESCE((EXTRACT(EPOCH FROM flush_lag)),0)::float AS flush_lag_seconds
, COALESCE((EXTRACT(EPOCH FROM replay_lag)),0)::float AS replay_lag_seconds
FROM pg_catalog.pg_stat_replication
metrics:
- usename:
usage: "LABEL"
description: "Name of the replication user"
- application_name:
usage: "LABEL"
description: "Name of the application"
- client_addr:
usage: "LABEL"
description: "Client IP address"
- client_port:
usage: "LABEL"
description: "Client TCP port"
- backend_start:
usage: "COUNTER"
description: "Time when this process was started"
- backend_xmin_age:
usage: "COUNTER"
description: "The age of this standby's xmin horizon"
- sent_diff_bytes:
usage: "GAUGE"
description: "Difference in bytes from the last write-ahead log location sent on this connection"
- write_diff_bytes:
usage: "GAUGE"
description: "Difference in bytes from the last write-ahead log location written to disk by this standby server"
- flush_diff_bytes:
usage: "GAUGE"
description: "Difference in bytes from the last write-ahead log location flushed to disk by this standby server"
- replay_diff_bytes:
usage: "GAUGE"
description: "Difference in bytes from the last write-ahead log location replayed into the database on this standby server"
- write_lag_seconds:
usage: "GAUGE"
description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written it"
- flush_lag_seconds:
usage: "GAUGE"
description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written and flushed it"
- replay_lag_seconds:
usage: "GAUGE"
description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written, flushed and applied it"
pg_settings:
query: |
SELECT name,
CASE setting WHEN 'on' THEN '1' WHEN 'off' THEN '0' ELSE setting END AS setting
FROM pg_catalog.pg_settings
WHERE vartype IN ('integer', 'real', 'bool')
ORDER BY 1
metrics:
- name:
usage: "LABEL"
description: "Name of the setting"
- setting:
usage: "GAUGE"
description: "Setting value"
pg_extensions:
query: |
SELECT
current_database() as datname,
name as extname,
default_version,
installed_version,
CASE
WHEN default_version = installed_version THEN 0
ELSE 1
END AS update_available
FROM pg_catalog.pg_available_extensions
WHERE installed_version IS NOT NULL
metrics:
- datname:
usage: "LABEL"
description: "Name of the database"
- extname:
usage: "LABEL"
description: "Extension name"
- default_version:
usage: "LABEL"
description: "Default version"
- installed_version:
usage: "LABEL"
description: "Installed version"
- update_available:
usage: "GAUGE"
description: "An update is available"
target_databases:
- '*'

12
comfyui/comfyui-pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: comfyui-pvc
namespace: comfyui
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 50Gi

13
comfyui/comfyui-svc.yaml Normal file
View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: comfyui
namespace: comfyui
spec:
selector:
app: comfyui
ports:
- protocol: TCP
port: 8188
targetPort: 8188
type: ClusterIP

44
comfyui/comfyui.yaml Normal file
View File

@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: comfyui
namespace: comfyui
spec:
replicas: 1
selector:
matchLabels:
app: comfyui
serviceName: comfyui
template:
metadata:
labels:
app: comfyui
spec:
restartPolicy: Always
terminationGracePeriodSeconds: 30
nodeSelector:
kubernetes.io/hostname: kubernetes-worker-1.jsme.be
containers:
- name: comfyui
image: ghcr.io/ai-dock/comfyui:latest
ports:
- containerPort: 8188
env:
- name: COMFYUI_FLAGS
value: "--listen 0.0.0.0 --port 8188 --use-xpu"
- name: AUTO_UPDATE
value: "false"
securityContext:
privileged: true
volumeMounts:
- name: data
mountPath: /config
- name: dri
mountPath: /dev/dri
volumes:
- name: data
persistentVolumeClaim:
claimName: comfyui-pvc
- name: dri
hostPath:
path: /dev/dri

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: databasus

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: databasus-pvc
namespace: databasus
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn-static
resources:
requests:
storage: 10Gi

View File

@@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: databasus
namespace: databasus
spec:
replicas: 1
selector:
matchLabels:
app: databasus
serviceName: databasus-svc
template:
metadata:
labels:
app: databasus
spec:
restartPolicy: Always
terminationGracePeriodSeconds: 10
containers:
- name: databasus
image: databasus/databasus:latest
imagePullPolicy: Always
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
ports:
- containerPort: 4005
volumeMounts:
- name: data
mountPath: /databasus-data
volumes:
- name: data
persistentVolumeClaim:
claimName: databasus-pvc

View File

@@ -0,0 +1,13 @@
kind: Service
apiVersion: v1
metadata:
name: databasus-svc
namespace: databasus
spec:
ports:
- name: databasus
port: 4005
targetPort: 4005
selector:
app: databasus
type: ClusterIP

46
databasus/httproute.yaml Normal file
View File

@@ -0,0 +1,46 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: databasus-route
namespace: databasus
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: databasus
hostnames:
- "databasus.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "databasus.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: databasus-svc
port: 4005
kind: Service
group: ""
weight: 1

View File

@@ -0,0 +1,29 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-ingress
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"
spec:
ingressClassName: nginx
tls:
- hosts:
- argocd.jsme.be
secretName: argocd-tls
rules:
- host: argocd.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 443

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bentopdf-ingress
namespace: bentopdf
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- pdf.jsme.be
secretName: bentopdf-tls
rules:
- host: pdf.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bentopdf
port:
number: 8080

View File

@@ -0,0 +1,29 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-ingress
namespace: gitea
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "8192m"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- gitea.jsme.be
secretName: gitea-tls
rules:
- host: gitea.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea
port:
number: 3000

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: infisical-ingress
namespace: infisical
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "100g"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- infisical.jsme.be
secretName: infisical-tls
rules:
- host: infisical.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: infisical
port:
number: 8080

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ittools-ingress
namespace: ittools
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- tools.jsme.be
secretName: tools-tls
rules:
- host: tools.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ittools
port:
number: 8080

View File

@@ -0,0 +1,29 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jellyseer-ingress
namespace: jellyseer
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"
spec:
ingressClassName: nginx
tls:
- hosts:
- jellyseer.jsme.be
secretName: jellyseer-tls
rules:
- host: jellyseer.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jellyseer
port:
number: 5055

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"
spec:
ingressClassName: nginx
tls:
- hosts:
- jenkins.jsme.be
secretName: jenkins-tls
rules:
- host: jenkins.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins-svc-ingress
port:
number: 8080

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc-ingress
namespace: jenkins
spec:
selector:
app: jenkins
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP

View File

@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: longhorn-ingress
namespace: longhorn-system
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- longhorn.jsme.be
secretName: longhorn-tls
rules:
- host: longhorn.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: longhorn-frontend
port:
number: 80

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: resume-minioweb-ingress
namespace: resume
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- resume-minioweb.jsme.be
secretName: resume-minioweb-tls
rules:
- host: resume-minioweb.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: minio
port:
number: 9001

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: resume-minio-ingress
namespace: resume
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- resume-minio.jsme.be
secretName: resume-minio-tls
rules:
- host: resume-minio.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: minio
port:
number: 9000

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: n8n-ingress
namespace: n8n
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- n8n.jsme.be
secretName: n8n-tls
rules:
- host: n8n.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: n8n-svc
port:
number: 5678

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: netbootxyz
namespace: netbootxyz
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- netboot.jsme.be
secretName: netbootxyz-tls
rules:
- host: netboot.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: netbootxyz
port:
number: 3000

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: passbolt-ingress
namespace: passbolt
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
tls:
- hosts:
- passbolt.jsme.be
secretName: passbolt-tls
rules:
- host: passbolt.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: passbolt
port:
number: 443

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: proxmox-ingress
namespace: proxmox
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
tls:
- hosts:
- proxmox.jsme.be
secretName: proxmox-tls
rules:
- host: proxmox.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: proxmox
port:
number: 8006

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: resume-ingress
namespace: resume
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- resume.jsme.be
secretName: resume-tls
rules:
- host: resume.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: resume
port:
number: 3000

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: technitium-backup-ingress
namespace: technitium
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "100g"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- dns2.jsme.be
secretName: technitium-backup-tls
rules:
- host: dns2.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: technitium-backup
port:
number: 5380

View File

@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: technitium-ingress
namespace: technitium
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- dns1.jsme.be
secretName: technitium-tls
rules:
- host: dns1.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: technitium
port:
number: 5380

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: truenas-ingress
namespace: truenas
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size: "100g"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- truenas.jsme.be
secretName: truenas-tls
rules:
- host: truenas.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: truenas
port:
number: 443

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: unifi-ingress
namespace: unifi
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
tls:
- hosts:
- unifi.jsme.be
secretName: unifi-tls
rules:
- host: unifi.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: unifi
port:
number: 443

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wiki-ingress
namespace: wiki
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
tls:
- hosts:
- wiki.jsme.be
secretName: wiki-tls
rules:
- host: wiki.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wiki
port:
number: 3000

View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zipline-ingress
namespace: zipline
annotations:
cert-manager.io/cluster-issuer: azure-dns
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx
tls:
- hosts:
- share.jsme.be
secretName: zipline-tls
rules:
- host: share.jsme.be
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zipline
port:
number: 3000

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: psono-tls
namespace: envoy-gateway
spec:
secretName: psono-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- psono.jsme.be

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: psono
protocol: HTTPS
port: 443
hostname: "psono.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: psono
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: psono-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,46 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: psono-route
namespace: psono
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: psono
hostnames:
- "psono.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "psono.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: psono
port: 80
kind: Service
group: ""
weight: 1

View File

@@ -0,0 +1,22 @@
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: psono-secrets
namespace: infisical
spec:
hostAPI: https://infisical.jsme.be
resyncInterval: 30
authentication:
universalAuth:
secretsScope:
projectSlug: "kubernetes"
envSlug: "prod"
secretsPath: "/psono"
recursive: true
credentialsRef:
secretName: infisical-universal-auth
secretNamespace: infisical
managedSecretReference:
secretName: psono-secrets
secretNamespace: psono
secretType: Opaque

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: psono

View File

@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: psono
spec:
replicas: 1
selector:
matchLabels:
app: postgresql
serviceName: postgresql
template:
metadata:
labels:
app: postgresql
spec:
restartPolicy: Always
terminationGracePeriodSeconds: 60
containers:
- name: postgresql
image: postgres:18
ports:
- containerPort: 5432
volumeMounts:
- name: postgresql-database
mountPath: /var/lib/postgresql/pgdata
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: psono-secrets
key: db_password
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: psono-secrets
key: db_user
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: psono-secrets
key: db_name
volumes:
- name: postgresql-database
persistentVolumeClaim:
claimName: postgresql-pvc

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgresql-pvc
namespace: psono
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: postgresql
namespace: psono
spec:
selector:
app: postgresql
type: ClusterIP
ports:
- name: postgresql-port
protocol: TCP
port: 5432
targetPort: 5432

12
deprecated/psono/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: psono-data
namespace: psono
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,254 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: psono-settings
namespace: psono
data:
settings.yaml: |
SECRET_KEY: 'KPjkg8HXdizAGt5DHV43DIAc9O3yeDy2UnbNMN35a3A2BthUhdh1sHX4V2yEGn6a'
ACTIVATION_LINK_SECRET: 'tTJnSKGtEzsh3cRj0WYCC3ZoGNwtSIgvsodbt72Jr037O0avVTUqbHTCKCzuiXH2'
DB_SECRET: 'oLSX12kWYDEaKPXWOU8uPk0sP9vmKmdAE84SqCj2z2XkSdJnMR3hVUsW1CwFQ7cP'
EMAIL_SECRET_SALT: '$2b$12$7iZIEIbGsilSxtPlJ4Tuce'
PRIVATE_KEY: 'f1eb687fb69ab3be9372b9acfce649518c1602e47e07f8fe909fe82059961e5d'
PUBLIC_KEY: '2154e086c8b469bce14d47382ca953b3ca37be485af16757e2cbab5543645974'
WEB_CLIENT_URL: 'https://psono.jsme.be'
# The number of proxies in your environment to parse the X-Forwarded-For header. The basic setup of Psono uses 2
# reverse proxies, the regular one and one in the combo container. If you have additional Loadbalancers you may have
# adjust this parameter.
NUM_PROXIES: 2
FAVICON_SERVICE_URL: 'https://favicon.psono.com/v1/icon/'
# Switch DEBUG to false if you go into production
DEBUG: False
# Adjust this according to Django Documentation https://docs.djangoproject.com/en/5.2/ref/settings/
ALLOWED_HOSTS: ['*']
# Should be your domain without "www.". Will be the last part of the username
ALLOWED_DOMAINS: ['jsme.be', 'gmail.com', 'telenet.be']
# If you want to disable registration, you can comment in the following line
# ALLOW_REGISTRATION: False
# If you want to disable the lost password functionality, you can comment in the following line
# ALLOW_LOST_PASSWORD: False
# If you want to enforce that the email address and username needs to match upon registration
ENFORCE_MATCHING_USERNAME_AND_EMAIL: False
# If you want to restrict registration to some email addresses you can specify here a list of domains to filter
# REGISTRATION_EMAIL_FILTER: ['company1.com', 'company2.com']
# Should be the URL of the host under which the host is reachable
# If you open the url and append /info/ to it you should have a text similar to {"info":"{\"version\": \"....}
HOST_URL: 'https://psono.jsme.be/server'
# The email used to send emails, e.g. for activation
# ATTENTION: If executed in a docker container, then "localhost" will resolve to the docker container, so
# "localhost" will not work as host. Use the public IP or DNS record of the server.
EMAIL_FROM: $email_from
EMAIL_HOST: $email_host
EMAIL_HOST_USER: $email_user
EMAIL_HOST_PASSWORD: $email_password
EMAIL_PORT: $email_port
EMAIL_SUBJECT_PREFIX: ''
EMAIL_USE_TLS: True
EMAIL_TIMEOUT: 10
# Cache with Redis
# By default you should use something different than database 0 or 1, e.g. 13 (default max is 16, can be configured in
# redis.conf) possible URLS are:
# redis://[:password]@localhost:6379/0
# rediss://[:password]@localhost:6379/0
# unix://[:password]@/path/to/socket.sock?db=0
# CACHE_ENABLE: False
# CACHE_REDIS: False
# CACHE_REDIS_LOCATION: 'redis://127.0.0.1:6379/13'
# The server will automatically connect to the license server to get a license for 10 users.
# For paying customers we offer the opportunity to get an offline license code.
#
# LICENSE_CODE: |
# 0abcdefg...
# 1abcdefg...
# 2abcdefg...
# 3abcdefg...
# 4abcdefg...
# 5abcdefg...
# 6abcdefg...
# 7abcdefg...
# 8abcdefg...
# Optional: Send an email notification when remaining licenses reach a threshold.
# The threshold is checked whenever users are created or activated.
ADMIN_EMAIL: [$email_user]
# ADMIN_EMAIL_LICENSE_THRESHOLD: 1
# Enables the management API, required for the psono-admin-client / admin portal (Default is set to False)
MANAGEMENT_ENABLED: True
# Enables the fileserver API, required for the psono-fileserver
# FILESERVER_HANDLER_ENABLED: False
# Enables files for the client
# FILES_ENABLED: False
# Allows that users can search for partial usernames
ALLOW_USER_SEARCH_BY_USERNAME_PARTIAL: True
# Allows that users can search for email addresses too
ALLOW_USER_SEARCH_BY_EMAIL: True
# Disables central security reports
# DISABLE_CENTRAL_SECURITY_REPORTS: True
# If you want to use SAML, then you can configure it like this as a dictionary.
#
# About the parameters:
# idp->entityId: Thats the url to the metadata of your IDP
# idp->singleLogoutService->url: Thats the url to the logout service of your IDP
# idp->singleSignOnService->url: Thats the url to the single sign-on service of your IDP
# idp->x509cert: Thats the certificate of your IDP
# idp->groups_attribute: The attribute in the SAML response that holds your groups
# idp->username_attribute: The attribute in the SAML response that holds the username. If you put here null, then it will use the NameID
# idp->email_attribute: The attribute in the SAML response that holds the email address.
# idp->username_domain: The domain that is appended to the provided username, if the provided username is not already in email format.
# idp->required_group: A list of group names (casesensitive) in order to restrict who can use SAML login with this installation. Leave empty for no restriction.
# idp->is_adfs: If you are using ADFS.
# idp->honor_multifactors: Multifactor authentication can be bypassed with this flag for all SAML users (e.g. when you already enforce multifactor on the SAML provider).
# idp->max_session_lifetime: The time in seconds that a session created throught SAML will live
#
# sp->NameIDFormat: The normal nameformat parameter. (should only be set to transient if you have set a username attribute with username_attribute)
# sp->attributeConsumingService: Only necessary if the IDP needs to be told to send some specific attributes
# sp->x509cert: The X.509 cert
# sp->privateKey: The corresponding private key of the X.509 cert
#
# There are a couple of more options next to those required ones below.
# More information can be found here https://github.com/onelogin/python3-saml
#
# A self-signed certificate can be generated with:
# openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes -sha256 -out sp_x509cert.crt -keyout sp_private_key.key
#
# To help you setup SAML, we have created a small "testsaml" command that should make things easier. You can execute it like:
# docker run --rm \
# -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
# -ti psono/psono-combo-enterprise:latest python3 psono/manage.py testsaml
#
# The number 1 in line 2 is the provider id. Users are matched by the constructed username.
#
# SAML_CONFIGURATIONS:
# 1:
# idp:
# entityId: "https://idp.exampple.com/metadata.php"
# singleLogoutService:
# binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
# url: "https://idp.exampple.com/SingleLogoutService.php"
# singleSignOnService:
# binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
# url: "https://idp.exampple.com/SingleSignOnService.php"
# x509cert: "ABC...=="
# groups_attribute: "groups"
# username_attribute: 'username'
# email_attribute: 'email'
# username_domain: 'example.com'
# required_group: []
# is_adfs: false
# honor_multifactors: true
# max_session_lifetime: 86400
# sp:
# NameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
# assertionConsumerService:
# binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
# attributeConsumingService:
# serviceName: "Psono"
# serviceDescription: "Psono password manager"
# requestedAttributes:
# -
# attributeValue: []
# friendlyName: ""
# isRequired: false
# name: "attribute-that-has-to-be-requested-explicitely"
# nameFormat: ""
# privateKey: "ABC...=="
# singleLogoutService:
# binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
# x509cert: "ABC...=="
# autoprovision_psono_folder: false
# autoprovision_psono_group: false
# strict: true
#
# You need a couple of urls to configure the IDP correctly. If the server is accessible under https://example.com/server
# (e.g. https://example.com/server/healthcheck/ shows some json output) and the provider id is 1 as in the example
# above the following urls are valid:
#
# for metadata : https://example.com/server/saml/1/metadata/
# for assertion consumer service : https://example.com/server/saml/1/acs/
# for single logout service : https://example.com/server/saml/1/sls/
#
#
# ATTENTION: API kays currently bypass SAML authentication, that means API keys can still access secrets even if the
# user was disabled in SAML. API keys can be disabled with COMPLIANCE_DISABLE_API_KEYS
# If you want to use OIDC, then you can configure it like this as a dictionary.
# OIDC_CONFIGURATIONS:
# 1:
# OIDC_RP_SIGN_ALGO: 'RS256'
# OIDC_RP_CLIENT_ID: 'whatever client id was provided'
# OIDC_RP_CLIENT_SECRET: 'whatever secret was provided'
# OIDC_OP_JWKS_ENDPOINT: 'https://example.com/jwks'
# OIDC_OP_AUTHORIZATION_ENDPOINT: 'https://example.com/authorize'
# OIDC_OP_TOKEN_ENDPOINT: 'https://example.com/token'
# OIDC_OP_USER_ENDPOINT: 'https://example.com/userinfo'
#
# Standard parameters explained:
# OIDC_RP_SIGN_ALGO defaults to HS256 and needs to match the algo of your IDP
# OIDC_RP_CLIENT_ID the client id that is provided by your IDP
# OIDC_RP_CLIENT_SECRET the secret that is provided by your IDP
# OIDC_OP_JWKS_ENDPOINT The JWKS endpoint of your IDP
# OIDC_OP_AUTHORIZATION_ENDPOINT The authorization endpoint of your IDP
# OIDC_OP_TOKEN_ENDPOINT The token endpoint of your IDP
#
# other parameters are:
# OIDC_VERIFY_JWT defaults to true, Controls whether Psono verifies the signature of the JWT tokens
# OIDC_USE_NONCE defaults to true, Controls whether Psono uses nonce verification
# OIDC_VERIFY_SSL defaults to true, Controls whether Psono verifies the SSL certificate of the IDP responses
# OIDC_TIMEOUT defaults to 10, Defines a timeout for all requests in seconds to the IDP (fetch JWS, retrieve JWT tokens, userinfo endpoint))
# OIDC_PROXY defaults to None, Defines a proxy for all requests to the IDP (fetch JWS, retrieve JWT tokens, Userinfo Endpoint). More infos can be found here https://requests.readthedocs.io/en/master/user/advanced/#proxies
# OIDC_RP_SCOPES defaults to 'openid email', The OpenID Connect scopes to request during login.
# OIDC_AUTH_REQUEST_EXTRA_PARAMS defaults to {}, Additional parameters to include in the initial authorization request.
# OIDC_RP_IDP_SIGN_KEY defaults to None, Sets the key the IDP uses to sign ID tokens in the case of an RSA sign algorithm. Should be the signing key in PEM or DER format.
# OIDC_ALLOW_UNSECURED_JWT defaults to False, Controls whether the Psono is going to allow unsecured JWT tokens (tokens with header {"alg":"none"}). This needs to be set to True if the IDP is returning unsecured JWT tokens and you want to accept them. See also https://tools.ietf.org/html/rfc7519#section-6
# OIDC_TOKEN_USE_BASIC_AUTH defaults to False, Use HTTP Basic Authentication instead of sending the client secret in token request POST body.
# Your Postgres Database credentials
# ATTENTION: If executed in a docker container, then "localhost" will resolve to the docker container, so
# "localhost" will not work as host. Use the public IP or DNS record of the server.
DATABASES:
default:
'ENGINE': 'django.db.backends.postgresql_psycopg2'
'NAME': $db_name
'USER': $db_user
'PASSWORD': $db_password
'HOST': $db_host
'PORT': $db_port
# The path to the template folder can be "shadowed" if required later
TEMPLATES: [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['/root/psono/templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

View File

@@ -0,0 +1,88 @@
apiVersion: v1
kind: Service
metadata:
name: psono
namespace: psono
spec:
clusterIP: None
selector:
app: psono
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: psono
namespace: psono
spec:
serviceName: psono
replicas: 1
selector:
matchLabels:
app: psono
template:
metadata:
labels:
app: psono
spec:
initContainers:
- name: envsubst
image: bhgedigital/envsubst:latest
command: ["sh", "-c", "envsubst < /tmp/settings-template/settings.yaml > /root/.psono_server/settings.yaml"]
envFrom:
- secretRef:
name: psono-secrets
volumeMounts:
- name: psono-settings-template
mountPath: /tmp/settings-template
- name: psono-settings-processed
mountPath: /root/.psono_server
- name: migrate
image: psono/psono-combo-enterprise:7.1.5-4.5.3-1.8.0
command: ["python3", "./psono/manage.py", "migrate"]
envFrom:
- secretRef:
name: psono-secrets
volumeMounts:
- name: psono-settings-processed
mountPath: /root/.psono_server
containers:
- name: psono
image: psono/psono-combo-enterprise:7.1.5-4.5.3-1.8.0
ports:
- name: http
containerPort: 80
envFrom:
- secretRef:
name: psono-secrets
volumeMounts:
- name: psono-settings-processed
mountPath: /root/.psono_server
- name: psono-data
mountPath: /var/log/psono
livenessProbe:
httpGet:
path: /server/healthcheck/
port: 80
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /server/healthcheck/
port: 80
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: psono-settings-template
configMap:
name: psono-settings
- name: psono-settings-processed
emptyDir: {}
- name: psono-data
persistentVolumeClaim:
claimName: psono-data

View File

@@ -0,0 +1,46 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vaultwarden-route
namespace: vaultwarden
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-internal
namespace: envoy-gateway
sectionName: vaultwarden
hostnames:
- "vault.jsme.be"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
set:
- name: X-Forwarded-Host
value: "vault.jsme.be"
- name: X-Forwarded-Proto
value: https
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
- name: X-Content-Type-Options
value: nosniff
- name: X-Frame-Options
value: SAMEORIGIN
- name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: Permissions-Policy
value: "camera=(), microphone=(), geolocation=(), payment=()"
backendRefs:
- name: vaultwarden
port: 80
kind: Service
group: ""
weight: 1

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: vaultwarden

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data
namespace: vaultwarden
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,120 @@
apiVersion: v1
kind: Service
metadata:
name: vaultwarden
namespace: vaultwarden
spec:
selector:
app: vaultwarden
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vaultwarden
namespace: vaultwarden
spec:
serviceName: vaultwarden
replicas: 1
selector:
matchLabels:
app: vaultwarden
template:
metadata:
labels:
app: vaultwarden
spec:
containers:
- name: vaultwarden
image: vaultwarden/server:1.35.6-alpine
ports:
- name: http
containerPort: 80
env:
- name: DOMAIN
value: "https://vault.jsme.be"
- name: SIGNUPS_ALLOWED
value: "false"
- name: ADMIN_TOKEN
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: admin_token
- name: SMTP_HOST
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: smtp_host
- name: SMTP_FROM
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: smtp_from
- name: SMTP_PORT
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: smtp_port
- name: SSO_ENABLED
value: "true"
- name: SSO_AUTHORITY
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: sso_authority
- name: SSO_CLIENT_ID
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: sso_client_id
- name: SSO_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: sso_client_secret
- name: SSO_SCOPES
value: "email profile offline_access"
- name: SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION
value: "false"
- name: SSO_CLIENT_CACHE_EXPIRATION
value: "0"
- name: SSO_ONLY
value: "true"
- name: SSO_SIGNUPS_MATCH_EMAIL
value: "true"
- name: SMTP_SECURITY
value: "starttls"
- name: SMTP_USERNAME
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: smtp_username
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: vaultwarden-secrets
key: smtp_password
volumeMounts:
- name: vaultwarden-data
mountPath: /data
livenessProbe:
httpGet:
path: /alive
port: 80
initialDelaySeconds: 15
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /alive
port: 80
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
volumes:
- name: vaultwarden-data
persistentVolumeClaim:
claimName: vaultwarden-data

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: argocd-tls
namespace: envoy-gateway
spec:
secretName: argocd-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- argocd.jsme.be

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: argocd
protocol: HTTPS
port: 443
hostname: "argocd.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: argocd
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: argocd-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: radarr-tls
namespace: envoy-gateway
spec:
secretName: radarr-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- radarr.jsme.be

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: radarr
protocol: HTTPS
port: 443
hostname: "radarr.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: arrstack
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: radarr-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: sonarr-tls
namespace: envoy-gateway
spec:
secretName: sonarr-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- sonarr.jsme.be

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: sonarr
protocol: HTTPS
port: 443
hostname: "sonarr.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: arrstack
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: sonarr-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: authentik-tls
namespace: envoy-gateway
spec:
secretName: authentik-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- auth.jsme.be

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: authentik
protocol: HTTPS
port: 443
hostname: "auth.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: authentik
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: authentik-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,19 @@
- op: add
path: /spec/listeners/-
value:
name: authentik
protocol: HTTPS
port: 443
hostname: "auth.jsme.be"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: authentik
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: authentik-tls
namespace: envoy-gateway

View File

@@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: bentopdf-tls
namespace: envoy-gateway
spec:
secretName: bentopdf-tls
privateKey:
rotationPolicy: Always
issuerRef:
name: azure-dns
kind: ClusterIssuer
dnsNames:
- pdf.jsme.be

Some files were not shown because too many files have changed in this diff Show More