--- 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