Adding Justfile and helm chart
This commit is contained in:
@@ -18,7 +18,10 @@
|
||||
"Bash(grep -l \"molecule_test_mode\" /home/iroddis/dev/sovereign/roles/*/tasks/main.yml)",
|
||||
"Bash(grep -l \"molecule_test_mode\" /home/iroddis/dev/sovereign/roles/*/handlers/main.yml)",
|
||||
"Bash(ls /home/iroddis/dev/sovereign/roles/*/molecule/default/)",
|
||||
"Bash(grep -v \"^$\")"
|
||||
"Bash(grep -v \"^$\")",
|
||||
"Bash(helm template:*)",
|
||||
"Bash(brew list:*)",
|
||||
"Bash(export PATH=\"/opt/homebrew/bin:$PATH\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
set dotenv-load
|
||||
|
||||
# Default: list available recipes
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Install Ansible Galaxy collections
|
||||
deps:
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
# Set up the target host: install Docker and create the sovereign network
|
||||
setup-host:
|
||||
ansible-playbook playbooks/site.yml --tags common
|
||||
|
||||
# Run molecule tests for all roles
|
||||
test:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
roles=(authentik common forgejo graylog headscale jitsi matrix minio nextcloud roundcube stalwart vaultwarden wazuh website)
|
||||
failed=()
|
||||
for role in "${roles[@]}"; do
|
||||
echo "==> Testing role: $role"
|
||||
if ! (cd roles/$role && molecule test); then
|
||||
failed+=("$role")
|
||||
fi
|
||||
done
|
||||
if [ ${#failed[@]} -gt 0 ]; then
|
||||
echo "FAILED roles: ${failed[*]}"
|
||||
exit 1
|
||||
fi
|
||||
echo "All molecule tests passed."
|
||||
|
||||
# Run molecule tests for a single role: just test-role common
|
||||
test-role role:
|
||||
cd roles/{{ role }} && molecule test
|
||||
|
||||
# Update an existing deployment (pull latest config, re-run all roles)
|
||||
update:
|
||||
ansible-playbook playbooks/site.yml
|
||||
|
||||
# Update a single service: just update-service authentik
|
||||
update-service service:
|
||||
ansible-playbook playbooks/site.yml --tags {{ service }}
|
||||
|
||||
# Dry-run the full deployment
|
||||
check:
|
||||
ansible-playbook playbooks/site.yml --check --diff
|
||||
|
||||
# Lint the project
|
||||
lint:
|
||||
ansible-lint
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: v2
|
||||
name: sovereign
|
||||
description: >
|
||||
Self-hosted infrastructure stack for small businesses — Traefik, Graylog,
|
||||
Authentik, MinIO, Nextcloud, Stalwart Mail, Roundcube, Matrix/Element,
|
||||
Jitsi, Headscale, Wazuh, Vaultwarden, Forgejo, and a static website.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "1.0.0"
|
||||
keywords:
|
||||
- self-hosted
|
||||
- infrastructure
|
||||
- authentik
|
||||
- nextcloud
|
||||
- matrix
|
||||
- forgejo
|
||||
home: https://github.com/your-org/sovereign
|
||||
maintainers:
|
||||
- name: Sovereign Maintainers
|
||||
@@ -0,0 +1,176 @@
|
||||
{{/*
|
||||
Expand the chart name.
|
||||
*/}}
|
||||
{{- define "sovereign.name" -}}
|
||||
{{- .Chart.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully-qualified app name using release name.
|
||||
*/}}
|
||||
{{- define "sovereign.fullname" -}}
|
||||
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels applied to every resource.
|
||||
*/}}
|
||||
{{- define "sovereign.labels" -}}
|
||||
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: sovereign
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels — used in matchLabels and Service selectors.
|
||||
Pass a dict with "root" (.Values context) and "component" (string).
|
||||
Usage: {{ include "sovereign.selectorLabels" (dict "root" . "component" "graylog") }}
|
||||
*/}}
|
||||
{{- define "sovereign.selectorLabels" -}}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Base domain.
|
||||
*/}}
|
||||
{{- define "sovereign.baseDomain" -}}
|
||||
{{- .Values.global.baseDomain -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
SMTP host: configured value or the stalwart Service name.
|
||||
*/}}
|
||||
{{- define "sovereign.smtpHost" -}}
|
||||
{{- if .Values.smtp.host -}}
|
||||
{{- .Values.smtp.host -}}
|
||||
{{- else -}}
|
||||
{{- .Release.Name }}-stalwart
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
SMTP from address.
|
||||
*/}}
|
||||
{{- define "sovereign.smtpFrom" -}}
|
||||
{{- if .Values.smtp.from -}}
|
||||
{{- .Values.smtp.from -}}
|
||||
{{- else -}}
|
||||
{{- printf "noreply@%s" .Values.global.baseDomain -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
SMTP username.
|
||||
*/}}
|
||||
{{- define "sovereign.smtpUser" -}}
|
||||
{{- if .Values.smtp.user -}}
|
||||
{{- .Values.smtp.user -}}
|
||||
{{- else -}}
|
||||
{{- printf "noreply@%s" .Values.global.baseDomain -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Graylog GELF host — release-name-graylog service, unless overridden.
|
||||
*/}}
|
||||
{{- define "sovereign.graylogHost" -}}
|
||||
{{- .Release.Name }}-graylog
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Authentik base URL.
|
||||
*/}}
|
||||
{{- define "sovereign.authentikURL" -}}
|
||||
{{- printf "https://auth.%s" .Values.global.baseDomain -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Traefik ACME email.
|
||||
*/}}
|
||||
{{- define "sovereign.acmeEmail" -}}
|
||||
{{- if .Values.traefik.acmeEmail -}}
|
||||
{{- .Values.traefik.acmeEmail -}}
|
||||
{{- else -}}
|
||||
{{- printf "admin@%s" .Values.global.baseDomain -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Authentik admin email.
|
||||
*/}}
|
||||
{{- define "sovereign.authentikAdminEmail" -}}
|
||||
{{- if .Values.authentik.adminEmail -}}
|
||||
{{- .Values.authentik.adminEmail -}}
|
||||
{{- else -}}
|
||||
{{- printf "admin@%s" .Values.global.baseDomain -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Forgejo admin email.
|
||||
*/}}
|
||||
{{- define "sovereign.forgejoAdminEmail" -}}
|
||||
{{- if .Values.forgejo.adminEmail -}}
|
||||
{{- .Values.forgejo.adminEmail -}}
|
||||
{{- else -}}
|
||||
{{- printf "admin@%s" .Values.global.baseDomain -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Standard Ingress annotations (cert-manager if configured).
|
||||
*/}}
|
||||
{{- define "sovereign.ingressAnnotations" -}}
|
||||
{{- if .Values.global.clusterIssuer }}
|
||||
cert-manager.io/cluster-issuer: {{ .Values.global.clusterIssuer }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PVC storageClassName snippet — omitted entirely when empty so the cluster default is used.
|
||||
Usage: {{ include "sovereign.storageClass" .Values.global.storageClass }}
|
||||
*/}}
|
||||
{{- define "sovereign.storageClass" -}}
|
||||
{{- if . }}
|
||||
storageClassName: {{ . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Standard Ingress TLS block for a single host.
|
||||
Usage: {{ include "sovereign.ingressTLS" (dict "host" "foo.example.com" "secretName" "foo-tls") }}
|
||||
*/}}
|
||||
{{/*
|
||||
Shared environment variables for Authentik server and worker containers.
|
||||
*/}}
|
||||
{{- define "authentik.commonEnv" -}}
|
||||
- name: AUTHENTIK_REDIS__HOST
|
||||
value: {{ .Release.Name }}-authentik-redis
|
||||
- name: AUTHENTIK_POSTGRESQL__HOST
|
||||
value: {{ .Release.Name }}-authentik-postgres
|
||||
- name: AUTHENTIK_POSTGRESQL__USER
|
||||
value: authentik
|
||||
- name: AUTHENTIK_POSTGRESQL__NAME
|
||||
value: authentik
|
||||
- name: AUTHENTIK_POSTGRESQL__PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-authentik
|
||||
key: dbPassword
|
||||
- name: AUTHENTIK_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-authentik
|
||||
key: secretKey
|
||||
- name: AUTHENTIK_ERROR_REPORTING__ENABLED
|
||||
value: "false"
|
||||
{{- end }}
|
||||
|
||||
{{- define "sovereign.ingressTLS" -}}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .host }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,275 @@
|
||||
{{- if .Values.authentik.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# AUTHENTIK — PostgreSQL + Redis + Server + Worker
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-postgres
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.authentik.persistence.postgresSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-media
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.authentik.persistence.mediaSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-certs
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.authentik.persistence.certsSize }}
|
||||
---
|
||||
# --- PostgreSQL ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-postgres
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: authentik-postgres
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-postgres") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-postgres") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: authentik
|
||||
- name: POSTGRES_DB
|
||||
value: authentik
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-authentik
|
||||
key: dbPassword
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: [sh, -c, "pg_isready -d authentik -U authentik"]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-authentik-postgres
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-postgres
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-postgres") | nindent 4 }}
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
---
|
||||
# --- Redis ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-redis
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: authentik-redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-redis") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-redis") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:alpine
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: [redis-cli, ping]
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-redis
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-redis") | nindent 4 }}
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
---
|
||||
# --- Authentik Server ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-server
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: authentik-server
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-server") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-server") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: server
|
||||
image: ghcr.io/goauthentik/server:{{ .Values.authentik.version }}
|
||||
command: [server]
|
||||
env:
|
||||
{{- include "authentik.commonEnv" . | nindent 12 }}
|
||||
- name: AUTHENTIK_EMAIL__HOST
|
||||
value: {{ include "sovereign.smtpHost" . | quote }}
|
||||
- name: AUTHENTIK_EMAIL__PORT
|
||||
value: {{ .Values.smtp.port | quote }}
|
||||
- name: AUTHENTIK_EMAIL__USERNAME
|
||||
value: {{ include "sovereign.smtpUser" . | quote }}
|
||||
- name: AUTHENTIK_EMAIL__FROM
|
||||
value: {{ include "sovereign.smtpFrom" . | quote }}
|
||||
- name: AUTHENTIK_EMAIL__USE_TLS
|
||||
value: "true"
|
||||
- name: AUTHENTIK_EMAIL__PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-smtp
|
||||
key: password
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 9000
|
||||
volumeMounts:
|
||||
- name: media
|
||||
mountPath: /media
|
||||
- name: certs
|
||||
mountPath: /certs
|
||||
volumes:
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-authentik-media
|
||||
- name: certs
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-authentik-certs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-server
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-server") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 9000
|
||||
targetPort: http
|
||||
---
|
||||
# --- Authentik Worker ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik-worker
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: authentik-worker
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-worker") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "authentik-worker") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: worker
|
||||
image: ghcr.io/goauthentik/server:{{ .Values.authentik.version }}
|
||||
command: [worker]
|
||||
env:
|
||||
{{- include "authentik.commonEnv" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: media
|
||||
mountPath: /media
|
||||
- name: certs
|
||||
mountPath: /certs
|
||||
volumes:
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-authentik-media
|
||||
- name: certs
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-authentik-certs
|
||||
---
|
||||
# --- Ingress ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: auth.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-authentik-server
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- auth.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-authentik-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,246 @@
|
||||
{{- if .Values.forgejo.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# FORGEJO — PostgreSQL + Forgejo Git
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.forgejo.persistence.dbSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.forgejo.persistence.dataSize }}
|
||||
---
|
||||
# --- PostgreSQL ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: forgejo-db
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo-db") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo-db") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: forgejo
|
||||
- name: POSTGRES_USER
|
||||
value: forgejo
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
key: dbPassword
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-forgejo-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo-db") | nindent 4 }}
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
---
|
||||
# --- Forgejo ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: forgejo
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo") | nindent 8 }}
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- name: forgejo
|
||||
image: codeberg.org/forgejo/forgejo:{{ .Values.forgejo.version }}
|
||||
env:
|
||||
- name: FORGEJO__database__DB_TYPE
|
||||
value: postgres
|
||||
- name: FORGEJO__database__HOST
|
||||
value: {{ .Release.Name }}-forgejo-db:5432
|
||||
- name: FORGEJO__database__NAME
|
||||
value: forgejo
|
||||
- name: FORGEJO__database__USER
|
||||
value: forgejo
|
||||
- name: FORGEJO__server__DOMAIN
|
||||
value: git.{{ .Values.global.baseDomain }}
|
||||
- name: FORGEJO__server__ROOT_URL
|
||||
value: https://git.{{ .Values.global.baseDomain }}
|
||||
- name: FORGEJO__server__SSH_DOMAIN
|
||||
value: git.{{ .Values.global.baseDomain }}
|
||||
- name: FORGEJO__server__SSH_PORT
|
||||
value: {{ .Values.forgejo.sshPort | quote }}
|
||||
- name: FORGEJO__server__SSH_LISTEN_PORT
|
||||
value: "22"
|
||||
- name: FORGEJO__mailer__ENABLED
|
||||
value: "true"
|
||||
- name: FORGEJO__mailer__SMTP_ADDR
|
||||
value: {{ include "sovereign.smtpHost" . | quote }}
|
||||
- name: FORGEJO__mailer__SMTP_PORT
|
||||
value: {{ .Values.smtp.port | quote }}
|
||||
- name: FORGEJO__mailer__FROM
|
||||
value: {{ include "sovereign.smtpFrom" . | quote }}
|
||||
- name: FORGEJO__mailer__USER
|
||||
value: {{ include "sovereign.smtpUser" . | quote }}
|
||||
- name: FORGEJO__openid__ENABLE_OPENID_SIGNIN
|
||||
value: "true"
|
||||
- name: FORGEJO__openid__ENABLE_OPENID_SIGNUP
|
||||
value: "false"
|
||||
- name: FORGEJO__oauth2_client__REGISTER_EMAIL_CONFIRM
|
||||
value: "false"
|
||||
- name: FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION
|
||||
value: "true"
|
||||
- name: FORGEJO____APP_NAME
|
||||
value: {{ .Values.global.tenantName | quote }}
|
||||
- name: FORGEJO__log__LEVEL
|
||||
value: warn
|
||||
- name: FORGEJO__database__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
key: dbPassword
|
||||
- name: FORGEJO__security__SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
key: secretKey
|
||||
- name: FORGEJO__security__INTERNAL_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
key: internalToken
|
||||
- name: FORGEJO__lfs__JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
key: lfsJwtSecret
|
||||
- name: FORGEJO__mailer__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-smtp
|
||||
key: password
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 3000
|
||||
- name: ssh
|
||||
containerPort: 22
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-forgejo-data
|
||||
---
|
||||
# HTTP service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
targetPort: http
|
||||
---
|
||||
# SSH service (NodePort on the configured sshPort)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo-ssh
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "forgejo") | nindent 4 }}
|
||||
ports:
|
||||
- name: ssh
|
||||
port: {{ .Values.forgejo.sshPort }}
|
||||
targetPort: ssh
|
||||
nodePort: {{ .Values.forgejo.sshPort }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: git.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- git.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-forgejo-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,262 @@
|
||||
{{- if .Values.graylog.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# GRAYLOG — MongoDB + OpenSearch + Graylog
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-mongodb
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.graylog.persistence.mongodbSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-opensearch
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.graylog.persistence.opensearchSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.graylog.persistence.graylogSize }}
|
||||
---
|
||||
# --- MongoDB ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-mongodb
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: graylog-mongodb
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-mongodb") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-mongodb") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: mongodb
|
||||
image: mongo:{{ .Values.graylog.mongodbVersion }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data/db
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-graylog-mongodb
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-mongodb
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-mongodb") | nindent 4 }}
|
||||
ports:
|
||||
- port: 27017
|
||||
targetPort: 27017
|
||||
---
|
||||
# --- OpenSearch ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-opensearch
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: graylog-opensearch
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-opensearch") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-opensearch") | nindent 8 }}
|
||||
spec:
|
||||
initContainers:
|
||||
- name: sysctl
|
||||
image: busybox
|
||||
command: ["sysctl", "-w", "vm.max_map_count=262144"]
|
||||
securityContext:
|
||||
privileged: true
|
||||
containers:
|
||||
- name: opensearch
|
||||
image: opensearchproject/opensearch:{{ .Values.graylog.opensearchVersion }}
|
||||
env:
|
||||
- name: OPENSEARCH_JAVA_OPTS
|
||||
value: {{ .Values.graylog.opensearchJavaOpts | quote }}
|
||||
- name: bootstrap.memory_lock
|
||||
value: "true"
|
||||
- name: discovery.type
|
||||
value: single-node
|
||||
- name: action.auto_create_index
|
||||
value: "false"
|
||||
- name: plugins.security.ssl.http.enabled
|
||||
value: "false"
|
||||
- name: plugins.security.disabled
|
||||
value: "true"
|
||||
- name: OPENSEARCH_INITIAL_ADMIN_PASSWORD
|
||||
value: "changeme_os_admin"
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: [IPC_LOCK]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/share/opensearch/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-graylog-opensearch
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog-opensearch
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog-opensearch") | nindent 4 }}
|
||||
ports:
|
||||
- port: 9200
|
||||
targetPort: 9200
|
||||
---
|
||||
# --- Graylog ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: graylog
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: graylog
|
||||
image: graylog/graylog:{{ .Values.graylog.version }}
|
||||
env:
|
||||
- name: GRAYLOG_NODE_ID_FILE
|
||||
value: /usr/share/graylog/data/config/node-id
|
||||
- name: GRAYLOG_HTTP_BIND_ADDRESS
|
||||
value: "0.0.0.0:9000"
|
||||
- name: GRAYLOG_ELASTICSEARCH_HOSTS
|
||||
value: http://{{ .Release.Name }}-graylog-opensearch:9200
|
||||
- name: GRAYLOG_MONGODB_URI
|
||||
value: mongodb://{{ .Release.Name }}-graylog-mongodb:27017/graylog
|
||||
- name: GRAYLOG_HTTP_EXTERNAL_URI
|
||||
value: https://logs.{{ .Values.global.baseDomain }}/
|
||||
- name: GRAYLOG_TRANSPORT_EMAIL_ENABLED
|
||||
value: "true"
|
||||
- name: GRAYLOG_TRANSPORT_EMAIL_HOSTNAME
|
||||
value: {{ include "sovereign.smtpHost" . | quote }}
|
||||
- name: GRAYLOG_TRANSPORT_EMAIL_PORT
|
||||
value: {{ .Values.smtp.port | quote }}
|
||||
- name: GRAYLOG_TRANSPORT_EMAIL_FROM_EMAIL
|
||||
value: {{ include "sovereign.smtpFrom" . | quote }}
|
||||
- name: GRAYLOG_PASSWORD_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
key: passwordSecret
|
||||
- name: GRAYLOG_ROOT_PASSWORD_SHA2
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
key: rootPasswordSha2
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 9000
|
||||
- name: gelf-udp
|
||||
containerPort: 12201
|
||||
protocol: UDP
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/share/graylog/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-graylog-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "graylog") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 9000
|
||||
targetPort: http
|
||||
- name: gelf-udp
|
||||
port: {{ .Values.graylog.gelfPort }}
|
||||
targetPort: gelf-udp
|
||||
protocol: UDP
|
||||
---
|
||||
# --- Ingress ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: logs.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- logs.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-graylog-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,189 @@
|
||||
{{- if .Values.headscale.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# HEADSCALE — WireGuard mesh VPN coordinator
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# ConfigMap: base headscale config
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale-config
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |
|
||||
server_url: "https://headscale.{{ .Values.global.baseDomain }}"
|
||||
listen_addr: "0.0.0.0:8080"
|
||||
grpc_listen_addr: "0.0.0.0:50443"
|
||||
grpc_allow_insecure: true
|
||||
private_key_path: /var/lib/headscale/private.key
|
||||
noise:
|
||||
private_key_path: /var/lib/headscale/noise_private.key
|
||||
ip_prefixes:
|
||||
- 100.64.0.0/10
|
||||
derp:
|
||||
server:
|
||||
enabled: false
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
auto_update_enabled: true
|
||||
update_frequency: 24h
|
||||
disable_check_updates: true
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
db_type: sqlite3
|
||||
db_path: /var/lib/headscale/db.sqlite
|
||||
log:
|
||||
level: warn
|
||||
acls_path: /etc/headscale/acls.hujson
|
||||
oidc:
|
||||
issuer: "{{ include "sovereign.authentikURL" . }}/application/o/headscale/"
|
||||
client_id: headscale
|
||||
client_secret: "changeme_headscale_oidc_secret"
|
||||
scope: [openid, profile, email]
|
||||
strip_email_domain: true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale-config
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.headscale.persistence.configSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.headscale.persistence.dataSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: headscale
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "headscale") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "headscale") | nindent 8 }}
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init-config
|
||||
image: busybox
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if [ ! -f /etc/headscale/config.yaml ]; then
|
||||
cp /configmap/config.yaml /etc/headscale/config.yaml
|
||||
fi
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/headscale
|
||||
- name: configmap
|
||||
mountPath: /configmap
|
||||
containers:
|
||||
- name: headscale
|
||||
image: headscale/headscale:{{ .Values.headscale.version }}
|
||||
command: [serve]
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
- name: grpc
|
||||
containerPort: 50443
|
||||
- name: wireguard
|
||||
containerPort: {{ .Values.headscale.wireguardPort }}
|
||||
protocol: UDP
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/headscale
|
||||
- name: data
|
||||
mountPath: /var/lib/headscale
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-headscale-config
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-headscale-data
|
||||
- name: configmap
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-headscale-config
|
||||
---
|
||||
# HTTP service (for Ingress)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "headscale") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
---
|
||||
# WireGuard UDP service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale-vpn
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "headscale") | nindent 4 }}
|
||||
ports:
|
||||
- name: wireguard
|
||||
port: {{ .Values.headscale.wireguardPort }}
|
||||
targetPort: wireguard
|
||||
nodePort: {{ .Values.headscale.wireguardPort }}
|
||||
protocol: UDP
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-headscale
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: headscale.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-headscale
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- headscale.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-headscale-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,362 @@
|
||||
{{- if .Values.jitsi.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# JITSI MEET — Web + Prosody + Jicofo + JVB
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
{{- range list "web" "prosody" "jicofo" "jvb" }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ $.Release.Name }}-jitsi-{{ . }}
|
||||
labels:
|
||||
{{- include "sovereign.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" $.Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ index $.Values.jitsi.persistence (printf "%sSize" .) }}
|
||||
---
|
||||
{{- end }}
|
||||
|
||||
# --- Prosody (XMPP) ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-prosody
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: jitsi-prosody
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-prosody") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-prosody") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: prosody
|
||||
image: jitsi/prosody:{{ .Values.jitsi.version }}
|
||||
env:
|
||||
- name: XMPP_DOMAIN
|
||||
value: meet.jitsi
|
||||
- name: XMPP_AUTH_DOMAIN
|
||||
value: auth.meet.jitsi
|
||||
- name: XMPP_MUC_DOMAIN
|
||||
value: muc.meet.jitsi
|
||||
- name: XMPP_INTERNAL_MUC_DOMAIN
|
||||
value: internal-muc.meet.jitsi
|
||||
- name: XMPP_RECORDER_DOMAIN
|
||||
value: recorder.meet.jitsi
|
||||
- name: JICOFO_AUTH_USER
|
||||
value: focus
|
||||
- name: JVB_AUTH_USER
|
||||
value: jvb
|
||||
- name: JIBRI_RECORDER_USER
|
||||
value: recorder
|
||||
- name: JIBRI_XMPP_USER
|
||||
value: jibri
|
||||
- name: JWT_APP_ID
|
||||
value: jitsi
|
||||
- name: ENABLE_AUTH
|
||||
value: "1"
|
||||
- name: ENABLE_GUESTS
|
||||
value: "1"
|
||||
- name: AUTH_TYPE
|
||||
value: jwt
|
||||
- name: TZ
|
||||
value: UTC
|
||||
- name: JICOFO_AUTH_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jicofoAuthPassword
|
||||
- name: JVB_AUTH_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jvbAuthPassword
|
||||
- name: JIBRI_RECORDER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jibriRecorderPassword
|
||||
- name: JIBRI_XMPP_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jibriXmppPassword
|
||||
- name: JWT_APP_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: turnSecret
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-jitsi-prosody
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-prosody
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-prosody") | nindent 4 }}
|
||||
ports:
|
||||
- name: xmpp-c2s
|
||||
port: 5222
|
||||
targetPort: 5222
|
||||
- name: xmpp-s2s
|
||||
port: 5269
|
||||
targetPort: 5269
|
||||
- name: bosh
|
||||
port: 5280
|
||||
targetPort: 5280
|
||||
- name: xmpp-component
|
||||
port: 5347
|
||||
targetPort: 5347
|
||||
---
|
||||
# --- Jicofo ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-jicofo
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: jitsi-jicofo
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-jicofo") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-jicofo") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: jicofo
|
||||
image: jitsi/jicofo:{{ .Values.jitsi.version }}
|
||||
env:
|
||||
- name: XMPP_SERVER
|
||||
value: {{ .Release.Name }}-jitsi-prosody
|
||||
- name: XMPP_DOMAIN
|
||||
value: meet.jitsi
|
||||
- name: XMPP_AUTH_DOMAIN
|
||||
value: auth.meet.jitsi
|
||||
- name: XMPP_INTERNAL_MUC_DOMAIN
|
||||
value: internal-muc.meet.jitsi
|
||||
- name: JICOFO_AUTH_USER
|
||||
value: focus
|
||||
- name: JVB_BREWERY_MUC
|
||||
value: jvbbrewery
|
||||
- name: TZ
|
||||
value: UTC
|
||||
- name: JICOFO_AUTH_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jicofoAuthPassword
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-jitsi-jicofo
|
||||
---
|
||||
# --- JVB (video bridge) ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-jvb
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: jitsi-jvb
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-jvb") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-jvb") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: jvb
|
||||
image: jitsi/jvb:{{ .Values.jitsi.version }}
|
||||
env:
|
||||
- name: XMPP_SERVER
|
||||
value: {{ .Release.Name }}-jitsi-prosody
|
||||
- name: XMPP_DOMAIN
|
||||
value: meet.jitsi
|
||||
- name: XMPP_AUTH_DOMAIN
|
||||
value: auth.meet.jitsi
|
||||
- name: XMPP_INTERNAL_MUC_DOMAIN
|
||||
value: internal-muc.meet.jitsi
|
||||
- name: JVB_AUTH_USER
|
||||
value: jvb
|
||||
- name: JVB_BREWERY_MUC
|
||||
value: jvbbrewery
|
||||
- name: JVB_PORT
|
||||
value: "10000"
|
||||
- name: JVB_TCP_HARVESTER_DISABLED
|
||||
value: "true"
|
||||
- name: TZ
|
||||
value: UTC
|
||||
- name: JVB_AUTH_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: jvbAuthPassword
|
||||
ports:
|
||||
- name: jvb-udp
|
||||
containerPort: 10000
|
||||
protocol: UDP
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-jitsi-jvb
|
||||
---
|
||||
# JVB service — needs to be reachable by clients (UDP)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-jvb
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-jvb") | nindent 4 }}
|
||||
ports:
|
||||
- name: jvb-udp
|
||||
port: 10000
|
||||
targetPort: jvb-udp
|
||||
protocol: UDP
|
||||
---
|
||||
# --- Jitsi Web ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-web
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: jitsi-web
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-web") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-web") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: web
|
||||
image: jitsi/web:{{ .Values.jitsi.version }}
|
||||
env:
|
||||
- name: PUBLIC_URL
|
||||
value: https://meet.{{ .Values.global.baseDomain }}
|
||||
- name: JITSI_WATERMARKLINK
|
||||
value: https://{{ .Values.global.baseDomain }}
|
||||
- name: XMPP_SERVER
|
||||
value: {{ .Release.Name }}-jitsi-prosody
|
||||
- name: XMPP_DOMAIN
|
||||
value: meet.jitsi
|
||||
- name: XMPP_AUTH_DOMAIN
|
||||
value: auth.meet.jitsi
|
||||
- name: XMPP_INTERNAL_MUC_DOMAIN
|
||||
value: internal-muc.meet.jitsi
|
||||
- name: XMPP_MUC_DOMAIN
|
||||
value: muc.meet.jitsi
|
||||
- name: XMPP_BOSH_URL_BASE
|
||||
value: http://{{ .Release.Name }}-jitsi-prosody:5280
|
||||
- name: XMPP_RECORDER_DOMAIN
|
||||
value: recorder.meet.jitsi
|
||||
- name: ENABLE_AUTH
|
||||
value: "1"
|
||||
- name: ENABLE_GUESTS
|
||||
value: "1"
|
||||
- name: AUTH_TYPE
|
||||
value: jwt
|
||||
- name: JWT_APP_ID
|
||||
value: jitsi
|
||||
- name: TZ
|
||||
value: UTC
|
||||
- name: JWT_APP_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: turnSecret
|
||||
- name: TURN_CREDENTIALS
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
key: turnSecret
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-jitsi-web
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi-web
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "jitsi-web") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: meet.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-jitsi-web
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- meet.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-jitsi-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,328 @@
|
||||
{{- if .Values.matrix.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# MATRIX / ELEMENT — PostgreSQL + Synapse + Element Web
|
||||
#
|
||||
# NOTE: Synapse requires a homeserver.yaml in its data volume.
|
||||
# On first run, exec into the synapse pod and run:
|
||||
# python -m synapse.app.homeserver --generate-config \
|
||||
# -H matrix.<baseDomain> --report-stats=no \
|
||||
# -c /data/homeserver.yaml
|
||||
# Or provide your own via the configMap below.
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# ConfigMap: basic homeserver.yaml — customize before deploying
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-synapse-config
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
data:
|
||||
homeserver.yaml: |
|
||||
server_name: "{{ .Values.global.baseDomain }}"
|
||||
public_baseurl: "https://matrix.{{ .Values.global.baseDomain }}"
|
||||
pid_file: /data/homeserver.pid
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
resources:
|
||||
- names: [client, federation]
|
||||
compress: false
|
||||
database:
|
||||
name: psycopg2
|
||||
args:
|
||||
user: synapse
|
||||
password: "<set via SYNAPSE_POSTGRES_PASSWORD env — see Deployment>"
|
||||
database: synapse
|
||||
host: {{ .Release.Name }}-matrix-db
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
log_config: "/data/log.config"
|
||||
media_store_path: /data/media_store
|
||||
registration_shared_secret: "<set via SYNAPSE_REGISTRATION_SHARED_SECRET env>"
|
||||
report_stats: false
|
||||
signing_key_path: "/data/{{ .Values.global.baseDomain }}.signing.key"
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
email:
|
||||
smtp_host: {{ include "sovereign.smtpHost" . | quote }}
|
||||
smtp_port: {{ .Values.smtp.port }}
|
||||
notif_from: "{{ include "sovereign.smtpFrom" . }}"
|
||||
|
||||
log.config: |
|
||||
version: 1
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
handlers:
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
level: WARNING
|
||||
root:
|
||||
level: WARNING
|
||||
handlers: [console]
|
||||
disable_existing_loggers: false
|
||||
|
||||
element-config.json: |
|
||||
{
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix.{{ .Values.global.baseDomain }}",
|
||||
"server_name": "{{ .Values.global.baseDomain }}"
|
||||
}
|
||||
},
|
||||
"brand": "{{ .Values.global.tenantName }}",
|
||||
"disable_guests": true,
|
||||
"room_directory": { "servers": ["{{ .Values.global.baseDomain }}"] }
|
||||
}
|
||||
---
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-matrix-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.matrix.persistence.dbSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-synapse-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.matrix.persistence.synapseSize }}
|
||||
---
|
||||
# --- PostgreSQL ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-matrix-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: matrix-db
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "matrix-db") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "matrix-db") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: synapse
|
||||
- name: POSTGRES_DB
|
||||
value: synapse
|
||||
- name: POSTGRES_INITDB_ARGS
|
||||
value: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-matrix
|
||||
key: dbPassword
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-matrix-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-matrix-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "matrix-db") | nindent 4 }}
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
---
|
||||
# --- Synapse ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-synapse
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: synapse
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "synapse") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "synapse") | nindent 8 }}
|
||||
spec:
|
||||
initContainers:
|
||||
# Copy config from ConfigMap into writable data volume on first run
|
||||
- name: init-config
|
||||
image: busybox
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if [ ! -f /data/homeserver.yaml ]; then
|
||||
cp /config/homeserver.yaml /data/homeserver.yaml
|
||||
cp /config/log.config /data/log.config
|
||||
fi
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
- name: config
|
||||
mountPath: /config
|
||||
containers:
|
||||
- name: synapse
|
||||
image: ghcr.io/element-hq/synapse:{{ .Values.matrix.synapseVersion }}
|
||||
env:
|
||||
- name: SYNAPSE_CONFIG_PATH
|
||||
value: /data/homeserver.yaml
|
||||
- name: SYNAPSE_POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-matrix
|
||||
key: dbPassword
|
||||
- name: SYNAPSE_REGISTRATION_SHARED_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-matrix
|
||||
key: registrationSecret
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8008
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-synapse-data
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-synapse-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-synapse
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "synapse") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8008
|
||||
targetPort: http
|
||||
---
|
||||
# --- Element Web ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-element
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: element
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "element") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "element") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: element
|
||||
image: vectorim/element-web:latest
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config.json
|
||||
subPath: element-config.json
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-synapse-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-element
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "element") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
# --- Ingress (matrix + chat subdomains) ---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-matrix
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: matrix.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-synapse
|
||||
port:
|
||||
name: http
|
||||
- host: chat.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-element
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- matrix.{{ .Values.global.baseDomain }}
|
||||
- chat.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-matrix-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,144 @@
|
||||
{{- if .Values.minio.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# MINIO — S3-compatible object storage
|
||||
# -------------------------------------------------------------------------
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.minio.persistence.size }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "minio") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "minio") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: minio
|
||||
image: quay.io/minio/minio:{{ .Values.minio.version }}
|
||||
command: [server, /data, --console-address, ":9001"]
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
value: {{ .Values.minio.rootUser | quote }}
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: rootPassword
|
||||
- name: MINIO_BROWSER_REDIRECT_URL
|
||||
value: https://minio.{{ .Values.global.baseDomain }}
|
||||
- name: MINIO_IDENTITY_OPENID_CONFIG_URL
|
||||
value: {{ include "sovereign.authentikURL" . }}/application/o/minio/.well-known/openid-configuration
|
||||
- name: MINIO_IDENTITY_OPENID_CLIENT_ID
|
||||
value: minio
|
||||
- name: MINIO_IDENTITY_OPENID_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: oidcSecret
|
||||
- name: MINIO_IDENTITY_OPENID_CLAIM_NAME
|
||||
value: policy
|
||||
- name: MINIO_IDENTITY_OPENID_REDIRECT_URI
|
||||
value: https://minio.{{ .Values.global.baseDomain }}/oauth_callback
|
||||
ports:
|
||||
- name: api
|
||||
containerPort: 9000
|
||||
- name: console
|
||||
containerPort: 9001
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-minio
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "minio") | nindent 4 }}
|
||||
ports:
|
||||
- name: api
|
||||
port: 9000
|
||||
targetPort: api
|
||||
- name: console
|
||||
port: 9001
|
||||
targetPort: console
|
||||
---
|
||||
# Two Ingresses: API (s3.<domain>) and Console (minio.<domain>)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio-api
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: s3.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-minio
|
||||
port:
|
||||
name: api
|
||||
tls:
|
||||
- hosts:
|
||||
- s3.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-minio-api-tls
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio-console
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: minio.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-minio
|
||||
port:
|
||||
name: console
|
||||
tls:
|
||||
- hosts:
|
||||
- minio.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-minio-console-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,292 @@
|
||||
{{- if .Values.nextcloud.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# NEXTCLOUD — MariaDB + Redis + Nextcloud + Cron
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.nextcloud.persistence.dbSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.nextcloud.persistence.dataSize }}
|
||||
---
|
||||
# --- MariaDB ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: nextcloud-db
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-db") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-db") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: mariadb
|
||||
image: mariadb:10.11
|
||||
args:
|
||||
- --transaction-isolation=READ-COMMITTED
|
||||
- --log-bin=binlog
|
||||
- --binlog-format=ROW
|
||||
env:
|
||||
- name: MYSQL_DATABASE
|
||||
value: nextcloud
|
||||
- name: MYSQL_USER
|
||||
value: nextcloud
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
key: dbRootPassword
|
||||
- name: MYSQL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
key: dbPassword
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-nextcloud-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-db") | nindent 4 }}
|
||||
ports:
|
||||
- port: 3306
|
||||
targetPort: 3306
|
||||
---
|
||||
# --- Redis ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-redis
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: nextcloud-redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-redis") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-redis") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:alpine
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-redis
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-redis") | nindent 4 }}
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
---
|
||||
# --- Nextcloud ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: nextcloud
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: nextcloud
|
||||
image: nextcloud:{{ .Values.nextcloud.version }}
|
||||
env:
|
||||
- name: MYSQL_HOST
|
||||
value: {{ .Release.Name }}-nextcloud-db
|
||||
- name: MYSQL_DATABASE
|
||||
value: nextcloud
|
||||
- name: MYSQL_USER
|
||||
value: nextcloud
|
||||
- name: MYSQL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
key: dbPassword
|
||||
- name: REDIS_HOST
|
||||
value: {{ .Release.Name }}-nextcloud-redis
|
||||
- name: NEXTCLOUD_ADMIN_USER
|
||||
value: {{ .Values.nextcloud.adminUser | quote }}
|
||||
- name: NEXTCLOUD_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
key: adminPassword
|
||||
- name: NEXTCLOUD_TRUSTED_DOMAINS
|
||||
value: cloud.{{ .Values.global.baseDomain }}
|
||||
- name: OVERWRITEPROTOCOL
|
||||
value: https
|
||||
- name: OVERWRITECLIURL
|
||||
value: https://cloud.{{ .Values.global.baseDomain }}
|
||||
- name: SMTP_HOST
|
||||
value: {{ include "sovereign.smtpHost" . | quote }}
|
||||
- name: SMTP_PORT
|
||||
value: {{ .Values.smtp.port | quote }}
|
||||
- name: SMTP_NAME
|
||||
value: {{ include "sovereign.smtpUser" . | quote }}
|
||||
- name: SMTP_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-smtp
|
||||
key: password
|
||||
- name: MAIL_FROM_ADDRESS
|
||||
value: noreply
|
||||
- name: MAIL_DOMAIN
|
||||
value: {{ .Values.global.baseDomain | quote }}
|
||||
- name: OBJECTSTORE_S3_HOST
|
||||
value: {{ .Release.Name }}-minio
|
||||
- name: OBJECTSTORE_S3_PORT
|
||||
value: "9000"
|
||||
- name: OBJECTSTORE_S3_SSL
|
||||
value: "false"
|
||||
- name: OBJECTSTORE_S3_BUCKET
|
||||
value: {{ .Values.minio.nextcloudBucket | quote }}
|
||||
- name: OBJECTSTORE_S3_KEY
|
||||
value: {{ .Values.minio.nextcloudAccessKey | quote }}
|
||||
- name: OBJECTSTORE_S3_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: nextcloudSecretKey
|
||||
- name: OBJECTSTORE_S3_USEPATH_STYLE
|
||||
value: "true"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-nextcloud-data
|
||||
---
|
||||
# Cron sidecar deployment
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud-cron
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: nextcloud-cron
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-cron") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud-cron") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: cron
|
||||
image: nextcloud:{{ .Values.nextcloud.version }}
|
||||
command: [/cron.sh]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-nextcloud-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "nextcloud") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
# CardDAV / CalDAV redirect
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /remote.php/dav
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: cloud.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- cloud.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-nextcloud-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,187 @@
|
||||
{{- if .Values.roundcube.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# ROUNDCUBE — PostgreSQL + Roundcube webmail
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# ConfigMap for custom.inc.php overrides
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube-config
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
data:
|
||||
custom.inc.php: |
|
||||
<?php
|
||||
// Additional Roundcube configuration overrides.
|
||||
// Add site-specific settings here.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.roundcube.persistence.dbSize }}
|
||||
---
|
||||
# --- PostgreSQL ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: roundcube-db
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube-db") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube-db") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: roundcube
|
||||
- name: POSTGRES_USER
|
||||
value: roundcube
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
key: dbPassword
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-roundcube-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube-db") | nindent 4 }}
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
---
|
||||
# --- Roundcube ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: roundcube
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: roundcube
|
||||
image: roundcube/roundcubemail:{{ .Values.roundcube.version }}
|
||||
env:
|
||||
- name: ROUNDCUBEMAIL_DB_TYPE
|
||||
value: pgsql
|
||||
- name: ROUNDCUBEMAIL_DB_HOST
|
||||
value: {{ .Release.Name }}-roundcube-db
|
||||
- name: ROUNDCUBEMAIL_DB_NAME
|
||||
value: roundcube
|
||||
- name: ROUNDCUBEMAIL_DB_USER
|
||||
value: roundcube
|
||||
- name: ROUNDCUBEMAIL_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
key: dbPassword
|
||||
- name: ROUNDCUBEMAIL_DEFAULT_HOST
|
||||
value: ssl://{{ .Release.Name }}-stalwart
|
||||
- name: ROUNDCUBEMAIL_DEFAULT_PORT
|
||||
value: "993"
|
||||
- name: ROUNDCUBEMAIL_SMTP_SERVER
|
||||
value: tls://{{ .Release.Name }}-stalwart
|
||||
- name: ROUNDCUBEMAIL_SMTP_PORT
|
||||
value: "587"
|
||||
- name: ROUNDCUBEMAIL_DES_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
key: desKey
|
||||
- name: ROUNDCUBEMAIL_PLUGINS
|
||||
value: "archive,zipdownload,managesieve,jqueryui"
|
||||
- name: ROUNDCUBEMAIL_SKIN
|
||||
value: {{ .Values.roundcube.skin | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /var/roundcube/config/custom.inc.php
|
||||
subPath: custom.inc.php
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-roundcube-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "roundcube") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: webmail.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- webmail.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-roundcube-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,179 @@
|
||||
{{/* -----------------------------------------------------------------------
|
||||
One Secret per service, containing only the credentials that service needs.
|
||||
Reference these in Deployments with secretKeyRef.
|
||||
----------------------------------------------------------------------- */}}
|
||||
|
||||
# -- Shared SMTP credentials (referenced by multiple services)
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-smtp
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
password: {{ .Values.smtp.password | quote }}
|
||||
---
|
||||
{{- if .Values.traefik.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
dashboardPassword: {{ .Values.traefik.dashboardPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.graylog.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-graylog
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
passwordSecret: {{ .Values.graylog.passwordSecret | quote }}
|
||||
rootPasswordSha2: {{ .Values.graylog.rootPasswordSha2 | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.authentik.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-authentik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
secretKey: {{ .Values.authentik.secretKey | quote }}
|
||||
dbPassword: {{ .Values.authentik.dbPassword | quote }}
|
||||
adminPassword: {{ .Values.authentik.adminPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.minio.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
rootPassword: {{ .Values.minio.rootPassword | quote }}
|
||||
oidcSecret: {{ .Values.minio.oidcSecret | quote }}
|
||||
nextcloudSecretKey: {{ .Values.minio.nextcloudSecretKey | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.nextcloud.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-nextcloud
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
adminPassword: {{ .Values.nextcloud.adminPassword | quote }}
|
||||
dbPassword: {{ .Values.nextcloud.dbPassword | quote }}
|
||||
dbRootPassword: {{ .Values.nextcloud.dbRootPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.stalwart.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
adminPassword: {{ .Values.stalwart.adminPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.roundcube.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-roundcube
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
dbPassword: {{ .Values.roundcube.dbPassword | quote }}
|
||||
desKey: {{ .Values.roundcube.desKey | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.matrix.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-matrix
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
registrationSecret: {{ .Values.matrix.registrationSecret | quote }}
|
||||
dbPassword: {{ .Values.matrix.dbPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.jitsi.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-jitsi
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
jicofoAuthPassword: {{ .Values.jitsi.jicofoAuthPassword | quote }}
|
||||
jvbAuthPassword: {{ .Values.jitsi.jvbAuthPassword | quote }}
|
||||
jibriRecorderPassword: {{ .Values.jitsi.jibriRecorderPassword | quote }}
|
||||
jibriXmppPassword: {{ .Values.jitsi.jibriXmppPassword | quote }}
|
||||
turnSecret: {{ .Values.jitsi.turnSecret | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.wazuh.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
adminPassword: {{ .Values.wazuh.adminPassword | quote }}
|
||||
apiPassword: {{ .Values.wazuh.apiPassword | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.vaultwarden.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
adminToken: {{ .Values.vaultwarden.adminToken | quote }}
|
||||
dbPassword: {{ .Values.vaultwarden.dbPassword | quote }}
|
||||
oidcSecret: {{ .Values.vaultwarden.oidcSecret | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- if .Values.forgejo.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-forgejo
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
dbPassword: {{ .Values.forgejo.dbPassword | quote }}
|
||||
secretKey: {{ .Values.forgejo.secretKey | quote }}
|
||||
internalToken: {{ .Values.forgejo.internalToken | quote }}
|
||||
lfsJwtSecret: {{ .Values.forgejo.lfsJwtSecret | quote }}
|
||||
adminPassword: {{ .Values.forgejo.adminPassword | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,133 @@
|
||||
{{- if .Values.stalwart.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# STALWART MAIL — SMTP/IMAP mail server
|
||||
# -------------------------------------------------------------------------
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.stalwart.persistence.size }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: stalwart
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "stalwart") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "stalwart") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: stalwart
|
||||
image: stalwartlabs/mail-server:{{ .Values.stalwart.version }}
|
||||
env:
|
||||
- name: TZ
|
||||
value: UTC
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
- name: smtp
|
||||
containerPort: 25
|
||||
- name: smtps
|
||||
containerPort: 465
|
||||
- name: submission
|
||||
containerPort: 587
|
||||
- name: imaps
|
||||
containerPort: 993
|
||||
- name: sieve
|
||||
containerPort: 4190
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /opt/stalwart-mail
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-stalwart
|
||||
---
|
||||
# HTTP service for the web admin UI (via Ingress)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "stalwart") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
- name: smtp
|
||||
port: 587
|
||||
targetPort: submission
|
||||
---
|
||||
# Mail service — LoadBalancer or NodePort to expose raw TCP/UDP mail ports
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart-mail
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.stalwart.mailServiceType }}
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "stalwart") | nindent 4 }}
|
||||
ports:
|
||||
- name: smtp
|
||||
port: 25
|
||||
targetPort: smtp
|
||||
- name: smtps
|
||||
port: 465
|
||||
targetPort: smtps
|
||||
- name: submission
|
||||
port: 587
|
||||
targetPort: submission
|
||||
- name: imaps
|
||||
port: 993
|
||||
targetPort: imaps
|
||||
- name: sieve
|
||||
port: 4190
|
||||
targetPort: sieve
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: mail.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-stalwart
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- mail.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-stalwart-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,165 @@
|
||||
{{- if .Values.traefik.enabled }}
|
||||
# ServiceAccount
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
---
|
||||
# ClusterRole — allow Traefik to watch Ingress / Service / Endpoint resources
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: [services, endpoints, secrets]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [networking.k8s.io]
|
||||
resources: [ingresses, ingressclasses]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [networking.k8s.io]
|
||||
resources: [ingresses/status]
|
||||
verbs: [update]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ .Release.Name }}-traefik
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-traefik
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
# IngressClass
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
controller: traefik.io/ingress-controller
|
||||
---
|
||||
# Deployment
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: traefik
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "traefik") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "traefik") | nindent 8 }}
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-traefik
|
||||
containers:
|
||||
- name: traefik
|
||||
image: traefik:{{ .Values.traefik.version }}
|
||||
args:
|
||||
- "--api.dashboard=true"
|
||||
- "--providers.kubernetesingress=true"
|
||||
- "--providers.kubernetesingress.ingressclass=traefik"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
||||
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.letsencrypt.acme.email={{ include "sovereign.acmeEmail" . }}"
|
||||
- "--certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json"
|
||||
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
|
||||
- "--log.level=INFO"
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: 80
|
||||
- name: websecure
|
||||
containerPort: 443
|
||||
- name: dashboard
|
||||
containerPort: 8080
|
||||
volumeMounts:
|
||||
- name: acme
|
||||
mountPath: /acme
|
||||
env:
|
||||
- name: TRAEFIK_API_DASHBOARD
|
||||
value: "true"
|
||||
volumes:
|
||||
- name: acme
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-traefik-acme
|
||||
---
|
||||
# PVC for ACME certificate storage
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik-acme
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: 128Mi
|
||||
---
|
||||
# Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.traefik.service.type }}
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "traefik") | nindent 4 }}
|
||||
ports:
|
||||
- name: web
|
||||
port: 80
|
||||
targetPort: web
|
||||
- name: websecure
|
||||
port: 443
|
||||
targetPort: websecure
|
||||
---
|
||||
# Dashboard Ingress (protected by basic auth via Traefik middleware annotation)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-traefik-dashboard
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-{{ .Release.Name }}-traefik-auth@kubernetescrd"
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: traefik.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-traefik
|
||||
port:
|
||||
name: dashboard
|
||||
tls:
|
||||
- hosts:
|
||||
- traefik.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-traefik-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,203 @@
|
||||
{{- if .Values.vaultwarden.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# VAULTWARDEN — PostgreSQL + Vaultwarden
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.vaultwarden.persistence.dbSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden-data
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.vaultwarden.persistence.dataSize }}
|
||||
---
|
||||
# --- PostgreSQL ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vaultwarden-db
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden-db") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden-db") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: vaultwarden
|
||||
- name: POSTGRES_USER
|
||||
value: vaultwarden
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
key: dbPassword
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-vaultwarden-db
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden-db
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden-db") | nindent 4 }}
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
---
|
||||
# --- Vaultwarden ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vaultwarden
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: vaultwarden
|
||||
image: vaultwarden/server:{{ .Values.vaultwarden.version }}
|
||||
env:
|
||||
- name: DOMAIN
|
||||
value: https://vault.{{ .Values.global.baseDomain }}
|
||||
- name: SIGNUPS_ALLOWED
|
||||
value: "false"
|
||||
- name: SSO_ENABLED
|
||||
value: "true"
|
||||
- name: SSO_ONLY
|
||||
value: "false"
|
||||
- name: SSO_AUTHORITY
|
||||
value: {{ include "sovereign.authentikURL" . }}/application/o/vaultwarden/
|
||||
- name: SSO_CLIENT_ID
|
||||
value: vaultwarden
|
||||
- name: SMTP_HOST
|
||||
value: {{ include "sovereign.smtpHost" . | quote }}
|
||||
- name: SMTP_FROM
|
||||
value: {{ include "sovereign.smtpFrom" . | quote }}
|
||||
- name: SMTP_PORT
|
||||
value: {{ .Values.smtp.port | quote }}
|
||||
- name: SMTP_SECURITY
|
||||
value: {{ .Values.smtp.tls | quote }}
|
||||
- name: SMTP_USERNAME
|
||||
value: {{ include "sovereign.smtpUser" . | quote }}
|
||||
- name: LOG_LEVEL
|
||||
value: warn
|
||||
- name: DATABASE_URL
|
||||
value: postgresql://vaultwarden:$(VAULTWARDEN_DB_PASSWORD)@{{ .Release.Name }}-vaultwarden-db/vaultwarden
|
||||
- name: VAULTWARDEN_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
key: dbPassword
|
||||
- name: ADMIN_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
key: adminToken
|
||||
- name: SSO_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
key: oidcSecret
|
||||
- name: SMTP_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-smtp
|
||||
key: password
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-vaultwarden-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "vaultwarden") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: vault.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-vaultwarden
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- vault.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-vaultwarden-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,325 @@
|
||||
{{- if .Values.wazuh.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# WAZUH — Manager + Indexer + Dashboard
|
||||
#
|
||||
# IMPORTANT: Wazuh requires mutual TLS between its components.
|
||||
# Before deploying, generate certificates using the Wazuh cert tool and
|
||||
# create a Secret named <release>-wazuh-certs with these keys:
|
||||
#
|
||||
# root-ca.pem root-ca-manager.pem
|
||||
# wazuh.manager.pem wazuh.manager-key.pem
|
||||
# wazuh.indexer.pem wazuh.indexer.key
|
||||
# admin.pem admin-key.pem
|
||||
# wazuh.dashboard.pem wazuh.dashboard-key.pem
|
||||
#
|
||||
# Example:
|
||||
# kubectl create secret generic <release>-wazuh-certs \
|
||||
# --from-file=root-ca.pem=./certs/root-ca.pem \
|
||||
# ... (repeat for each cert)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# --- PVCs ---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-manager
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.wazuh.persistence.managerSize }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-indexer
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.wazuh.persistence.indexerSize }}
|
||||
---
|
||||
# --- Wazuh Indexer (OpenSearch-based) ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-indexer
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: wazuh-indexer
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-indexer") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-indexer") | nindent 8 }}
|
||||
spec:
|
||||
initContainers:
|
||||
- name: sysctl
|
||||
image: busybox
|
||||
command: ["sysctl", "-w", "vm.max_map_count=262144"]
|
||||
securityContext:
|
||||
privileged: true
|
||||
containers:
|
||||
- name: wazuh-indexer
|
||||
image: wazuh/wazuh-indexer:{{ .Values.wazuh.version }}
|
||||
env:
|
||||
- name: OPENSEARCH_JAVA_OPTS
|
||||
value: {{ .Values.wazuh.indexerJavaOpts | quote }}
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: [IPC_LOCK]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/wazuh-indexer
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-indexer/certs/root-ca.pem
|
||||
subPath: root-ca.pem
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-indexer/certs/wazuh.indexer.key
|
||||
subPath: wazuh.indexer.key
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-indexer/certs/wazuh.indexer.pem
|
||||
subPath: wazuh.indexer.pem
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-indexer/certs/admin.pem
|
||||
subPath: admin.pem
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-indexer/certs/admin-key.pem
|
||||
subPath: admin-key.pem
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-wazuh-indexer
|
||||
- name: certs
|
||||
secret:
|
||||
secretName: {{ .Release.Name }}-wazuh-certs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-indexer
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-indexer") | nindent 4 }}
|
||||
ports:
|
||||
- port: 9200
|
||||
targetPort: 9200
|
||||
---
|
||||
# --- Wazuh Manager ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-manager
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: wazuh-manager
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-manager") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-manager") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: wazuh-manager
|
||||
image: wazuh/wazuh-manager:{{ .Values.wazuh.version }}
|
||||
env:
|
||||
- name: INDEXER_URL
|
||||
value: https://{{ .Release.Name }}-wazuh-indexer:9200
|
||||
- name: INDEXER_USERNAME
|
||||
value: admin
|
||||
- name: FILEBEAT_SSL_VERIFICATION_MODE
|
||||
value: full
|
||||
- name: SSL_CERTIFICATE_AUTHORITIES
|
||||
value: /etc/ssl/root-ca.pem
|
||||
- name: SSL_CERTIFICATE
|
||||
value: /etc/ssl/filebeat.pem
|
||||
- name: SSL_KEY
|
||||
value: /etc/ssl/filebeat.key
|
||||
- name: API_USERNAME
|
||||
value: wazuh-wui
|
||||
- name: INDEXER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
key: adminPassword
|
||||
- name: API_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
key: apiPassword
|
||||
ports:
|
||||
- name: agent
|
||||
containerPort: 1514
|
||||
- name: enrollment
|
||||
containerPort: 1515
|
||||
- name: syslog
|
||||
containerPort: 514
|
||||
protocol: UDP
|
||||
- name: api
|
||||
containerPort: 55000
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/ossec/data
|
||||
- name: certs
|
||||
mountPath: /etc/ssl/root-ca.pem
|
||||
subPath: root-ca-manager.pem
|
||||
- name: certs
|
||||
mountPath: /etc/ssl/filebeat.pem
|
||||
subPath: wazuh.manager.pem
|
||||
- name: certs
|
||||
mountPath: /etc/ssl/filebeat.key
|
||||
subPath: wazuh.manager-key.pem
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-wazuh-manager
|
||||
- name: certs
|
||||
secret:
|
||||
secretName: {{ .Release.Name }}-wazuh-certs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-manager
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-manager") | nindent 4 }}
|
||||
ports:
|
||||
- name: agent
|
||||
port: 1514
|
||||
targetPort: agent
|
||||
- name: enrollment
|
||||
port: 1515
|
||||
targetPort: enrollment
|
||||
- name: syslog
|
||||
port: 514
|
||||
targetPort: syslog
|
||||
protocol: UDP
|
||||
- name: api
|
||||
port: 55000
|
||||
targetPort: api
|
||||
---
|
||||
# --- Wazuh Dashboard ---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-dashboard
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: wazuh-dashboard
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-dashboard") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-dashboard") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: wazuh-dashboard
|
||||
image: wazuh/wazuh-dashboard:{{ .Values.wazuh.version }}
|
||||
env:
|
||||
- name: INDEXER_USERNAME
|
||||
value: admin
|
||||
- name: WAZUH_API_URL
|
||||
value: https://{{ .Release.Name }}-wazuh-manager
|
||||
- name: DASHBOARD_USERNAME
|
||||
value: kibanaserver
|
||||
- name: API_USERNAME
|
||||
value: wazuh-wui
|
||||
- name: INDEXER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
key: adminPassword
|
||||
- name: DASHBOARD_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
key: adminPassword
|
||||
- name: API_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
key: apiPassword
|
||||
ports:
|
||||
- name: https
|
||||
containerPort: 5601
|
||||
volumeMounts:
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
|
||||
subPath: wazuh.dashboard.pem
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
|
||||
subPath: wazuh.dashboard-key.pem
|
||||
- name: certs
|
||||
mountPath: /usr/share/wazuh-dashboard/certs/root-ca.pem
|
||||
subPath: root-ca.pem
|
||||
volumes:
|
||||
- name: certs
|
||||
secret:
|
||||
secretName: {{ .Release.Name }}-wazuh-certs
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh-dashboard
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "wazuh-dashboard") | nindent 4 }}
|
||||
ports:
|
||||
- name: https
|
||||
port: 5601
|
||||
targetPort: https
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-wazuh
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
# Dashboard speaks HTTPS internally
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
traefik.ingress.kubernetes.io/service.serversscheme: "https"
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: wazuh.{{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-wazuh-dashboard
|
||||
port:
|
||||
name: https
|
||||
tls:
|
||||
- hosts:
|
||||
- wazuh.{{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-wazuh-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,89 @@
|
||||
{{- if .Values.website.enabled }}
|
||||
# -------------------------------------------------------------------------
|
||||
# WEBSITE — static site served by nginx
|
||||
# -------------------------------------------------------------------------
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-website-html
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
{{- include "sovereign.storageClass" .Values.global.storageClass | nindent 2 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.website.persistence.htmlSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-website
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: website
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "website") | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "website") | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:{{ .Values.website.nginxVersion }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: html
|
||||
mountPath: /usr/share/nginx/html
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: html
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-website-html
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-website
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
spec:
|
||||
selector:
|
||||
{{- include "sovereign.selectorLabels" (dict "root" . "component" "website") | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-website
|
||||
labels:
|
||||
{{- include "sovereign.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "sovereign.ingressAnnotations" . | nindent 4 }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.global.ingressClassName }}
|
||||
rules:
|
||||
- host: {{ .Values.global.baseDomain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ .Release.Name }}-website
|
||||
port:
|
||||
name: http
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.global.baseDomain }}
|
||||
secretName: {{ .Release.Name }}-website-tls
|
||||
{{- end }}
|
||||
@@ -0,0 +1,244 @@
|
||||
# =============================================================================
|
||||
# SOVEREIGN HELM VALUES
|
||||
# Mirrors the structure of inventories/production/group_vars/all.yml.
|
||||
# For a new deployment: copy this file, update baseDomain, and replace all
|
||||
# changeme_* values with secure secrets.
|
||||
# =============================================================================
|
||||
|
||||
# -- Global settings shared by all services
|
||||
global:
|
||||
# Base domain — all service subdomains derive from this
|
||||
baseDomain: "example.com"
|
||||
# Display name shown in service UIs and email subjects
|
||||
tenantName: "Example Corp"
|
||||
# Brand colours (hex)
|
||||
primaryColor: "#2563eb"
|
||||
accentColor: "#1e40af"
|
||||
# Kubernetes IngressClass name used for all Ingress resources
|
||||
ingressClassName: "traefik"
|
||||
# cert-manager ClusterIssuer name; leave empty to disable cert-manager integration
|
||||
clusterIssuer: ""
|
||||
# Default StorageClass for PVCs; empty string = cluster default
|
||||
storageClass: ""
|
||||
|
||||
# -- SMTP (shared across services that send email)
|
||||
smtp:
|
||||
# Service name or hostname for the SMTP server.
|
||||
# Defaults to the release-name-stalwart service when empty.
|
||||
host: ""
|
||||
port: 587
|
||||
# Sender address; defaults to noreply@<baseDomain> when empty
|
||||
from: ""
|
||||
# Login username; defaults to noreply@<baseDomain> when empty
|
||||
user: ""
|
||||
password: "changeme_smtp"
|
||||
# starttls | tls | plain
|
||||
tls: "starttls"
|
||||
|
||||
# =============================================================================
|
||||
# TRAEFIK — reverse proxy / ingress controller
|
||||
# Set enabled: false to use an existing ingress controller (nginx, etc.)
|
||||
# and still deploy all other services with standard Ingress resources.
|
||||
# =============================================================================
|
||||
traefik:
|
||||
enabled: true
|
||||
version: "v3.1"
|
||||
# ACME / Let's Encrypt email; defaults to admin@<baseDomain> when empty
|
||||
acmeEmail: ""
|
||||
# htpasswd-hashed password for the Traefik dashboard
|
||||
dashboardPassword: "changeme"
|
||||
service:
|
||||
# LoadBalancer | NodePort
|
||||
type: LoadBalancer
|
||||
|
||||
# =============================================================================
|
||||
# GRAYLOG — centralised logging (Graylog + OpenSearch + MongoDB)
|
||||
# =============================================================================
|
||||
graylog:
|
||||
enabled: true
|
||||
version: "6.0"
|
||||
opensearchVersion: "2.15.0"
|
||||
opensearchJavaOpts: "-Xms1g -Xmx1g"
|
||||
mongodbVersion: "6.0"
|
||||
# Minimum 16 characters
|
||||
passwordSecret: "changeme_graylog_secret_min_16_chars"
|
||||
# sha256 of the root password: echo -n yourpassword | sha256sum
|
||||
rootPasswordSha2: "changeme_sha256_of_password"
|
||||
persistence:
|
||||
mongodbSize: "10Gi"
|
||||
opensearchSize: "50Gi"
|
||||
graylogSize: "10Gi"
|
||||
|
||||
# =============================================================================
|
||||
# AUTHENTIK — identity provider (OIDC / OAuth2 / SAML)
|
||||
# =============================================================================
|
||||
authentik:
|
||||
enabled: true
|
||||
version: "2024.10.5"
|
||||
# 50-character random string
|
||||
secretKey: "change-me-to-a-50-char-random-string"
|
||||
dbPassword: "changeme_authentik_db"
|
||||
# Defaults to admin@<baseDomain> when empty
|
||||
adminEmail: ""
|
||||
adminPassword: "changeme_admin"
|
||||
persistence:
|
||||
postgresSize: "10Gi"
|
||||
mediaSize: "5Gi"
|
||||
certsSize: "1Gi"
|
||||
|
||||
# =============================================================================
|
||||
# MINIO — S3-compatible object storage
|
||||
# =============================================================================
|
||||
minio:
|
||||
enabled: true
|
||||
version: "latest"
|
||||
rootUser: "minioadmin"
|
||||
rootPassword: "changeme_minio"
|
||||
# OIDC client secret configured in Authentik
|
||||
oidcSecret: "changeme_minio_oidc_secret"
|
||||
# Bucket / credentials used by Nextcloud
|
||||
nextcloudBucket: "nextcloud"
|
||||
nextcloudAccessKey: "nextcloud"
|
||||
nextcloudSecretKey: "changeme_nextcloud_s3"
|
||||
persistence:
|
||||
size: "100Gi"
|
||||
|
||||
# =============================================================================
|
||||
# NEXTCLOUD — file sync and share
|
||||
# =============================================================================
|
||||
nextcloud:
|
||||
enabled: true
|
||||
version: "29"
|
||||
adminUser: "admin"
|
||||
adminPassword: "changeme_nextcloud"
|
||||
dbPassword: "changeme_nextcloud_db"
|
||||
dbRootPassword: "changeme_nextcloud_db_root"
|
||||
persistence:
|
||||
dbSize: "10Gi"
|
||||
dataSize: "50Gi"
|
||||
|
||||
# =============================================================================
|
||||
# STALWART MAIL — SMTP / IMAP mail server
|
||||
# =============================================================================
|
||||
stalwart:
|
||||
enabled: true
|
||||
version: "latest"
|
||||
adminPassword: "changeme_mail_admin"
|
||||
persistence:
|
||||
size: "20Gi"
|
||||
# Service type for external mail ports (25/465/587/993/4190)
|
||||
# LoadBalancer | NodePort
|
||||
mailServiceType: LoadBalancer
|
||||
|
||||
# =============================================================================
|
||||
# ROUNDCUBE — webmail client
|
||||
# =============================================================================
|
||||
roundcube:
|
||||
enabled: true
|
||||
version: "latest"
|
||||
dbPassword: "changeme_roundcube_db"
|
||||
# Exactly 24 characters
|
||||
desKey: "changeme_24_char_des_key____"
|
||||
skin: "elastic"
|
||||
persistence:
|
||||
dbSize: "5Gi"
|
||||
|
||||
# =============================================================================
|
||||
# MATRIX / ELEMENT — federated chat (Synapse + Element Web)
|
||||
# =============================================================================
|
||||
matrix:
|
||||
enabled: true
|
||||
synapseVersion: "v1.118.0"
|
||||
# Used for user registration via the admin API
|
||||
registrationSecret: "changeme_registration_secret"
|
||||
dbPassword: "changeme_matrix_db"
|
||||
persistence:
|
||||
dbSize: "10Gi"
|
||||
synapseSize: "20Gi"
|
||||
|
||||
# =============================================================================
|
||||
# JITSI — video conferencing
|
||||
# =============================================================================
|
||||
jitsi:
|
||||
enabled: true
|
||||
version: "stable-9753"
|
||||
jicofoAuthPassword: "changeme_jicofo"
|
||||
jvbAuthPassword: "changeme_jvb"
|
||||
jibriRecorderPassword: "changeme_jibri_recorder"
|
||||
jibriXmppPassword: "changeme_jibri_xmpp"
|
||||
turnSecret: "changeme_turn"
|
||||
persistence:
|
||||
webSize: "1Gi"
|
||||
prosodySize: "1Gi"
|
||||
jicofoSize: "1Gi"
|
||||
jvbSize: "1Gi"
|
||||
|
||||
# =============================================================================
|
||||
# HEADSCALE — WireGuard mesh VPN coordinator
|
||||
# =============================================================================
|
||||
headscale:
|
||||
enabled: true
|
||||
version: "0.23.0"
|
||||
wireguardPort: 51820
|
||||
persistence:
|
||||
configSize: "1Gi"
|
||||
dataSize: "5Gi"
|
||||
|
||||
# =============================================================================
|
||||
# WAZUH — endpoint security (Manager + Indexer + Dashboard)
|
||||
# NOTE: Wazuh requires pre-generated TLS certificates stored in a Kubernetes
|
||||
# Secret named <release>-wazuh-certs with the keys documented in
|
||||
# templates/wazuh.yaml before first deployment.
|
||||
# =============================================================================
|
||||
wazuh:
|
||||
enabled: true
|
||||
version: "4.9.0"
|
||||
adminPassword: "changeme_wazuh_admin"
|
||||
apiPassword: "changeme_wazuh_api"
|
||||
indexerJavaOpts: "-Xms512m -Xmx512m"
|
||||
persistence:
|
||||
managerSize: "20Gi"
|
||||
indexerSize: "50Gi"
|
||||
|
||||
# =============================================================================
|
||||
# VAULTWARDEN — Bitwarden-compatible password manager
|
||||
# =============================================================================
|
||||
vaultwarden:
|
||||
enabled: true
|
||||
version: "latest"
|
||||
adminToken: "changeme_vaultwarden_admin_token"
|
||||
dbPassword: "changeme_vaultwarden_db"
|
||||
# OIDC client secret configured in Authentik
|
||||
oidcSecret: "changeme_vaultwarden_oidc_secret"
|
||||
persistence:
|
||||
dbSize: "5Gi"
|
||||
dataSize: "10Gi"
|
||||
|
||||
# =============================================================================
|
||||
# FORGEJO — self-hosted Git
|
||||
# =============================================================================
|
||||
forgejo:
|
||||
enabled: true
|
||||
version: "latest"
|
||||
dbPassword: "changeme_forgejo_db"
|
||||
secretKey: "changeme_forgejo_secret"
|
||||
internalToken: "changeme_forgejo_internal_token"
|
||||
lfsJwtSecret: "changeme_forgejo_lfs_jwt"
|
||||
adminUser: "admin"
|
||||
adminPassword: "changeme_forgejo_admin"
|
||||
# Defaults to admin@<baseDomain> when empty
|
||||
adminEmail: ""
|
||||
# NodePort number for SSH git access
|
||||
sshPort: 2222
|
||||
persistence:
|
||||
dbSize: "10Gi"
|
||||
dataSize: "20Gi"
|
||||
|
||||
# =============================================================================
|
||||
# WEBSITE — static site (nginx)
|
||||
# =============================================================================
|
||||
website:
|
||||
enabled: true
|
||||
nginxVersion: "alpine"
|
||||
persistence:
|
||||
htmlSize: "1Gi"
|
||||
Reference in New Issue
Block a user