Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y31cBx4B4b56LmzTA9wx76
152 lines
5.0 KiB
Markdown
152 lines
5.0 KiB
Markdown
# GREIF Matrix Chat — Self-Hosted Deployment
|
|
|
|
Komplett selbst gehosteter Matrix-Stack mit Docker Compose: Synapse Homeserver,
|
|
Element Web, Synapse-Admin, Caddy als Reverse Proxy (automatisches HTTPS) und
|
|
PostgreSQL.
|
|
|
|
## Dienste
|
|
|
|
| Dienst | Image | Erreichbar unter |
|
|
|-----------------|----------------------------------------|-------------------------------------------|
|
|
| `synapse` | `matrixdotorg/synapse:latest` | `matrix.greif.life-maps.com` (`/_matrix`) |
|
|
| `element` | `vectorim/element-web:latest` | `element.greif.life-maps.com` |
|
|
| `element-admin` | `awesometechnologies/synapse-admin` | `element-admin.greif.life-maps.com` |
|
|
| `caddy` | `caddy:2-alpine` | Ports 80 / 443 |
|
|
| `db` | `postgres:15` | nur intern |
|
|
| Landing Page | statisch aus `matrix-landing/` | `matrix.greif.life-maps.com` (Root) |
|
|
|
|
Registrierung ist deaktiviert (`enable_registration: false`), Föderation ist
|
|
über eine leere Whitelist abgeschaltet. Max. Upload-Größe: 2 GB.
|
|
|
|
## Voraussetzungen
|
|
|
|
- Linux-Host mit Docker und Docker Compose v2
|
|
- Ports **80** und **443** öffentlich erreichbar (Caddy holt Let's-Encrypt-Zertifikate)
|
|
- DNS-A-Records auf die Server-IP:
|
|
- `matrix.greif.life-maps.com`
|
|
- `element.greif.life-maps.com`
|
|
- `element-admin.greif.life-maps.com`
|
|
|
|
## Aufsetzen
|
|
|
|
### 1. Repo klonen
|
|
|
|
```bash
|
|
git clone <gitea-url> matrix-deployment
|
|
cd matrix-deployment
|
|
```
|
|
|
|
### 2. Signing Key erzeugen
|
|
|
|
Erzeugt `synapse/matrix.greif.life-maps.com.signing.key` (und eine
|
|
Default-`homeserver.yaml`, die im nächsten Schritt überschrieben wird):
|
|
|
|
```bash
|
|
docker run --rm \
|
|
-v "$PWD/synapse:/data" \
|
|
-e SYNAPSE_SERVER_NAME=matrix.greif.life-maps.com \
|
|
-e SYNAPSE_REPORT_STATS=no \
|
|
matrixdotorg/synapse:latest generate
|
|
```
|
|
|
|
### 3. Konfiguration und Secrets anlegen
|
|
|
|
```bash
|
|
cp synapse/homeserver.yaml.example synapse/homeserver.yaml
|
|
cp secrets/db_password.txt.example secrets/db_password.txt
|
|
```
|
|
|
|
Vier Werte ersetzen — alle `CHANGE_ME_*` Platzhalter:
|
|
|
|
```bash
|
|
# je einen zufälligen Wert erzeugen
|
|
openssl rand -base64 36
|
|
```
|
|
|
|
- `secrets/db_password.txt` → DB-Passwort (ohne Zeilenumbruch am Ende ist ok)
|
|
- `synapse/homeserver.yaml`:
|
|
- `database.args.password` → **muss identisch** zu `secrets/db_password.txt` sein
|
|
- `registration_shared_secret`
|
|
- `macaroon_secret_key`
|
|
- `form_secret`
|
|
|
|
> Das DB-Passwort wird nur beim **ersten** Start in die Datenbank geschrieben.
|
|
> Wird es später geändert, muss es auch in Postgres geändert werden.
|
|
|
|
### 4. Rechte für die Volumes
|
|
|
|
Synapse läuft im Container als UID/GID 991:
|
|
|
|
```bash
|
|
mkdir -p synapse/media_store postgres caddy/data caddy/config
|
|
sudo chown -R 991:991 synapse
|
|
```
|
|
|
|
### 5. Starten
|
|
|
|
```bash
|
|
docker compose up -d
|
|
docker compose logs -f synapse
|
|
```
|
|
|
|
Caddy stellt die Zertifikate beim ersten Aufruf automatisch aus. Danach ist die
|
|
Landing Page unter `https://matrix.greif.life-maps.com` erreichbar.
|
|
|
|
### 6. Ersten Benutzer anlegen
|
|
|
|
Da die Registrierung deaktiviert ist, wird der Admin-Account über das
|
|
`registration_shared_secret` erstellt:
|
|
|
|
```bash
|
|
docker compose exec synapse \
|
|
register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
|
|
```
|
|
|
|
Anmeldung danach über `https://element.greif.life-maps.com`,
|
|
Benutzerverwaltung über `https://element-admin.greif.life-maps.com`
|
|
(Homeserver-URL dort: `https://matrix.greif.life-maps.com`).
|
|
|
|
## Betrieb
|
|
|
|
```bash
|
|
docker compose ps # Status
|
|
docker compose logs -f synapse # Logs
|
|
docker compose restart synapse # nach Config-Änderung
|
|
docker compose pull && docker compose up -d # Updates einspielen
|
|
docker compose down # stoppen
|
|
```
|
|
|
|
**Datenbank-Backup:**
|
|
|
|
```bash
|
|
docker compose exec db pg_dump -U matrix synapse > backup-$(date +%F).sql
|
|
```
|
|
|
|
**Vollständiges Backup** = DB-Dump + `synapse/media_store/` +
|
|
`synapse/*.signing.key` + `synapse/homeserver.yaml` + `secrets/`.
|
|
Ohne den Signing Key verlieren alle bestehenden Räume ihre Server-Identität —
|
|
er ist nicht ersetzbar.
|
|
|
|
## Was nicht im Repo liegt
|
|
|
|
Per `.gitignore` ausgeschlossen, weil Secrets oder Laufzeitdaten:
|
|
|
|
- `secrets/` — DB-Passwort (Vorlage: `secrets/db_password.txt.example`)
|
|
- `synapse/homeserver.yaml` — enthält DB-Passwort und drei Secrets
|
|
(Vorlage: `synapse/homeserver.yaml.example`)
|
|
- `synapse/*.signing.key` — Server-Identität
|
|
- `postgres/`, `synapse/media_store/`, `caddy/data/`, `caddy/config/` — Volumes
|
|
- Logs, Backups und Dumps
|
|
|
|
## Struktur
|
|
|
|
```
|
|
docker-compose.yml Stack-Definition
|
|
caddy/Caddyfile Reverse Proxy, Routing der drei Subdomains
|
|
element/config.json Element-Web-Konfiguration (Homeserver, Jitsi)
|
|
synapse/homeserver.yaml Synapse-Konfiguration (nicht im Repo)
|
|
synapse/*.log.config Logging-Konfiguration
|
|
matrix-landing/ statische Landing Page (index.html + Assets)
|
|
secrets/ DB-Passwort als Docker Secret (nicht im Repo)
|
|
```
|