Add Matrix.

This commit is contained in:
2026-01-04 19:36:40 +00:00
parent d756126a34
commit 39095e76d2
9 changed files with 498 additions and 0 deletions

66
matrix/configmap.yaml Normal file
View File

@@ -0,0 +1,66 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: matrix-config
data:
homeserver.yaml: |
server_name: "{{ .serverName }}"
public_baseurl: https://{{ .domain }}
listeners:
- port: {{ .port }}
tls: false
type: http
x_forwarded: true
bind_addresses: ['::']
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: {{ .dbUsername }}
password: ${DB_PASSWORD}
database: {{ .dbName }}
host: {{ .dbHostname }}
port: 5432
cp_min: 5
cp_max: 10
redis:
enabled: true
host: {{ .redisHostname }}
port: 6379
password: ${REDIS_PASSWORD}
media_store_path: /data/media_store
uploads_path: /data/uploads
max_upload_size: 100M
enable_registration: {{ .enableRegistration }}
registration_shared_secret: "${REGISTRATION_SHARED_SECRET}"
macaroon_secret_key: "${MACAROON_SECRET_KEY}"
form_secret: "${FORM_SECRET}"
signing_key_path: /data/keys/signing.key
trusted_key_servers:
- server_name: "matrix.org"
email:
smtp_host: "{{ .smtp.host }}"
smtp_port: {{ .smtp.port }}
smtp_user: "{{ .smtp.user }}"
smtp_pass: "${SMTP_PASSWORD}"
require_transport_security: {{ .smtp.requireTls }}
notif_from: "{{ .smtp.from }}"
app_name: Matrix
report_stats: false
enable_metrics: true
suppress_key_server_warning: true

57
matrix/db-init-job.yaml Normal file
View File

@@ -0,0 +1,57 @@
apiVersion: batch/v1
kind: Job
metadata:
name: matrix-db-init
spec:
template:
spec:
containers:
- name: db-init
image: postgres:17
command: ["/bin/bash", "-c"]
args:
- |
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOSTNAME} -U postgres <<EOF
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USERNAME}') THEN
CREATE USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
ELSE
ALTER USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
END IF;
END
\$\$;
SELECT 'CREATE DATABASE ${DB_DATABASE_NAME} ENCODING ''UTF8'' LC_COLLATE ''C'' LC_CTYPE ''C'' TEMPLATE template0' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_DATABASE_NAME}')\gexec
ALTER DATABASE ${DB_DATABASE_NAME} OWNER TO ${DB_USERNAME};
GRANT ALL PRIVILEGES ON DATABASE ${DB_DATABASE_NAME} TO ${DB_USERNAME};
EOF
env:
- name: POSTGRES_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: postgres.password
- name: DB_HOSTNAME
value: "{{ .dbHostname }}"
- name: DB_DATABASE_NAME
value: "{{ .dbName }}"
- name: DB_USERNAME
value: "{{ .dbUsername }}"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: dbPassword
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: false
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
seccompProfile:
type: RuntimeDefault
restartPolicy: OnFailure

221
matrix/deployment.yaml Normal file
View File

@@ -0,0 +1,221 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: matrix-synapse
spec:
replicas: 1
selector:
matchLabels:
app: matrix-synapse
strategy:
type: Recreate
template:
metadata:
labels:
app: matrix-synapse
component: synapse
spec:
initContainers:
- name: generate-signing-key
image: "{{ .image }}"
command: ["/bin/sh", "-c"]
args:
- |
if [ ! -f /data/keys/signing.key ]; then
echo "Generating signing key..."
mkdir -p /data/keys
# Use Synapse's generate-keys command
python3 -m synapse.app.homeserver \
--generate-keys \
--config-path=/config/homeserver.yaml
echo "Signing key generated successfully"
ls -la /data/keys/
else
echo "Signing key already exists"
fi
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: dbPassword
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: redis.password
- name: REGISTRATION_SHARED_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: registrationSharedSecret
- name: MACAROON_SECRET_KEY
valueFrom:
secretKeyRef:
name: matrix-secrets
key: macaroonSecretKey
- name: FORM_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: formSecret
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: smtp.password
volumeMounts:
- name: matrix-data
mountPath: /data
- name: matrix-config
mountPath: /config
readOnly: true
securityContext:
runAsUser: 991
runAsGroup: 991
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: false
containers:
- name: synapse
image: "{{ .image }}"
command: ["/bin/sh", "-c"]
args:
- |
set -e
echo "Starting config substitution..."
# Substitute environment variables in the config using Python
python3 -c "
import os
import re
import sys
print('Reading config from /config/homeserver.yaml', file=sys.stderr)
try:
with open('/config/homeserver.yaml', 'r') as f:
content = f.read()
print(f'Config file read: {len(content)} bytes', file=sys.stderr)
except Exception as e:
print(f'Error reading config: {e}', file=sys.stderr)
sys.exit(1)
# Replace \${VAR} with environment variable values
def replace_var(match):
var_name = match.group(1)
value = os.environ.get(var_name, match.group(0))
print(f'Replacing {var_name}: {\"***\" if \"PASSWORD\" in var_name or \"SECRET\" in var_name else value}', file=sys.stderr)
return value
content = re.sub(r'\\\$\{([A-Z_]+)\}', replace_var, content)
print('Writing processed config to /data/homeserver.yaml', file=sys.stderr)
try:
with open('/data/homeserver.yaml', 'w') as f:
f.write(content)
print('Config file written successfully', file=sys.stderr)
except Exception as e:
print(f'Error writing config: {e}', file=sys.stderr)
sys.exit(1)
" || { echo "Python script failed with exit code $?"; exit 1; }
echo "Config substitution complete"
ls -la /data/homeserver.yaml
# Start Synapse with the processed config
exec /start.py
ports:
- containerPort: {{ .port }}
protocol: TCP
name: http
- containerPort: {{ .federationPort }}
protocol: TCP
name: federation
env:
- name: SYNAPSE_CONFIG_PATH
value: /data/homeserver.yaml
- name: TZ
value: "{{ .timezone }}"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: dbPassword
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: redis.password
- name: REGISTRATION_SHARED_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: registrationSharedSecret
- name: MACAROON_SECRET_KEY
valueFrom:
secretKeyRef:
name: matrix-secrets
key: macaroonSecretKey
- name: FORM_SECRET
valueFrom:
secretKeyRef:
name: matrix-secrets
key: formSecret
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-secrets
key: smtp.password
volumeMounts:
- name: matrix-config
mountPath: /config
readOnly: true
- name: matrix-data
mountPath: /data
- name: matrix-media
mountPath: /data/media_store
livenessProbe:
httpGet:
path: /health
port: {{ .port }}
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: {{ .port }}
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: false
securityContext:
runAsNonRoot: true
runAsUser: 991
runAsGroup: 991
fsGroup: 991
seccompProfile:
type: RuntimeDefault
volumes:
- name: matrix-config
configMap:
name: matrix-config
- name: matrix-data
persistentVolumeClaim:
claimName: matrix-data-pvc
- name: matrix-media
persistentVolumeClaim:
claimName: matrix-media-pvc

52
matrix/ingress.yaml Normal file
View File

@@ -0,0 +1,52 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-client-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }}
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
spec:
tls:
- hosts:
- {{ .domain }}
secretName: {{ .tlsSecretName }}
rules:
- host: {{ .domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: matrix-synapse
port:
number: {{ .port }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-federation-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }}
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
spec:
tls:
- hosts:
- {{ .serverName }}
secretName: {{ .tlsSecretName }}
rules:
- host: {{ .serverName }}
http:
paths:
- path: /.well-known/matrix
pathType: Prefix
backend:
service:
name: matrix-synapse
port:
number: {{ .federationPort }}

17
matrix/kustomization.yaml Normal file
View File

@@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: {{ .namespace }}
labels:
- includeSelectors: true
pairs:
app: matrix
managedBy: kustomize
partOf: wild-cloud
resources:
- namespace.yaml
- configmap.yaml
- pvc.yaml
- db-init-job.yaml
- deployment.yaml
- service.yaml
- ingress.yaml

41
matrix/manifest.yaml Normal file
View File

@@ -0,0 +1,41 @@
name: matrix
is: matrix
install: true
description: Matrix is an open standard for secure, decentralized, real-time communication. This deploys the Synapse homeserver for self-hosted Matrix federation and messaging.
version: v1.144.0
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/matrix.svg
requires:
- name: postgres
- name: redis
defaultConfig:
namespace: matrix
externalDnsDomain: '{{ .cloud.domain }}'
image: matrixdotorg/synapse:v1.144.0
timezone: UTC
port: 8008
federationPort: 8448
storage: 50Gi
mediaStorage: 100Gi
serverName: '{{ .cloud.domain }}'
dbHostname: postgres.postgres.svc.cluster.local
dbUsername: matrix
dbName: matrix
redisHostname: redis.redis.svc.cluster.local
domain: matrix.{{ .cloud.domain }}
tlsSecretName: wildcard-wild-cloud-tls
enableRegistration: false
smtp:
host: '{{ .cloud.smtp.host }}'
port: '{{ .cloud.smtp.port }}'
from: matrix@{{ .cloud.domain }}
user: '{{ .cloud.smtp.user }}'
requireTls: '{{ .cloud.smtp.tls }}'
defaultSecrets:
- key: dbPassword
- key: registrationSharedSecret
- key: macaroonSecretKey
- key: formSecret
requiredSecrets:
- postgres.password
- redis.password
- smtp.password

4
matrix/namespace.yaml Normal file
View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .namespace }}

22
matrix/pvc.yaml Normal file
View File

@@ -0,0 +1,22 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: matrix-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .storage }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: matrix-media-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .mediaStorage }}

18
matrix/service.yaml Normal file
View File

@@ -0,0 +1,18 @@
---
apiVersion: v1
kind: Service
metadata:
name: matrix-synapse
spec:
type: ClusterIP
ports:
- name: http
port: {{ .port }}
targetPort: {{ .port }}
protocol: TCP
- name: federation
port: {{ .federationPort }}
targetPort: {{ .federationPort }}
protocol: TCP
selector:
app: matrix-synapse