Files
vault-para/100-project/Personal/Software/Matrix Ess Server Install.md
windyboyandClaude Sonnet 4.5 9f6e62676e refactor: Complete vault remediation - fix duplicates, broken links, and add frontmatter
Resolved 48 identified issues across 5 remediation batches:

Critical Fixes (2/2 = 100%):
- Removed duplicate "System Architec" directory with 4 archived files
- Fixed broken PARA Notes wikilinks in 2 Outline.md files

High Priority (14/15 = 93%):
- Consolidated 10+ duplicate file pairs to canonical locations
- Added frontmatter to 30 files in 200-area (now 100% coverage)
- Relocated orphaned image with updated reference
- Removed security-sensitive file duplicates

Medium Priority (32/41 = 78%):
- Deleted 4 empty files (0-15 bytes each)
- Relocated misplaced files to proper PARA categories
- Improved archive organization structure

File Changes:
- Modified: 33 files (frontmatter + wikilink fixes)
- Moved: 16 files (to archive or new locations)
- Deleted: 6 files (duplicates after archival)
- Created: 25 files (archived copies + documentation)

Vault Health Improvement:
- Frontmatter coverage: 43% → 75%
- Broken wikilinks: 2 → 0
- Duplicate files: 10+ → 0
- Empty files: 4 → 0
- Overall health score: 6.5/10 → 8.5/10

Documentation:
- Created comprehensive remediation plan and batch reports in copilot/
- All changes tracked with detailed change reports
- No data loss - duplicates archived, not deleted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 14:36:42 +08:00

425 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Matrix ESS (Community) — SingleNode Install on Debian 13 (K3s + Traefik + certmanager)
_Last updated: 2025-09-25 08:45 UTC_
This guide installs **Element Server Suite (ESS) Community** (Synapse + MAS + Element Web + Matrix RTC) on a **single Debian 13** node using **K3s**, **Traefik** (default in K3s), and **certmanager** with **Lets Encrypt**. It is tailored to your domain choices:
- **serverName**: `chans.xyz`
- **Hosts**: `synapse.chans.xyz`, `account.chans.xyz`, `chat.chans.xyz`, `mrtc.chans.xyz`
> Tip: if you already have K3s and certmanager installed and working, you can jump to **5. Values files** and **6. Install ESS**.
---
## 0) Requirements & Ports
- Debian 13 (root/sudo), public IPv4 (and optional IPv6).
- DNS control for `chans.xyz`.
- Open/forward these ports to this node:
- **80/tcp**, **443/tcp** (ACME + HTTPS + federation)
- **30881/tcp**, **30882/udp** (Matrix RTC SFU)
- Time in sync (`systemd-timesyncd` or equivalent).
---
## 1) DNS Setup
Create A/AAAA records that point to your nodes public IP(s):
```
chans.xyz A / AAAA -> <YOUR_IP>
synapse.chans.xyz A / AAAA -> <YOUR_IP>
account.chans.xyz A / AAAA -> <YOUR_IP>
chat.chans.xyz A / AAAA -> <YOUR_IP>
mrtc.chans.xyz A / AAAA -> <YOUR_IP>
```
Notes:
- **Do not** use a `CNAME` at the **apex** (`chans.xyz`)—use `A/AAAA`. Subdomains can be `CNAME`s if you prefer.
- Federation relies on `https://chans.xyz/.well-known/matrix/server` which the chart serves for you.
---
## 2) (Optional) CloudInit (without firewalld)
If you build the node via cloudinit, this minimal config installs K3s & Helm and disables swap:
```yaml
#cloud-config
package_update: true
package_upgrade: true
packages: [curl, ca-certificates, gnupg, lsb-release]
runcmd:
- swapoff -a
- sed -ri 's/^[^#].*\sswap\s/## &/g' /etc/fstab
- curl -sfL https://get.k3s.io | sh -s - server
- mkdir -p /home/windy/.kube
- cp /etc/rancher/k3s/k3s.yaml /home/windy/.kube/config
- chown windy:windy /home/windy/.kube/config && chmod 600 /home/windy/.kube/config
- bash -lc 'echo export KUBECONFIG=$HOME/.kube/config >> /home/windy/.bashrc'
- su - windy -c "curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash"
```
You can manage ports at the cloud firewall or your router (no `firewalld` required).
---
## 3) Manual K3s + Helm (if not using cloudinit)
```bash
# Install latest K3s
curl -sfL https://get.k3s.io | sh -s - server
# kubeconfig for your user (replace 'windy' if needed)
mkdir -p ~windy/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~windy/.kube/config
sudo chown windy:windy ~windy/.kube/config
chmod 600 ~windy/.kube/config
echo 'export KUBECONFIG=$HOME/.kube/config' | sudo tee -a ~windy/.bashrc
# Helm
sudo -iu windy bash -lc 'curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash'
```
Verify:
```bash
kubectl get nodes -o wide
kubectl get pods -A
```
You should see the node `Ready` and `traefik` running in `kube-system`.
---
## 4) certmanager + Lets Encrypt (ClusterIssuer)
If you havent installed certmanager yet:
```bash
helm repo add jetstack https://charts.jetstack.io --force-update
kubectl create namespace cert-manager 2>/dev/null || true
helm install cert-manager jetstack/cert-manager -n cert-manager --set crds.enabled=true
```
Create a production ClusterIssuer (`letsencrypt-prod`):
```yaml
# clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-private-key
solvers:
- http01:
ingress:
class: traefik
```
Apply:
```bash
kubectl apply -f clusterissuer.yaml
kubectl get clusterissuer
```
You should see `letsencrypt-prod READY=True`.
---
## 5) Values files (hosts + TLS)
Create the directory and values files:
```bash
mkdir -p ~/ess-config-values
```
**`~/ess-config-values/hostnames.yaml`**
```yaml
serverName: chans.xyz
elementWeb:
ingress:
host: chat.chans.xyz
synapse:
ingress:
host: synapse.chans.xyz
matrixAuthenticationService:
ingress:
host: account.chans.xyz
matrixRTC:
ingress:
host: mrtc.chans.xyz
```
**`~/ess-config-values/tls.yaml`**
```yaml
global:
ingress:
className: traefik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
tls:
enabled: true
issuer: letsencrypt-prod
```
> The TLS values ensure your Ingresses are annotated for certmanager and include TLS host entries so Certificates are created automatically.
---
## 6) Install ESS (matrixstack chart)
```bash
kubectl create namespace ess 2>/dev/null || true
helm upgrade --install ess oci://ghcr.io/element-hq/ess-helm/matrix-stack -n ess -f ~/ess-config-values/hostnames.yaml -f ~/ess-config-values/tls.yaml --wait
```
Check status:
```bash
kubectl get pods -n ess
kubectl get ingress -n ess
```
You should see ingresses for `synapse`, `account`, `chat`, `mrtc`, and `well-known` with `CLASS=traefik`.
---
## 7) Certificates issuance
Confirm the ingresses have TLS + issuer:
```bash
kubectl -n ess get ingress -o jsonpath='{range .items[*]}{.metadata.name}{" issuer="}{.metadata.annotations.cert-manager\.io/cluster-issuer}{" tlsHosts="}{range .spec.tls[*].hosts}{.}{" "}{end}{"\n"}{end}'
```
Then watch certs:
```bash
kubectl get certificate -n ess
kubectl get order,challenge -n ess
```
When ready, confirm live certs:
```bash
for h in synapse.chans.xyz account.chans.xyz chat.chans.xyz mrtc.chans.xyz chans.xyz; do
echo "=== $h ==="
openssl s_client -connect "$h:443" -servername "$h" </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject -dates
done
```
---
## 8) WellKnown verification (federation & clients)
```bash
curl -s https://chans.xyz/.well-known/matrix/server | jq .
curl -s https://chans.xyz/.well-known/matrix/client | jq .
```
Expected:
- `server``{ "m.server": "synapse.chans.xyz:443" }`
- `client``{ "m.homeserver": { "base_url": "https://synapse.chans.xyz" }, ... }`
Optional federation tester: <https://federationtester.matrix.org/#chans.xyz>
---
## 9) Create the first admin account
Interactive:
```bash
kubectl exec -n ess -it deploy/ess-matrix-authentication-service -- mas-cli manage register-user --admin
```
Noninteractive example:
```bash
kubectl exec -n ess deploy/ess-matrix-authentication-service -- mas-cli manage register-user --yes --admin --username admin --password 'CHANGE_ME_strong_password'
```
Login at **https://chat.chans.xyz**.
---
## 10) Enable selfregistration (optional)
```yaml
# ~/ess-config-values/mas-registration.yaml
matrixAuthenticationService:
additional:
registration.yaml:
config: |
account:
password_registration_enabled: true
password_recovery_enabled: true
login_with_email_allowed: true
```
Apply (include this file):
```bash
helm upgrade --install ess oci://ghcr.io/element-hq/ess-helm/matrix-stack -n ess -f ~/ess-config-values/hostnames.yaml -f ~/ess-config-values/tls.yaml -f ~/ess-config-values/mas-registration.yaml --wait
```
---
## 11) Outbound email (MAS required, Synapse optional)
### 11.1 MAS SMTP (required for signup/reset)
**Option A — inline values (simple):**
```yaml
# ~/ess-config-values/mas-email.yaml
matrixAuthenticationService:
additional:
user-config.yaml:
config: |
email:
from: '"Matrix @ chans.xyz" <noreply@chans.xyz>'
reply_to: '"Support" <support@chans.xyz>'
transport: smtp
mode: starttls
hostname: smtp.windy.me
port: 587
username: noreply@chans.xyz # authenticate as the sender
password: "MAILBOX_PASSWORD"
account:
password_registration_enabled: true
password_recovery_enabled: true
login_with_email_allowed: true
```
**Option B — secret ref (keeps password out of Git):**
```bash
cat > /tmp/mas-user-config.yaml <<'YAML'
email:
from: '"Matrix @ chans.xyz" <noreply@chans.xyz>'
reply_to: '"Support" <support@chans.xyz>'
transport: smtp
mode: starttls
hostname: smtp.windy.me
port: 587
username: noreply@chans.xyz
password: "MAILBOX_PASSWORD"
account:
password_registration_enabled: true
password_recovery_enabled: true
login_with_email_allowed: true
YAML
kubectl -n ess create secret generic mas-extra-config --from-file=user-config.yaml=/tmp/mas-user-config.yaml
```
Then reference it:
```yaml
# ~/ess-config-values/mas-email-secretref.yaml
matrixAuthenticationService:
additional:
user-config.yaml:
configSecret: mas-extra-config
configSecretKey: user-config.yaml
```
Apply (include one of the two files above):
```bash
helm upgrade --install ess oci://ghcr.io/element-hq/ess-helm/matrix-stack -n ess -f ~/ess-config-values/hostnames.yaml -f ~/ess-config-values/tls.yaml -f ~/ess-config-values/mas-email.yaml --wait
# or replace mas-email.yaml with mas-email-secretref.yaml if you used a Secret
```
> **Mailcow 553 fix**: If authenticating as `zhiqiang@windy.me` and sending as `noreply@chans.xyz`, Mailcow rejects with `553 5.7.1 Sender address rejected`. Either (a) **authenticate as** `noreply@chans.xyz` by creating that mailbox in Mailcow and publishing SPF/DKIM/DMARC for `chans.xyz`; or (b) allow “send as” in Mailcows **Sender ACL** for `zhiqiang@windy.me`. Hosting the `chans.xyz` mailbox gives best deliverability (DKIM/DMARC alignment).
Monitor while testing:
```bash
kubectl -n ess logs deploy/ess-matrix-authentication-service -f | grep -iE 'smtp|email|send'
```
### 11.2 Synapse email notifications (optional)
```yaml
# ~/ess-config-values/synapse-email.yaml
synapse:
additional:
email.yaml:
config: |
email:
smtp_host: "smtp.windy.me"
smtp_port: 587
smtp_user: "noreply@chans.xyz"
smtp_pass: "MAILBOX_PASSWORD"
require_transport_security: true
notif_from: "Matrix on chans.xyz <noreply@chans.xyz>"
enable_notifs: true
```
Include this file in your next Helm upgrade.
---
## 12) Health checks & troubleshooting
**Basic:**
```bash
kubectl get pods,svc,ingress,certificate -n ess -o wide
```
**Certs flow:**
```bash
kubectl get certificate,order,challenge -n ess
kubectl describe challenge -n ess <name>
kubectl logs -n kube-system deploy/traefik --tail=200
```
**Wellknown + federation:**
```bash
curl -s https://chans.xyz/.well-known/matrix/server | jq .
curl -s https://chans.xyz/.well-known/matrix/client | jq .
```
**Common pitfalls:**
- Ingresses lack TLS + `cert-manager.io/cluster-issuer` → fix `tls.yaml`.
- `553 Sender address rejected` from Mailcow → align SMTP auth user with sender or allow “send as”, and set SPF/DKIM/DMARC for `chans.xyz`.
- Port 80 blocked → Lets Encrypt HTTP01 fails (check challenges).
- Apex `chans.xyz` not pointing at the node → `.well-known` fails → federation fails.
---
## 13) Upgrades / Uninstall
Upgrade to latest chart:
```bash
helm repo update # if using repos
helm upgrade --install ess oci://ghcr.io/element-hq/ess-helm/matrix-stack -n ess -f ~/ess-config-values/hostnames.yaml -f ~/ess-config-values/tls.yaml --wait
```
Uninstall ESS (keeps PVCs unless you delete them):
```bash
helm uninstall ess -n ess
kubectl delete namespace ess
```
Reset K3s (if ever needed):
```bash
sudo /usr/local/bin/k3s-uninstall.sh
```
---
## 14) Quick copypaste checklist
1. DNS A/AAAA for: `chans.xyz`, `synapse.`, `account.`, `chat.`, `mrtc.` → your IP.
2. K3s running with Traefik; certmanager installed; `ClusterIssuer letsencrypt-prod` **Ready**.
3. `hostnames.yaml` with `*.ingress.host` set to your subdomains.
4. `tls.yaml` with `global.ingress.annotations.cert-manager.io/cluster-issuer=letsencrypt-prod` and TLS enabled.
5. `helm upgrade --install ess …` with both files.
6. `kubectl get certificate -n ess``READY=True`.
7. `/.well-known` returns correct JSON; federation tester OK.
8. Create admin via MAS CLI; log in at `https://chat.chans.xyz`.
9. Configure SMTP for MAS (and optionally Synapse), fix Mailcow sender policy if needed.