feat(matrix): add Synapse + Element Web deployment

Personal homeserver with bridges deferred. Single host
matrix.{cluster.domain} with path-based routing: /_matrix, /_synapse,
/.well-known/matrix → Synapse; / → Element Web. Both share matrix-tls.

Stack: ananace/matrix-synapse + element-web charts, CNPG postgres
(LC_COLLATE=C), in-cluster alpine redis (no auth, replaces bitnami
subchart), mittwald-generated synapse-secrets for registration_shared/
macaroon/form_secret, custom idempotent signing-key init Job (replaces
chart's bitnami/kubectl publisher).

Sync waves:
  -3 Namespace
  -2 synapse-secrets (mittwald head-start), signing-key RBAC
  -1 signing-key Job, CNPG Cluster, redis
   0 Synapse, Element, Ingress

Synapse pod waits in extraCommands until synapse-secrets is populated,
then writes zz-overrides.yaml to override chart placeholders for the
three secret values without churning the chart-managed Secret on every
render. Resources tightened for 1-2 user scale: Synapse 256Mi/512Mi,
Postgres 64Mi/128Mi.

ArgoCD destination.namespace overridden to matrix via prototype-level
argocd overlay so both apps share the matrix ns instead of creating
unused matrix-synapse and element-web namespaces.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Felix Wolf 2026-05-03 18:04:29 +02:00
parent fe51c8c1bc
commit 137705bfe0
68 changed files with 2138 additions and 0 deletions

View file

@ -14,6 +14,8 @@ environment:
- proto: metrics-server - proto: metrics-server
- proto: grafana - proto: grafana
- proto: ocis - proto: ocis
- proto: matrix-synapse
- proto: element-web
cluster: cluster:
domain: minikube domain: minikube

View file

@ -18,6 +18,8 @@ environment:
- proto: cloudnative-pg - proto: cloudnative-pg
- proto: metrics-server - proto: metrics-server
- proto: ocis - proto: ocis
- proto: matrix-synapse
- proto: element-web
cluster: cluster:
domain: tr1ceracop.de domain: tr1ceracop.de

View file

@ -0,0 +1,6 @@
#@data/values-schema
---
#@overlay/match-child-defaults missing_ok=True
application:
namespace: matrix
subdomain: matrix

View file

@ -0,0 +1,8 @@
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")
#@overlay/match by=overlay.all, expects="1+"
---
spec:
destination:
namespace: #@ data.values.application.namespace

View file

@ -0,0 +1,40 @@
#@ load("@ytt:data", "data")
#@ host = data.values.application.subdomain + "." + data.values.cluster.domain
---
defaultServer:
url: #@ "https://" + host
name: #@ host
ingress:
enabled: true
className: #@ data.values.cluster.ingress.className
annotations:
cert-manager.io/cluster-issuer: #@ data.values.cluster.tls.issuer
hosts:
- #@ host
tls:
- secretName: matrix-tls
hosts:
- #@ host
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
podSecurityContext:
runAsNonRoot: true
runAsUser: 101
runAsGroup: 101
fsGroup: 101
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
capabilities:
drop:
- ALL

View file

@ -0,0 +1,16 @@
#@ load("@ytt:data", "data")
#@ app = data.values.application
---
apiVersion: vendir.k14s.io/v1alpha1
kind: Config
directories:
- path: #@ "charts/" + app.name
contents:
- path: .
helmChart:
name: #@ app.name
version: #@ app.version
repository:
url: #@ app.url
lazy: true

View file

@ -0,0 +1,7 @@
#@data/values-schema
---
#@overlay/match-child-defaults missing_ok=True
application:
name: element-web
url: https://gitlab.com/api/v4/projects/12378663/packages/helm/stable
version: 1.4.36

View file

@ -0,0 +1,10 @@
#@ load("@ytt:data", "data")
#@ load("@ytt:overlay", "overlay")
#@ ns = data.values.application.namespace
#@overlay/match by=overlay.all, expects="1+"
---
metadata:
#@overlay/match missing_ok=True
namespace: #@ ns

View file

@ -0,0 +1,6 @@
#@data/values-schema
---
#@overlay/match-child-defaults missing_ok=True
application:
namespace: matrix
subdomain: matrix

View file

@ -0,0 +1,8 @@
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")
#@overlay/match by=overlay.all, expects="1+"
---
spec:
destination:
namespace: #@ data.values.application.namespace

View file

@ -0,0 +1,111 @@
#@ load("@ytt:data", "data")
#@ host = data.values.application.subdomain + "." + data.values.cluster.domain
---
argoCD: true
serverName: #@ host
publicServerName: #@ host
image:
repository: ghcr.io/element-hq/synapse
config:
reportStats: false
enableRegistration: false
publicBaseurl: #@ "https://" + host
#! Placeholders kept stable across renders so the chart-managed Secret
#! does not drift in ArgoCD. The real values live in `synapse-secrets`
#! (mittwald-generated) and are written to conf.d/zz-overrides.yaml at
#! pod startup via synapse.extraCommands, overriding these.
registrationSharedSecret: overridden-by-zz-overrides
macaroonSecretKey: overridden-by-zz-overrides
signingkey:
job:
enabled: false
existingSecret: synapse-signing-key
existingSecretKey: signing.key
postgresql:
enabled: false
externalPostgresql:
host: synapse-cnpg-rw.matrix.svc
port: 5432
username: synapse
database: synapse
existingSecret: synapse-cnpg-app
existingSecretPasswordKey: password
sslmode: disable
redis:
enabled: false
usePassword: false
password: ~
auth:
enabled: false
password: ~
externalRedis:
host: redis.matrix.svc
port: 6379
password: ~
persistence:
enabled: true
storageClass: #@ data.values.cluster.storageClass.block
accessMode: ReadWriteOnce
size: 10Gi
service:
type: ClusterIP
port: 8008
ingress:
enabled: true
className: #@ data.values.cluster.ingress.className
annotations:
cert-manager.io/cluster-issuer: #@ data.values.cluster.tls.issuer
tls:
- secretName: matrix-tls
hosts:
- #@ host
wellknown:
enabled: false
synapse:
strategy:
type: Recreate
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
podSecurityContext:
runAsNonRoot: true
runAsUser: 991
runAsGroup: 991
fsGroup: 991
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
extraVolumes:
- name: synapse-secrets
secret:
secretName: synapse-secrets
extraVolumeMounts:
- name: synapse-secrets
mountPath: /synapse/extra-secrets
readOnly: true
extraCommands:
- 'i=0; while [ ! -s /synapse/extra-secrets/registration_shared_secret ] && [ $i -lt 60 ]; do echo "waiting for synapse-secrets"; sleep 2; i=$((i+1)); done'
- 'printf ''registration_shared_secret: "%s"\nmacaroon_secret_key: "%s"\nform_secret: "%s"\n'' "$(cat /synapse/extra-secrets/registration_shared_secret)" "$(cat /synapse/extra-secrets/macaroon_secret_key)" "$(cat /synapse/extra-secrets/form_secret)" > /synapse/config/conf.d/zz-overrides.yaml'
serviceAccount:
create: true

View file

@ -0,0 +1,16 @@
#@ load("@ytt:data", "data")
#@ app = data.values.application
---
apiVersion: vendir.k14s.io/v1alpha1
kind: Config
directories:
- path: #@ "charts/" + app.name
contents:
- path: .
helmChart:
name: #@ app.name
version: #@ app.version
repository:
url: #@ app.url
lazy: true

View file

@ -0,0 +1,7 @@
#@data/values-schema
---
#@overlay/match-child-defaults missing_ok=True
application:
name: matrix-synapse
url: https://gitlab.com/api/v4/projects/12378663/packages/helm/stable
version: 3.12.26

View file

@ -0,0 +1,40 @@
#@ load("@ytt:data", "data")
#@ ns = data.values.application.namespace
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: synapse-cnpg
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
instances: 1
bootstrap:
initdb:
database: synapse
owner: synapse
localeCollate: C
localeCType: C
storage:
size: 5Gi
storageClass: #@ data.values.cluster.storageClass.block
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
postgresql:
parameters:
shared_buffers: "32MB"
effective_cache_size: "96MB"
work_mem: "4MB"
maintenance_work_mem: "32MB"
max_connections: "30"

View file

@ -0,0 +1,20 @@
#@ load("@ytt:data", "data")
#@ load("@ytt:overlay", "overlay")
#@ ns = data.values.application.namespace
---
apiVersion: v1
kind: Namespace
metadata:
name: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-3"
labels:
pod-security.kubernetes.io/enforce: restricted
#@overlay/match by=overlay.all, expects="1+"
---
metadata:
#@overlay/match missing_ok=True
namespace: #@ ns

View file

@ -0,0 +1,15 @@
#@ load("@ytt:data", "data")
#@ ns = data.values.application.namespace
---
apiVersion: v1
kind: Secret
metadata:
name: synapse-secrets
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-2"
secret-generator.v1.mittwald.de/autogenerate: registration_shared_secret,macaroon_secret_key,form_secret
secret-generator.v1.mittwald.de/length: "64"
type: Opaque

View file

@ -0,0 +1,67 @@
#@ load("@ytt:data", "data")
#@ ns = data.values.application.namespace
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: redis
template:
metadata:
labels:
app.kubernetes.io/name: redis
spec:
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
fsGroup: 999
seccompProfile:
type: RuntimeDefault
containers:
- name: redis
image: docker.io/redis:7-alpine
imagePullPolicy: IfNotPresent
command: ["redis-server", "--save", "", "--appendonly", "no"]
ports:
- name: redis
containerPort: 6379
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: redis
ports:
- name: redis
port: 6379
targetPort: redis

View file

@ -0,0 +1,127 @@
#@ load("@ytt:data", "data")
#@ ns = data.values.application.namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: synapse-signing-key-init
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-2"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: synapse-signing-key-init
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-2"
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: synapse-signing-key-init
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-wave: "-2"
subjects:
- kind: ServiceAccount
name: synapse-signing-key-init
namespace: #@ ns
roleRef:
kind: Role
name: synapse-signing-key-init
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
name: synapse-signing-key-init
namespace: #@ ns
annotations:
argocd.argoproj.io/sync-options: Replace=true,Force=true
argocd.argoproj.io/sync-wave: "-1"
spec:
ttlSecondsAfterFinished: 300
template:
spec:
serviceAccountName: synapse-signing-key-init
restartPolicy: OnFailure
securityContext:
runAsNonRoot: true
runAsUser: 991
runAsGroup: 991
fsGroup: 991
seccompProfile:
type: RuntimeDefault
initContainers:
- name: generate
image: ghcr.io/element-hq/synapse:v1.152.0
command:
- sh
- -c
- |
set -e
if [ -f /shared/signing.key ]; then
exit 0
fi
if command -v generate_signing_key >/dev/null 2>&1; then
generate_signing_key -o /shared/signing.key
else
generate_signing_key.py -o /shared/signing.key
fi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: shared
mountPath: /shared
containers:
- name: store
image: alpine/k8s:1.32.3
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- sh
- -c
- |
set -e
SECRET="synapse-signing-key"
if kubectl get secret "${SECRET}" -n "${NAMESPACE}" >/dev/null 2>&1; then
echo "Secret ${SECRET} already exists, skipping"
exit 0
fi
kubectl create secret generic "${SECRET}" \
--namespace="${NAMESPACE}" \
--from-file=signing.key=/shared/signing.key
echo "Created secret ${SECRET}"
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: shared
mountPath: /shared
readOnly: true
volumes:
- name: shared
emptyDir:
medium: Memory
sizeLimit: 1Mi

View file

@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
myks.dev/environment: minikube
finalizers:
- resources-finalizer.argocd.argoproj.io
name: app-minikube-element-web
namespace: argocd
spec:
destination:
namespace: matrix
server: https://kubernetes.default.svc
project: env-minikube
source:
path: rendered/envs/minikube/element-web
repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View file

@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
myks.dev/environment: minikube
finalizers:
- resources-finalizer.argocd.argoproj.io
name: app-minikube-matrix-synapse
namespace: argocd
spec:
destination:
namespace: matrix
server: https://kubernetes.default.svc
project: env-minikube
source:
path: rendered/envs/minikube/matrix-synapse
repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View file

@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
myks.dev/environment: production
finalizers:
- resources-finalizer.argocd.argoproj.io
name: app-production-element-web
namespace: argocd
spec:
destination:
namespace: matrix
server: https://kubernetes.default.svc
project: env-production
source:
path: rendered/envs/production/element-web
repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View file

@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
myks.dev/environment: production
finalizers:
- resources-finalizer.argocd.argoproj.io
name: app-production-matrix-synapse
namespace: argocd
spec:
destination:
namespace: matrix
server: https://kubernetes.default.svc
project: env-production
source:
path: rendered/envs/production/matrix-synapse
repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View file

@ -0,0 +1,37 @@
apiVersion: v1
data:
default.conf: |
server {
listen 8080;
listen [::]:8080;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "frame-ancestors 'self'";
# Set no-cache for the index.html only so that browsers always check for a new copy of Element Web.
location = /index.html {
add_header Cache-Control "no-cache";
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
}
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web-nginx
namespace: matrix

View file

@ -0,0 +1,16 @@
apiVersion: v1
data:
config.json: |
{"default_server_config":{"m.homeserver":{"base_url":"https://matrix.minikube","server_name":"matrix.minikube"},"m.identity_server":{"base_url":"https://vector.im"}}}
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix

View file

@ -0,0 +1,81 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
template:
metadata:
annotations:
checksum/config: 2d356a5bdaf9a18d891cfa939070f193ac94dc87bcc001a43769c6a0cae50a17
checksum/config-nginx: 7b910777640c47e06f1153bb1d327cc8b7bbfe8ee1d58e444c5abcc2a4afb7a0
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
spec:
containers:
- env:
- name: ELEMENT_WEB_PORT
value: "8080"
image: ghcr.io/element-hq/element-web:v1.12.17
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: http
name: element-web
ports:
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
httpGet:
path: /
port: http
resources:
limits:
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /app/config.json
name: config
subPath: config.json
- mountPath: /etc/nginx/conf.d/config.json
name: config-nginx
subPath: config.json
securityContext:
fsGroup: 101
runAsGroup: 101
runAsNonRoot: true
runAsUser: 101
seccompProfile:
type: RuntimeDefault
serviceAccountName: element-web
volumes:
- configMap:
name: element-web
name: config
- configMap:
name: element-web-nginx
name: config-nginx

View file

@ -0,0 +1,31 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
cert-manager.io/cluster-issuer: mkcert
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
ingressClassName: traefik
rules:
- host: matrix.minikube
http:
paths:
- backend:
service:
name: element-web
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- matrix.minikube
secretName: matrix-tls

View file

@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
type: ClusterIP

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix

View file

@ -0,0 +1,32 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: synapse-cnpg
namespace: matrix
spec:
bootstrap:
initdb:
database: synapse
localeCType: C
localeCollate: C
owner: synapse
instances: 1
postgresql:
parameters:
effective_cache_size: 96MB
maintenance_work_mem: 32MB
max_connections: "30"
shared_buffers: 32MB
work_mem: 4MB
resources:
limits:
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
storage:
size: 5Gi
storageClass: standard

View file

@ -0,0 +1,36 @@
apiVersion: v1
data:
homeserver.yaml: "# NOTE:\n# Secrets are stored in separate configs to better fit K8s concepts\n\n## Server ##\n\nserver_name: \"matrix.minikube\"\npublic_baseurl: \"https://matrix.minikube\"\npid_file: /homeserver.pid\nweb_client: False\nsoft_file_limit: 0\nlog_config: \"/synapse/config/log.yaml\"\nreport_stats: false\n\ninstance_map:\n main:\n host: matrix-synapse-replication\n port: 9093\n\n## Ports ##\n\nlisteners:\n - port: 8008\n tls: false\n bind_addresses: [\"::\"]\n type: http\n x_forwarded: true\n\n resources:\n - names: \n - client\n - federation\n compress: false\n\n - port: 9090\n tls: false\n bind_addresses: [\"::\"]\n type: http\n\n resources:\n - names: [metrics]\n compress: false\n\n - port: 9093\n tls: false\n bind_addresses: [\"::\"]\n type: http\n\n resources:\n - names: [replication]\n compress: false\n\n## Files ##\n\nmedia_store_path: \"/synapse/data/media\"\nuploads_path: \"/synapse/data/uploads\"\n\n## Registration ##\n\nenable_registration: false\n\n## Metrics ###\n\nenable_metrics: true\n\n## Signing Keys ##\n\nsigning_key_path: \"/synapse/keys/signing.key\"\n\n# The trusted servers to download signing keys from.\ntrusted_key_servers:\n - server_name: matrix.org\n\n## Workers ##\n"
log.yaml: |
version: 1
formatters:
precise:
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s- %(message)s'
filters:
context:
(): synapse.util.logcontext.LoggingContextFilter
request: ""
handlers:
console:
class: logging.StreamHandler
formatter: precise
filters: [context]
level: INFO
loggers:
synapse:
level: INFO
root:
level: INFO
handlers: [console]
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix

View file

@ -0,0 +1,142 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
strategy:
type: Recreate
template:
metadata:
annotations:
checksum/config: 0750c2f14986445e44cd32eddbea80ce9ef5c78ba14041b3e6a6a0be971d04f1
checksum/secrets: 54091df516cd7bf15484597ec0c9613cd969341f977e3228b5416997dc9b8c95
labels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
spec:
containers:
- command:
- sh
- -c
- |
export POSTGRES_PASSWORD=$(echo "${POSTGRES_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') && \
export REDIS_PASSWORD=$(echo "${REDIS_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') && \
cat /synapse/secrets/*.yaml | \
sed -e "s/@@POSTGRES_PASSWORD@@/${POSTGRES_PASSWORD:-}/" \
-e "s/@@REDIS_PASSWORD@@/${REDIS_PASSWORD:-}/" \
> /synapse/config/conf.d/secrets.yaml
i=0; while [ ! -s /synapse/extra-secrets/registration_shared_secret ] && [ $i -lt 60 ]; do echo "waiting for synapse-secrets"; sleep 2; i=$((i+1)); done
printf 'registration_shared_secret: "%s"\nmacaroon_secret_key: "%s"\nform_secret: "%s"\n' "$(cat /synapse/extra-secrets/registration_shared_secret)" "$(cat /synapse/extra-secrets/macaroon_secret_key)" "$(cat /synapse/extra-secrets/form_secret)" > /synapse/config/conf.d/zz-overrides.yaml
exec python -B -m synapse.app.homeserver \
-c /synapse/config/homeserver.yaml \
-c /synapse/config/conf.d/
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: synapse-cnpg-app
image: ghcr.io/element-hq/synapse:v1.152.0
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /health
port: http
name: synapse
ports:
- containerPort: 8008
name: http
protocol: TCP
- containerPort: 9093
name: replication
protocol: TCP
- containerPort: 9090
name: metrics
protocol: TCP
readinessProbe:
httpGet:
path: /health
port: http
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
startupProbe:
failureThreshold: 12
httpGet:
path: /health
port: http
volumeMounts:
- mountPath: /synapse/config
name: config
- mountPath: /synapse/config/conf.d
name: tmpconf
- mountPath: /synapse/secrets
name: secrets
- mountPath: /synapse/keys
name: signingkey
- mountPath: /synapse/data
name: media
- mountPath: /tmp
name: tmpdir
- mountPath: /synapse/extra-secrets
name: synapse-secrets
readOnly: true
securityContext:
fsGroup: 991
runAsGroup: 991
runAsNonRoot: true
runAsUser: 991
seccompProfile:
type: RuntimeDefault
serviceAccountName: matrix-synapse
volumes:
- configMap:
name: matrix-synapse
name: config
- name: secrets
secret:
secretName: matrix-synapse
- name: signingkey
secret:
items:
- key: signing.key
path: signing.key
secretName: synapse-signing-key
- emptyDir: {}
name: tmpconf
- emptyDir: {}
name: tmpdir
- name: media
persistentVolumeClaim:
claimName: matrix-synapse
- name: synapse-secrets
secret:
secretName: synapse-secrets

View file

@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: redis
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: redis
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/name: redis
spec:
containers:
- command:
- redis-server
- --save
- ""
- --appendonly
- "no"
image: docker.io/redis:7-alpine
imagePullPolicy: IfNotPresent
name: redis
ports:
- containerPort: 6379
name: redis
resources:
limits:
memory: 64Mi
requests:
cpu: 10m
memory: 16Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
securityContext:
fsGroup: 999
runAsGroup: 999
runAsNonRoot: true
runAsUser: 999
seccompProfile:
type: RuntimeDefault

View file

@ -0,0 +1,45 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
cert-manager.io/cluster-issuer: mkcert
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
ingressClassName: traefik
rules:
- host: matrix.minikube
http:
paths:
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /_matrix
pathType: Prefix
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /_synapse
pathType: Prefix
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /.well-known/matrix
pathType: Prefix
tls:
- hosts:
- matrix.minikube
secretName: matrix-tls

View file

@ -0,0 +1,84 @@
apiVersion: batch/v1
kind: Job
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-options: Replace=true,Force=true
argocd.argoproj.io/sync-wave: "-1"
name: synapse-signing-key-init
namespace: matrix
spec:
template:
spec:
containers:
- command:
- sh
- -c
- |
set -e
SECRET="synapse-signing-key"
if kubectl get secret "${SECRET}" -n "${NAMESPACE}" >/dev/null 2>&1; then
echo "Secret ${SECRET} already exists, skipping"
exit 0
fi
kubectl create secret generic "${SECRET}" \
--namespace="${NAMESPACE}" \
--from-file=signing.key=/shared/signing.key
echo "Created secret ${SECRET}"
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: alpine/k8s:1.32.3
name: store
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /shared
name: shared
readOnly: true
initContainers:
- command:
- sh
- -c
- |
set -e
if [ -f /shared/signing.key ]; then
exit 0
fi
if command -v generate_signing_key >/dev/null 2>&1; then
generate_signing_key -o /shared/signing.key
else
generate_signing_key.py -o /shared/signing.key
fi
image: ghcr.io/element-hq/synapse:v1.152.0
name: generate
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /shared
name: shared
restartPolicy: OnFailure
securityContext:
fsGroup: 991
runAsGroup: 991
runAsNonRoot: true
runAsUser: 991
seccompProfile:
type: RuntimeDefault
serviceAccountName: synapse-signing-key-init
volumes:
- emptyDir:
medium: Memory
sizeLimit: 1Mi
name: shared
ttlSecondsAfterFinished: 300

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Namespace
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-3"
labels:
pod-security.kubernetes.io/enforce: restricted
name: matrix
namespace: matrix

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: synapse-signing-key-init
subjects:
- kind: ServiceAccount
name: synapse-signing-key-init
namespace: matrix

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
stringData:
config.yaml: "## Registration ##\n\nregistration_shared_secret: \"overridden-by-zz-overrides\"\n\n## API Configuration ##\n\nmacaroon_secret_key: \"overridden-by-zz-overrides\"\n\n## Database configuration ##\n\ndatabase:\n name: \"psycopg2\"\n args:\n user: \"synapse\"\n password: \"@@POSTGRES_PASSWORD@@\"\n database: \"synapse\"\n host: \"synapse-cnpg-rw.matrix.svc\"\n port: 5432\n sslmode: \"disable\"\n cp_min: 5\n cp_max: 10\n \n\n## Redis configuration ##\n\nredis:\n enabled: true\n host: \"redis.matrix.svc\"\n port: 6379\n"

View file

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
secret-generator.v1.mittwald.de/autogenerate: registration_shared_secret,macaroon_secret_key,form_secret
secret-generator.v1.mittwald.de/length: "64"
name: synapse-secrets
namespace: matrix
type: Opaque

View file

@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse-replication
namespace: matrix
spec:
ports:
- name: replication
port: 9093
protocol: TCP
targetPort: replication
selector:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
type: ClusterIP

View file

@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
ports:
- name: http
port: 8008
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
type: ClusterIP

View file

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: redis
namespace: matrix
spec:
ports:
- name: redis
port: 6379
targetPort: redis
selector:
app.kubernetes.io/name: redis
type: ClusterIP

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix

View file

@ -0,0 +1,37 @@
apiVersion: v1
data:
default.conf: |
server {
listen 8080;
listen [::]:8080;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "frame-ancestors 'self'";
# Set no-cache for the index.html only so that browsers always check for a new copy of Element Web.
location = /index.html {
add_header Cache-Control "no-cache";
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
}
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web-nginx
namespace: matrix

View file

@ -0,0 +1,16 @@
apiVersion: v1
data:
config.json: |
{"default_server_config":{"m.homeserver":{"base_url":"https://matrix.tr1ceracop.de","server_name":"matrix.tr1ceracop.de"},"m.identity_server":{"base_url":"https://vector.im"}}}
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix

View file

@ -0,0 +1,81 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
template:
metadata:
annotations:
checksum/config: 258884d3c78bc05fe275db741f0d980e7e157fe0cd432aa4302e6a59d423012a
checksum/config-nginx: 7b910777640c47e06f1153bb1d327cc8b7bbfe8ee1d58e444c5abcc2a4afb7a0
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
spec:
containers:
- env:
- name: ELEMENT_WEB_PORT
value: "8080"
image: ghcr.io/element-hq/element-web:v1.12.17
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: http
name: element-web
ports:
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
httpGet:
path: /
port: http
resources:
limits:
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /app/config.json
name: config
subPath: config.json
- mountPath: /etc/nginx/conf.d/config.json
name: config-nginx
subPath: config.json
securityContext:
fsGroup: 101
runAsGroup: 101
runAsNonRoot: true
runAsUser: 101
seccompProfile:
type: RuntimeDefault
serviceAccountName: element-web
volumes:
- configMap:
name: element-web
name: config
- configMap:
name: element-web-nginx
name: config-nginx

View file

@ -0,0 +1,31 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
cert-manager.io/cluster-issuer: letsencrypt
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
ingressClassName: traefik
rules:
- host: matrix.tr1ceracop.de
http:
paths:
- backend:
service:
name: element-web
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- matrix.tr1ceracop.de
secretName: matrix-tls

View file

@ -0,0 +1,23 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/instance: element-web
app.kubernetes.io/name: element-web
type: ClusterIP

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: element-web
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: element-web
app.kubernetes.io/version: 1.12.17
helm.sh/chart: element-web-1.4.36
name: element-web
namespace: matrix

View file

@ -0,0 +1,32 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: synapse-cnpg
namespace: matrix
spec:
bootstrap:
initdb:
database: synapse
localeCType: C
localeCollate: C
owner: synapse
instances: 1
postgresql:
parameters:
effective_cache_size: 96MB
maintenance_work_mem: 32MB
max_connections: "30"
shared_buffers: 32MB
work_mem: 4MB
resources:
limits:
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
storage:
size: 5Gi
storageClass: hcloud-volumes

View file

@ -0,0 +1,36 @@
apiVersion: v1
data:
homeserver.yaml: "# NOTE:\n# Secrets are stored in separate configs to better fit K8s concepts\n\n## Server ##\n\nserver_name: \"matrix.tr1ceracop.de\"\npublic_baseurl: \"https://matrix.tr1ceracop.de\"\npid_file: /homeserver.pid\nweb_client: False\nsoft_file_limit: 0\nlog_config: \"/synapse/config/log.yaml\"\nreport_stats: false\n\ninstance_map:\n main:\n host: matrix-synapse-replication\n port: 9093\n\n## Ports ##\n\nlisteners:\n - port: 8008\n tls: false\n bind_addresses: [\"::\"]\n type: http\n x_forwarded: true\n\n resources:\n - names: \n - client\n - federation\n compress: false\n\n - port: 9090\n tls: false\n bind_addresses: [\"::\"]\n type: http\n\n resources:\n - names: [metrics]\n compress: false\n\n - port: 9093\n tls: false\n bind_addresses: [\"::\"]\n type: http\n\n resources:\n - names: [replication]\n compress: false\n\n## Files ##\n\nmedia_store_path: \"/synapse/data/media\"\nuploads_path: \"/synapse/data/uploads\"\n\n## Registration ##\n\nenable_registration: false\n\n## Metrics ###\n\nenable_metrics: true\n\n## Signing Keys ##\n\nsigning_key_path: \"/synapse/keys/signing.key\"\n\n# The trusted servers to download signing keys from.\ntrusted_key_servers:\n - server_name: matrix.org\n\n## Workers ##\n"
log.yaml: |
version: 1
formatters:
precise:
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s- %(message)s'
filters:
context:
(): synapse.util.logcontext.LoggingContextFilter
request: ""
handlers:
console:
class: logging.StreamHandler
formatter: precise
filters: [context]
level: INFO
loggers:
synapse:
level: INFO
root:
level: INFO
handlers: [console]
kind: ConfigMap
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix

View file

@ -0,0 +1,142 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
strategy:
type: Recreate
template:
metadata:
annotations:
checksum/config: e9410364225cc447e9ce6b06ef65e4740011fa188b0a8ebab877ea04a1d100d7
checksum/secrets: 54091df516cd7bf15484597ec0c9613cd969341f977e3228b5416997dc9b8c95
labels:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
spec:
containers:
- command:
- sh
- -c
- |
export POSTGRES_PASSWORD=$(echo "${POSTGRES_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') && \
export REDIS_PASSWORD=$(echo "${REDIS_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g') && \
cat /synapse/secrets/*.yaml | \
sed -e "s/@@POSTGRES_PASSWORD@@/${POSTGRES_PASSWORD:-}/" \
-e "s/@@REDIS_PASSWORD@@/${REDIS_PASSWORD:-}/" \
> /synapse/config/conf.d/secrets.yaml
i=0; while [ ! -s /synapse/extra-secrets/registration_shared_secret ] && [ $i -lt 60 ]; do echo "waiting for synapse-secrets"; sleep 2; i=$((i+1)); done
printf 'registration_shared_secret: "%s"\nmacaroon_secret_key: "%s"\nform_secret: "%s"\n' "$(cat /synapse/extra-secrets/registration_shared_secret)" "$(cat /synapse/extra-secrets/macaroon_secret_key)" "$(cat /synapse/extra-secrets/form_secret)" > /synapse/config/conf.d/zz-overrides.yaml
exec python -B -m synapse.app.homeserver \
-c /synapse/config/homeserver.yaml \
-c /synapse/config/conf.d/
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: synapse-cnpg-app
image: ghcr.io/element-hq/synapse:v1.152.0
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /health
port: http
name: synapse
ports:
- containerPort: 8008
name: http
protocol: TCP
- containerPort: 9093
name: replication
protocol: TCP
- containerPort: 9090
name: metrics
protocol: TCP
readinessProbe:
httpGet:
path: /health
port: http
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
startupProbe:
failureThreshold: 12
httpGet:
path: /health
port: http
volumeMounts:
- mountPath: /synapse/config
name: config
- mountPath: /synapse/config/conf.d
name: tmpconf
- mountPath: /synapse/secrets
name: secrets
- mountPath: /synapse/keys
name: signingkey
- mountPath: /synapse/data
name: media
- mountPath: /tmp
name: tmpdir
- mountPath: /synapse/extra-secrets
name: synapse-secrets
readOnly: true
securityContext:
fsGroup: 991
runAsGroup: 991
runAsNonRoot: true
runAsUser: 991
seccompProfile:
type: RuntimeDefault
serviceAccountName: matrix-synapse
volumes:
- configMap:
name: matrix-synapse
name: config
- name: secrets
secret:
secretName: matrix-synapse
- name: signingkey
secret:
items:
- key: signing.key
path: signing.key
secretName: synapse-signing-key
- emptyDir: {}
name: tmpconf
- emptyDir: {}
name: tmpdir
- name: media
persistentVolumeClaim:
claimName: matrix-synapse
- name: synapse-secrets
secret:
secretName: synapse-secrets

View file

@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: redis
namespace: matrix
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: redis
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/name: redis
spec:
containers:
- command:
- redis-server
- --save
- ""
- --appendonly
- "no"
image: docker.io/redis:7-alpine
imagePullPolicy: IfNotPresent
name: redis
ports:
- containerPort: 6379
name: redis
resources:
limits:
memory: 64Mi
requests:
cpu: 10m
memory: 16Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
securityContext:
fsGroup: 999
runAsGroup: 999
runAsNonRoot: true
runAsUser: 999
seccompProfile:
type: RuntimeDefault

View file

@ -0,0 +1,45 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
cert-manager.io/cluster-issuer: letsencrypt
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
ingressClassName: traefik
rules:
- host: matrix.tr1ceracop.de
http:
paths:
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /_matrix
pathType: Prefix
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /_synapse
pathType: Prefix
- backend:
service:
name: matrix-synapse
port:
number: 8008
path: /.well-known/matrix
pathType: Prefix
tls:
- hosts:
- matrix.tr1ceracop.de
secretName: matrix-tls

View file

@ -0,0 +1,84 @@
apiVersion: batch/v1
kind: Job
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-options: Replace=true,Force=true
argocd.argoproj.io/sync-wave: "-1"
name: synapse-signing-key-init
namespace: matrix
spec:
template:
spec:
containers:
- command:
- sh
- -c
- |
set -e
SECRET="synapse-signing-key"
if kubectl get secret "${SECRET}" -n "${NAMESPACE}" >/dev/null 2>&1; then
echo "Secret ${SECRET} already exists, skipping"
exit 0
fi
kubectl create secret generic "${SECRET}" \
--namespace="${NAMESPACE}" \
--from-file=signing.key=/shared/signing.key
echo "Created secret ${SECRET}"
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: alpine/k8s:1.32.3
name: store
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /shared
name: shared
readOnly: true
initContainers:
- command:
- sh
- -c
- |
set -e
if [ -f /shared/signing.key ]; then
exit 0
fi
if command -v generate_signing_key >/dev/null 2>&1; then
generate_signing_key -o /shared/signing.key
else
generate_signing_key.py -o /shared/signing.key
fi
image: ghcr.io/element-hq/synapse:v1.152.0
name: generate
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /shared
name: shared
restartPolicy: OnFailure
securityContext:
fsGroup: 991
runAsGroup: 991
runAsNonRoot: true
runAsUser: 991
seccompProfile:
type: RuntimeDefault
serviceAccountName: synapse-signing-key-init
volumes:
- emptyDir:
medium: Memory
sizeLimit: 1Mi
name: shared
ttlSecondsAfterFinished: 300

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Namespace
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-3"
labels:
pod-security.kubernetes.io/enforce: restricted
name: matrix
namespace: matrix

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: hcloud-volumes

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create

View file

@ -0,0 +1,16 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: synapse-signing-key-init
subjects:
- kind: ServiceAccount
name: synapse-signing-key-init
namespace: matrix

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
stringData:
config.yaml: "## Registration ##\n\nregistration_shared_secret: \"overridden-by-zz-overrides\"\n\n## API Configuration ##\n\nmacaroon_secret_key: \"overridden-by-zz-overrides\"\n\n## Database configuration ##\n\ndatabase:\n name: \"psycopg2\"\n args:\n user: \"synapse\"\n password: \"@@POSTGRES_PASSWORD@@\"\n database: \"synapse\"\n host: \"synapse-cnpg-rw.matrix.svc\"\n port: 5432\n sslmode: \"disable\"\n cp_min: 5\n cp_max: 10\n \n\n## Redis configuration ##\n\nredis:\n enabled: true\n host: \"redis.matrix.svc\"\n port: 6379\n"

View file

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
secret-generator.v1.mittwald.de/autogenerate: registration_shared_secret,macaroon_secret_key,form_secret
secret-generator.v1.mittwald.de/length: "64"
name: synapse-secrets
namespace: matrix
type: Opaque

View file

@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse-replication
namespace: matrix
spec:
ports:
- name: replication
port: 9093
protocol: TCP
targetPort: replication
selector:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
type: ClusterIP

View file

@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix
spec:
ports:
- name: http
port: 8008
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/component: synapse
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/name: matrix-synapse
type: ClusterIP

View file

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-1"
name: redis
namespace: matrix
spec:
ports:
- name: redis
port: 6379
targetPort: redis
selector:
app.kubernetes.io/name: redis
type: ClusterIP

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
labels:
app.kubernetes.io/instance: matrix-synapse
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/version: 1.152.0
helm.sh/chart: matrix-synapse-3.12.26
name: matrix-synapse
namespace: matrix

View file

@ -0,0 +1,8 @@
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
argocd.argoproj.io/sync-wave: "-2"
name: synapse-signing-key-init
namespace: matrix