Removes the Paperclip deployment (namespace paperclip, CNPG cluster
pclp-pg, ingresses, image automation, server image build) and the
infrastructure that existed only for its agents:
- agent sandbox: paperclip-renner namespace and CNPs, the
kubernetes-sigs/agent-sandbox controller with its namespace, CNP and
Renovate rules
- agent-runtime-{go,ops} images and the build-agent-runtime pipeline
- matrix bridge (Element <-> Paperclip agents) and synapse's appservice
registration mount
- monitoring loki-read-gateway (only called by the paperclip Role)
- MQTT account agents-read and the controller's RBAC in ns paperclip
- the OpenBao secret-exists-check policy file
- agent admits in the wiki, lidarr, shelly-manager, mosquitto and
hubble-relay CNPs; the paperclip-api Gitea webhook host; the wiki API
key; the ClusterSecretStore namespace entry; the pclp-pg RECOVERY row
- the Paperclip design spec and plan
Authentik group "Paperclip Users" is switched to state: absent so the
blueprint deletes it. package-retention's EXCLUDE_PACKAGES becomes
optional, since its only value was the agent-runtime prefix.
The shelly-manager api-proxy sidecar stays: mqtt-account-controller
calls shelly-manager-api too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
311 lines
9.6 KiB
YAML
311 lines
9.6 KiB
YAML
# Synapse homeserver for matrix.renner.uno (REN-567).
|
|
#
|
|
# Private: federation is off at three layers — federation_domain_whitelist
|
|
# is empty, no listener serves the federation/keys resources, and the
|
|
# namespace egress policy lets Synapse reach nothing outside the cluster
|
|
# except the push gateway. Logins and accounts are delegated to MAS
|
|
# (mas.yaml); registration is closed.
|
|
#
|
|
# server_name is permanent: it is part of every user and room ID, and
|
|
# cannot be changed without a new, empty server. matrix.renner.uno needs no
|
|
# .well-known delegation from the apex, which is the WordPress site.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: synapse-config
|
|
namespace: matrix
|
|
data:
|
|
homeserver.yaml: |
|
|
server_name: matrix.renner.uno
|
|
public_baseurl: https://matrix.renner.uno/
|
|
# Lets Element X and other clients discover the homeserver from the
|
|
# server name. No server well-known: there is no federation to point at.
|
|
serve_client_wellknown: true
|
|
pid_file: /tmp/homeserver.pid
|
|
report_stats: false
|
|
|
|
listeners:
|
|
# Client API only (includes media and /.well-known). Leaving out the
|
|
# `federation` and `keys` resources means this server does not answer
|
|
# federation at all.
|
|
- port: 8008
|
|
type: http
|
|
tls: false
|
|
bind_addresses: ["::"]
|
|
x_forwarded: true
|
|
resources:
|
|
- names: [client]
|
|
compress: false
|
|
|
|
# The password comes from PGPASSWORD (libpq reads it), so no credential
|
|
# is written into this file.
|
|
database:
|
|
name: psycopg2
|
|
args:
|
|
host: mx-pg-rw
|
|
port: 5432
|
|
dbname: synapse
|
|
user: synapse
|
|
cp_min: 2
|
|
cp_max: 10
|
|
|
|
# Signing key is generated on first start if missing; it lives on the
|
|
# data PVC next to the media store, so Velero backs up both.
|
|
signing_key_path: /data/signing.key
|
|
media_store_path: /data/media_store
|
|
max_upload_size: 100M
|
|
# Also the macaroon key: Synapse falls back to it when
|
|
# macaroon_secret_key is unset, so rotating it logs every session out.
|
|
registration_shared_secret_path: /secrets/registration_shared_secret
|
|
|
|
# MAS handles login, sessions and accounts. Synapse asks it to check
|
|
# every access token; password login here must be off.
|
|
matrix_authentication_service:
|
|
enabled: true
|
|
endpoint: http://mas:8080/
|
|
secret_path: /secrets/mas_matrix_secret
|
|
password_config:
|
|
enabled: false
|
|
|
|
# Sign in with QR code (Element X): the rendezvous channel between the
|
|
# new and the signed-in device. Both require MAS. `open` lets the new,
|
|
# not-yet-signed-in device create the channel; the server is LAN-only.
|
|
experimental_features:
|
|
msc4108_enabled: true
|
|
msc4388_mode: open
|
|
|
|
# Federation off.
|
|
federation_domain_whitelist: []
|
|
trusted_key_servers: []
|
|
allow_public_rooms_over_federation: false
|
|
|
|
enable_registration: false
|
|
allow_guest_access: false
|
|
url_preview_enabled: false
|
|
user_directory:
|
|
search_all_users: true
|
|
|
|
# Phones get pushes through the Element push gateway on matrix.org.
|
|
# Only event and room IDs leave the cluster, never message text.
|
|
push:
|
|
include_content: false
|
|
---
|
|
# Media store and the server signing key. Not reconstructable: lost media
|
|
# is gone, and a lost signing key invalidates the server's past signatures.
|
|
# Backed up by Velero (matrix-daily); the database by Barman (mx-pg).
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: synapse-data
|
|
namespace: matrix
|
|
labels:
|
|
app.kubernetes.io/name: synapse
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
storageClassName: ceph-block
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: synapse
|
|
namespace: matrix
|
|
annotations:
|
|
configmap.reloader.stakater.com/reload: synapse-config,mas-config
|
|
secret.reloader.stakater.com/reload: synapse-secrets
|
|
labels:
|
|
app.kubernetes.io/name: synapse
|
|
app.kubernetes.io/part-of: matrix
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: synapse
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: synapse
|
|
app.kubernetes.io/part-of: matrix
|
|
spec:
|
|
automountServiceAccountToken: false
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 991
|
|
runAsGroup: 991
|
|
fsGroup: 991
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
initContainers:
|
|
# One-time move of the Synapse accounts (owner, password hash,
|
|
# sessions) into the MAS database. syn2mas needs Synapse offline;
|
|
# this runs before Synapse starts, and Recreate stops the old pod
|
|
# first. The marker on the data PVC makes later starts skip it.
|
|
# Debug image: the plain one has no shell for the marker check.
|
|
- name: migrate-to-mas
|
|
image: ghcr.io/element-hq/matrix-authentication-service:1.26.0-debug@sha256:46f7480f5ea4243ccb6fd2c447ea859e0230c8b3c0e676ee285d4ae6ca344ee3
|
|
command:
|
|
- /busybox/sh
|
|
- -ec
|
|
- |
|
|
if [ -f /data/.syn2mas-done ]; then
|
|
echo "syn2mas already done"; exit 0
|
|
fi
|
|
mas-cli syn2mas migrate \
|
|
--config /mas-config/config.yaml \
|
|
--synapse-config /config/homeserver.yaml \
|
|
--synapse-database-uri postgresql:
|
|
touch /data/.syn2mas-done
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
env:
|
|
# libpq-style variables for the Synapse database; the URI above
|
|
# is empty on purpose.
|
|
- name: PGHOST
|
|
value: mx-pg-rw
|
|
- name: PGUSER
|
|
value: synapse
|
|
- name: PGDATABASE
|
|
value: synapse
|
|
- name: PGPASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: mx-pg-app
|
|
key: password
|
|
resources:
|
|
requests:
|
|
cpu: 10m
|
|
memory: 64Mi
|
|
limits:
|
|
memory: 256Mi
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
readOnly: true
|
|
- name: mas-config
|
|
mountPath: /mas-config
|
|
readOnly: true
|
|
- name: secrets
|
|
mountPath: /secrets
|
|
readOnly: true
|
|
- name: pg
|
|
mountPath: /pg
|
|
readOnly: true
|
|
- name: data
|
|
mountPath: /data
|
|
containers:
|
|
- name: synapse
|
|
image: ghcr.io/element-hq/synapse:v1.162.0@sha256:6b84a7bbac36f080b2d2e51e0289cf1b08b349598ea44a558df38d558f2c2311
|
|
# Bypass /start.py: it expects to run as root and template a config
|
|
# from env. Default mode is generate-missing-and-run, which creates
|
|
# the signing key on first start.
|
|
command:
|
|
- python
|
|
- -m
|
|
- synapse.app.homeserver
|
|
- --config-path
|
|
- /config/homeserver.yaml
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
env:
|
|
- name: PGPASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: mx-pg-app
|
|
key: password
|
|
ports:
|
|
- name: http
|
|
containerPort: 8008
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
limits:
|
|
memory: 1Gi
|
|
# First start runs every schema migration against an empty
|
|
# database; give it up to 10 min.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: http
|
|
periodSeconds: 10
|
|
failureThreshold: 60
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: http
|
|
periodSeconds: 10
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: http
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 4
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
readOnly: true
|
|
- name: secrets
|
|
mountPath: /secrets
|
|
readOnly: true
|
|
- name: data
|
|
mountPath: /data
|
|
- name: tmp
|
|
mountPath: /tmp
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: synapse-config
|
|
- name: secrets
|
|
secret:
|
|
secretName: synapse-secrets
|
|
items:
|
|
- key: registration_shared_secret
|
|
path: registration_shared_secret
|
|
- key: mas_matrix_secret
|
|
path: mas_matrix_secret
|
|
- key: mas_encryption
|
|
path: mas_encryption
|
|
- key: mas_rsa_key
|
|
path: mas_rsa_key
|
|
- key: mas_ec_key
|
|
path: mas_ec_key
|
|
- name: mas-config
|
|
configMap:
|
|
name: mas-config
|
|
- name: pg
|
|
secret:
|
|
secretName: mx-pg-app
|
|
items:
|
|
- key: password
|
|
path: password
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: synapse-data
|
|
- name: tmp
|
|
emptyDir: {}
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: synapse
|
|
namespace: matrix
|
|
spec:
|
|
selector:
|
|
app.kubernetes.io/name: synapse
|
|
ports:
|
|
- name: http
|
|
port: 8008
|
|
targetPort: http
|