diff --git a/app/matrix/prod.jsonnet b/app/matrix/prod.jsonnet new file mode 100644 index 00000000..81b69f0e --- /dev/null +++ b/app/matrix/prod.jsonnet @@ -0,0 +1,208 @@ +# matrix.hackerspace.pl, a matrix/synapse instance +# This needs a secret provisioned, create with: +# kubectl -n matrix create secret generic synapse --from-literal=postgres_password=$(pwgen 24 1) + +local kube = import "../../kube/kube.libsonnet"; +local postgres = import "../../kube/postgres.libsonnet"; + +{ + local app = self, + local cfg = app.cfg, + cfg:: { + namespace: "matrix", + image: "matrixdotorg/synapse:v0.99.3.2", + riotImage: "bubuntux/riot-web:v1.1.0", + domain: "matrix.hackerspace.pl", + serverName: "hackerspace.pl", + storageClassName: "waw-hdd-redundant-1", + }, + + metadata(component):: { + namespace: app.cfg.namespace, + labels: { + "app.kubernetes.io/name": "matrix", + "app.kubernetes.io/managed-by": "kubecfg", + "app.kubernetes.io/component": component, + }, + }, + + namespace: kube.Namespace(app.cfg.namespace), + + postgres: postgres { + cfg+: { + namespace: cfg.namespace, + appName: "synapse", + database: "synapse", + username: "synapse", + password: { secretKeyRef: { name: "synapse", key: "postgres_password" } }, + }, + }, + + dataVolume: kube.PersistentVolumeClaim("synapse-data") { + metadata+: app.metadata("synapse-data"), + spec+: { + storageClassName: cfg.storageClassName, + accessModes: [ "ReadWriteOnce" ], + resources: { + requests: { + storage: "50Gi", + }, + }, + }, + }, + deployment: kube.Deployment("synapse") { + metadata+: app.metadata("synapse"), + spec+: { + replicas: 1, + template+: { + spec+: { + volumes_: { + data: kube.PersistentVolumeClaimVolume(app.dataVolume), + }, + containers_: { + web: kube.Container("synapse") { + image: cfg.image, + ports_: { + http: { containerPort: 8008 }, + }, + env_: { + SYNAPSE_SERVER_NAME: app.cfg.serverName, + SYNAPSE_REPORT_STATS: "no", + SYNAPSE_NO_TLS: "1", + + POSTGRES_HOST: "postgres", + POSTGRES_USER: app.postgres.cfg.username, + POSTGRES_PORT: "5432", + POSTGRES_DB: app.postgres.cfg.database, + POSTGRES_PASSWORD: { secretKeyRef: { name: "synapse", key: "postgres_password" } }, + }, + volumeMounts_: { + data: { mountPath: "/data" }, + }, + }, + }, + }, + }, + }, + }, + + riotConfig: kube.ConfigMap("riot-web-config") { + metadata+: app.metadata("riot-web-config"), + data: { + "config.json": std.manifestJsonEx({ + "default_hs_url": "https://matrix.hackerspace.pl", + "default_is_url": "https://vector.im", + "disable_custom_urls": false, + "disable_guests": false, + "disable_login_language_selector": false, + "disable_3pid_login": false, + "brand": "Riot", + "integrations_ui_url": "https://scalar.vector.im/", + "integrations_rest_url": "https://scalar.vector.im/api", + "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html", + "bug_report_endpoint_url": "https://riot.im/bugreports/submit", + "features": { + "feature_groups": "labs", + "feature_pinning": "labs", + "feature_reactions": "labs" + }, + "default_federate": true, + "default_theme": "light", + "roomDirectory": { + "servers": [ + "matrix.hackerspace.pl" + ] + }, + "welcomeUserId": "@riot-bot:matrix.org", + "piwik": { + "url": "https://piwik.riot.im/", + "whitelistedHSUrls": ["https://matrix.org"], + "whitelistedISUrls": ["https://vector.im", "https://matrix.org"], + "siteId": 1 + }, + "enable_presence_by_hs_url": { + "https://matrix.org": false + } + }, ""), + }, + }, + + riotDeployment: kube.Deployment("riot-web") { + metadata+: app.metadata("riot-web"), + spec+: { + replicas: 1, + template+: { + spec+: { + volumes_: { + config: kube.ConfigMapVolume(app.riotConfig), + }, + containers_: { + web: kube.Container("synapse") { + image: cfg.riotImage, + ports_: { + http: { containerPort: 80 }, + }, + volumeMounts_: { + config: { + mountPath: "/etc/riot-web/config.json", + subPath: "config.json", + }, + }, + }, + }, + }, + }, + }, + }, + + svc: kube.Service("synapse") { + metadata+: app.metadata("synapse"), + target_pod:: app.deployment.spec.template, + spec+: { + ports: [ + { name: "http", port: 8008, protocol: "TCP" }, + ], + type: "ClusterIP", + }, + }, + + riotSvc: kube.Service("riot-web") { + metadata+: app.metadata("riot-web"), + target_pod:: app.riotDeployment.spec.template, + spec+: { + ports: [ + { name: "http", port: 80, protocol: "TCP" }, + ], + type: "ClusterIP", + }, + }, + + ingress: kube.Ingress("synapse") { + metadata+: app.metadata("synapse") { + annotations+: { + "kubernetes.io/tls-acme": "true", + "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", + "nginx.ingress.kubernetes.io/proxy-body-size": "0", + }, + }, + spec+: { + tls: [ + { + hosts: [cfg.domain], + secretName: "synapse-tls", + }, + ], + rules: [ + { + host: cfg.domain, + http: { + paths: [ + { path: "/", backend: app.riotSvc.name_port }, + { path: "/_matrix", backend: app.svc.name_port }, + ] + }, + } + ], + }, + }, +}