Files
vps/hosts/synapse.chans.xyz.md
windyboy c0c975584a docs(plane): 自托管 Plane 落地事实入仓库 + plane-health runbook + hardening 草稿
记录源 Linear→Plane (2026-09-03 起, Plane MCP) + plane.chans.xyz 服务行/upstream 段;
inventory + hosts/synapse.chans.xyz.md 补 Plane 部署事实 (Helm plane-ce-1.8.0 / app v1.4.1,
ns plane, IngressRoute/自有证书 issuer/PVC 5+5Gi local-path/无备份层);
新增 runbooks/plane-health.md (只读健康检查) 与 docs/plane-hardening/ 草稿
(values.hardened.yaml、secrets.yaml.example 占位、backup/ CronJob), 均为未应用设计稿;
.gitignore 增加 .tmp-* agent 临时文件。
2026-09-13 19:12:32 +08:00

6.5 KiB

synapse.chans.xyz — Matrix homeserver (ESS)

Role

Matrix homeserver running Element Server Suite (ESS) Community: Synapse + Matrix Authentication Service (MAS) + Element Web + Element Admin.

SSH

ssh -4 windy@synapse.chans.xyz
  • User: windy (sudo via Ansible)
  • IPv4: 169.58.86.13
  • OS: Ubuntu 26.04

Stack

Layer Detail
Runtime K3s v1.36.2+k3s1 (single-node)
Ingress K3s built-in Traefik (hostPort :80 / :443)
TLS cert-manager v1.19.3 + letsencrypt-prod ClusterIssuer (HTTP-01)
DB ESS embedded PostgreSQL 17 (PVC 20Gi, local-path)
Cache ESS embedded Redis (PVC 2Gi)
Chart oci://ghcr.io/element-hq/ess-helm/matrix-stack, version 26.7.2
Plane Helm plane-ce-1.8.0 (app v1.4.1), namespace plane — self-hosted Plane project management

Matrix service endpoints

URL Component
https://chat.chans.xyz Element Web
https://synapse.chans.xyz Synapse Client-Server / Federation API
https://account.chans.xyz Matrix Authentication Service
https://admin.chans.xyz Element Admin console
https://chans.xyz/.well-known/matrix/server Federation discovery → synapse.chans.xyz:443
https://chans.xyz/.well-known/matrix/client Client discovery → https://synapse.chans.xyz
mrtc.chans.xyz Reserved for MatrixRTC (not deployed)

Public ports

Port Protocol Service
22/tcp SSH OpenSSH
80/tcp HTTP Let's Encrypt HTTP-01 / Traefik redirect
443/tcp HTTPS Matrix Client-Server, Federation, Element, MAS, Admin

All other ports internal only (no K3s API, no database, no Redis exposed).

Namespace layout

  • ess — all ESS workloads (Synapse, MAS, Element, Postgres, Redis, HAProxy)
  • matrix-system — cluster base resources (ResourceQuota, LimitRange, mrtc-placeholder)
  • plane — Plane project management (Helm release plane-app)
  • cert-manager — cert-manager

Plane (project management)

Self-hosted Plane on the same K3s node, deployed via the official plane-ce Helm chart.

Item Detail
Release plane-app (ns plane), chart plane-ce-1.8.0, app v1.4.1, revision 1
URL https://plane.chans.xyz
Install date 2026-09-01
Values source /home/windy/plane-k3s/values.yaml (plain file, not a git repo)
Images artifacts.plane.so/makeplane/* (plane-frontend, plane-backend, plane-admin, plane-live), pullPolicy Always
Ingress Traefik IngressRoute plane-app-ingress/→web, /api /auth→api, /spaces→space, /god-mode→admin, /live→live, /uploads→minio; maxRequestBodyBytes 20Mi
TLS Own namespace Issuer plane-app-cert-issuer (HTTP-01, LE prod, admin@chans.xyz); cert plane-app-ssl-cert (CN plane.chans.xyz)
DB Bundled Postgres 15.7-alpine (PVC 5Gi, local-path)
Cache/queue Bundled Redis (PVC 100Mi), RabbitMQ 3.13.6-management-alpine (PVC 100Mi)
Storage Bundled MinIO (minio/minio:latest, root user admin, PVC 5Gi) — S3 for uploads/docs
Resources Every workload: cpu 50m/500m, mem 50Mi/1000Mi, replicas 1
SMTP Not configured (no smtp values) — Plane invites/password resets won't email yet

Workloads (all 1/1 Running): 7 Deployments (plane-app-{admin,api,beat-worker,live,space,web,worker}-wl) + 4 StatefulSets (plane-app-{minio,pgdb,rabbitmq,redis}-wl); init Jobs api-migrate-1 / minio-bucket-1 Completed. All PVCs Bound on local-path (root disk).

Plane configuration notes

  • planeVersion: v1.4.1 pinned in values.yaml; chart tracks Plane's own tags.
  • Secrets: Helm-generated Opaque secrets (plane-app-app-secrets, -doc-store-secrets, -pgdb-secrets, -rabbitmq-secrets, -live-secrets); requireExplicitSecrets: false. Values live in $SECRET_KEY, DATABASE_URL, AMQP_URL, REDIS_URL etc.
  • Sentry / CORS: sentry_dsn and cors_allowed_origins empty (defaults fine for single-host).
  • MinIO is latest tag — pin a version for reproducibility.
  • Backup: NOT covered by /var/backups/matrix (which is paused anyway) — Plane Postgres/MinIO PVCs have no backup tier yet.

Plane verification

# Release + workloads
sudo helm list -A
sudo k3s kubectl -n plane get deploy,sts,pods -o wide
# Cert + ingress
sudo k3s kubectl -n plane get certificate,ingressroute
# Endpoint
curl -4 -s -o /dev/null -w '%{http_code}\n' https://plane.chans.xyz/

Local backup

Item Detail
Path /var/backups/matrix (root:root, 0700)
Schedule Pausedmatrix-backup.timer is disabled pending a reviewed backup design
Retention 7 days
Disk warning 80% (healthcheck), 90% (backup stops)
Content Planned: PostgreSQL synapse + mas logical dumps, media store archive, /etc/matrix-bootstrap
Status Not operational — no current Matrix backup or recovery tier. Plane data (its own Postgres + MinIO PVCs in ns plane) is also not covered by any backup.

Health checks

Daily via matrix-k3s-healthcheck.timer, outputs to /var/lib/vps-health/latest.json. Checks:

  • K3s API / namespace health
  • ESS pod restart counts
  • Backup freshness
  • Root disk usage
  • Certificate expiry
  • External HTTPS endpoints

Bootstrap secrets

Path: /etc/matrix-bootstrap/ (root:root, 0700) — individual files per secret key (0600). SMTP password, DB passwords, signing key etc. Included in local backup.

Identity

  • Server name: chans.xyz (user IDs: @user:chans.xyz)
  • Deployment type: New instance (no recovery from previous homeserver)
  • Public registration: Disabled
  • Authentication: MAS local passwords

Ansible

Inventory group: matrix_production (but NOT in managed which expects Docker Compose).

Routine status: cd ansible && ansible-playbook playbooks/health-report.yml --limit matrix. Use matrix-preflight.yml before a Matrix/K3s change, and use the gated matrix-stack.yml to apply a reviewed ESS chart version. Playbooks are in ansible/playbooks/matrix-*.yml; direct SSH is reserved for focused K3s diagnosis and imperative recovery work.

Known limitations

  • MatrixRTC / Element Call / LiveKit / Coturn not deployed (mrtc.chans.xyz reserved only)
  • SMTP email not yet configured (requires manual secret bootstrap followed by a reviewed Ansible stack deployment)
  • Plane minio image uses latest tag (pin a version)
  • No off-site Restic backup
  • Single-node K3s (no HA for control plane)