Files
ermnvldmr.com/services/www/content/articles/2026/matrix-server-deployment-guide.ru.mdx
T
deytenit b3638f4d63 fix: cyrillic fonts, dev certs, page head, and ru-text typography (#67)
🤖 PR generated for branch `fix/cyrillic-fonts-dev-certs-and-page-head`.

### Changes Summary
- **Fonts**: Add Cyrillic glyph subsets for Lato, EB Garamond, and Fira
Code.
- **Dev**: Support remote Root CA and encrypted dev CA key in
`.env.dev`.
- **UI & Kits**: Add size variant to `Breadcrumbs` component and enlarge
`PageHead` breadcrumbs with tuned collapse scroll threshold.
- **ESLint**: Add `no-hanging-particles` i18n & markdown typography rule
with auto-fixer.
- **Content & i18n**: Apply `ru-text` editorial and typography polish
(em dashes, number ranges, «ё» restoration, non-breaking spaces) across
`services/www` and `services/docs`.
2026-10-25 15:21:09 +03:00

436 lines
21 KiB
Plaintext
Raw 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.
---
title: 'Руководство по развёртыванию Matrix-сервера'
description: 'Разбор архитектуры и развёртывание Synapse, Coturn, LiveKit SFU и Native Matrix RTC'
createdDate: 2026-02-15
tags: ['self-hosting', 'guides', 'matrix']
---
Развёртывание полноценного стека связи Matrix не ограничивается запуском одного веб-сервера. Matrix — открытый децентрализованный протокол для голосовой связи и обмена сообщениями со сквозным шифрованием в реальном времени. Если для текстовых чатов достаточно базового homeserver и базы данных, то современные мультимедийные возможности — от личных WebRTC-звонков 1:1 до групповых видеоконференций — требуют специализированных медиарелеев и мостов аутентификации.
В статье разберём устройство и пошаговое развёртывание стека Matrix для продакшена на базе **Synapse**, **PostgreSQL**, **Coturn**, **LiveKit SFU** и **lk-jwt-service**.
---
## Архитектура технического стека
Чтобы понять взаимодействие компонентов, разберём задачи каждого из шести ключевых компонентов:
1. **Synapse**: Основной движок homeserver. Управляет аутентификацией пользователей, состоянием комнат, синхронизацией сообщений, обменом ключами сквозного шифрования (E2EE) и федерацией с другими серверами в глобальной сети Matrix.
2. **PostgreSQL**: Реляционная база данных для Synapse. Если для коротких локальных тестов Synapse допускает SQLite, то в продакшене PostgreSQL обязателен для обработки параллельных транзакций, индексации комнат и истории сообщений.
3. **Coturn (STUN/TURN)**: Сервер ретрансляции для обхода NAT. При звонке 1:1 устройства пытаются установить прямое peer-to-peer WebRTC-соединение. Если между участниками есть симметричный NAT или фаервол, Coturn служит ретранслятором и передаёт зашифрованные аудио- и видеопакеты по протоколам UDP или TCP.
4. **LiveKit SFU**: Высокопроизводительный Selective Forwarding Unit. Соединение peer-to-peer становится неэффективным при групповых звонках от трёх участников. LiveKit принимает аудио- и видеопотоки каждого спикера и пересылает их остальным участникам, существенно экономя исходящий интернет-трафик клиентов.
5. **lk-jwt-service**: Мост аутентификации для Element Call и Element X Native Matrix RTC (стандарты MSC4143 и MSC4186). Когда пользователь входит в групповой звонок в Element X, `lk-jwt-service` проверяет его сессию в Synapse и генерирует временный токен JWT для подключения к комнате LiveKit.
6. **Обратный прокси (Traefik / Nginx)**: Входной шлюз. Терминирует SSL-сертификаты, обрабатывает WebSocket-соединения для сигнализации LiveKit (`/livekit`), проставляет заголовки CORS для веб-клиентов и отдаёт файлы автообнаружения `.well-known`.
---
## 1. Инфраструктура Docker (docker-compose.yml)
Контейнеризация обеспечит изоляцию сервисов, правильный порядок их запуска и предсказуемую сетевую связность.
В конфигурации Compose для PostgreSQL настроена проверка готовности (`pg_isready`), чтобы Synapse не запускался до полной инициализации базы данных. Дополнительные сервисы, такие как Coturn, LiveKit и `lk-jwt-service`, используют сетевой режим `network_mode: "service:synapse"` или выделенные сети контейнеров, что пробрасывает порты WebRTC и STUN/TURN непосредственно на хост.
Для корректной передачи медиапотоков открываются следующие диапазоны портов:
- **Порты 3478 и 5349 (TCP/UDP)**: Сигнализация Coturn STUN и TURN.
- **Диапазон 49152–49172 (UDP)**: Динамические каналы ретрансляции медиа Coturn.
- **Порт 7880 (TCP)**: HTTP-сигнализация и WebSockets в LiveKit.
- **Порт 7881 (TCP)**: Резервный TCP-порт для WebRTC в LiveKit.
- **Диапазон 50000–50020 (UDP)**: Каналы передачи медиа в LiveKit SFU.
Итоговый файл `docker-compose.yml`:
```yaml
networks:
matrix:
name: matrix-network
volumes:
synapse_data:
postgres_data:
services:
postgres:
image: postgres:16-alpine
container_name: matrix-db
environment:
POSTGRES_DB: synapse
POSTGRES_USER: synapse
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_INITDB_ARGS: '--encoding=UTF-8 --lc-collate=C --lc-ctype=C'
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- matrix
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U synapse -d synapse']
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped
synapse:
image: ghcr.io/element-hq/synapse:v1.146.0
container_name: matrix-synapse
depends_on:
postgres:
condition: service_healthy
environment:
SYNAPSE_SERVER_NAME: '${DOMAIN}'
SYNAPSE_REPORT_STATS: 'no'
SYNAPSE_CONFIG_PATH: '/data/homeserver.yaml'
volumes:
- ./homeserver.yaml:/data/homeserver.yaml:ro
- synapse_data:/data
networks:
- matrix
ports:
# Matrix Client & Federation HTTP API
- '8008:8008'
# Порты сигнализации Coturn STUN/TURN
- '3478:3478/tcp'
- '3478:3478/udp'
- '5349:5349/tcp'
- '5349:5349/udp'
# Диапазон UDP-портов для медиа-релея Coturn
- '49152-49172:49152-49172/udp'
# Порты LiveKit HTTP/WebSocket и WebRTC
- '7880:7880/tcp'
- '7881:7881/tcp'
- '50000-50020:50000-50020/udp'
restart: unless-stopped
coturn:
image: coturn/coturn:4.8-alpine
container_name: matrix-coturn
depends_on:
- synapse
volumes:
- ./turnserver.conf:/etc/coturn/turnserver.conf:ro
network_mode: 'service:synapse'
command: ['-c', '/etc/coturn/turnserver.conf']
restart: unless-stopped
livekit:
image: livekit/livekit-server:v1.9
container_name: matrix-livekit
depends_on:
- synapse
volumes:
- ./livekit.yaml:/etc/livekit.yaml:ro
environment:
LIVEKIT_KEYS: '${LK_KEY}: ${LK_SECRET}'
network_mode: 'service:synapse'
command: --config /etc/livekit.yaml --node-ip ${SERVER_IP}
restart: unless-stopped
lk-jwt:
image: ghcr.io/element-hq/lk-jwt-service:0.4.1
container_name: matrix-lk-jwt
depends_on:
- synapse
environment:
LK_JWT_PORT: 8080
LIVEKIT_URL: wss://${DOMAIN}/livekit
LIVEKIT_KEY: '${LK_KEY}'
LIVEKIT_SECRET: '${LK_SECRET}'
network_mode: 'service:synapse'
restart: unless-stopped
```
---
## 2. Конфигурация Homeserver (homeserver.yaml)
Synapse использует `homeserver.yaml` для определения правил работы. Разберём ключевые блоки:
- **Идентификация сервера (`server_name`)**: Определяет доменное имя сервера и суффикс ID пользователей (например, `@user:matrix.example.com`). Изменение этого имени в будущем приведёт к потере связей с другими серверами и поломке ID комнат.
- **Подключение к базе данных (`database`)**: Настраивает подключение к PostgreSQL через модуль `psycopg2`. Параметры `cp_min` и `cp_max` управляют пулом соединений при нагрузке.
- **Ротация медиафайлов (`media_retention`)**: Участники комнат постоянно отправляют фото и файлы. Параметр `remote_media_lifetime: 14d` очищает кэш файлов с чужих серверов каждые 14 дней, экономя дисковое пространство (локальные файлы хранятся в течение года: `local_media_lifetime: 365d`).
- **Интеграция VoIP (`turn_uris` и `turn_shared_secret`)**: Передаёт Synapse параметры Coturn. При звонке 1:1 Synapse с помощью `turn_shared_secret` генерирует временные логин и пароль для безопасного подключения к TURN-релею.
- **Native Matrix RTC (MSC4143 / MSC4186)**: Современные клиенты, такие как Element X и Element Call, используют спецификации MSC4143 (RTC Foci) и MSC4186 (LiveKit Call Authentication). Блок `extra_well_known_client_content` сообщает клиенту, что выпиской токенов для звонков занимается сервис `lk-jwt-service` по адресу `https://matrix.example.com/livekit/jwt`.
Полный файл `homeserver.yaml`:
```yaml
# Идентификация сервера
server_name: "matrix.example.com"
pid_file: /data/homeserver.pid
public_baseurl: "https://matrix.example.com"
# Слушатели (Listeners)
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
# База данных
database:
name: psycopg2
args:
user: "synapse"
password: "YOUR_POSTGRES_PASSWORD"
database: "synapse"
host: "postgres"
cp_min: 5
cp_max: 10
# Безопасность и регистрация
enable_registration: false
enable_registration_captcha: false
registration_shared_secret: "YOUR_REGISTRATION_SHARED_SECRET"
# Хранение файлов и ротация
media_store_path: "/data/media_store"
max_upload_size: "50M"
max_image_pixels: "32M"
dynamic_thumbnails: true
media_retention:
remote_media_lifetime: 14d
local_media_lifetime: 365d
caches:
global_factor: 0.5
# VoIP / Coturn (Звонки 1:1)
turn_uris:
- "turn:matrix.example.com:3478?transport=udp"
- "turn:matrix.example.com:3478?transport=tcp"
turn_shared_secret: "YOUR_TURN_SHARED_SECRET"
turn_user_lifetime: 1h
turn_allow_guests: true
# Native Matrix RTC (MSC4143 / MSC4186 для звонков в Element X)
experimental_features:
msc3266_enabled: true
msc4222_enabled: true
serve_server_wellknown: true
extra_well_known_client_content:
"org.matrix.msc4186.stable": {"enabled": true}
"org.matrix.msc4143.rtc_foci": [
{
"type": "livekit",
"livekit_service_url": "https://matrix.example.com/livekit/jwt"
}
]
report_stats: false
```
---
## 3. Конфигурация LiveKit SFU (livekit.yaml)
LiveKit распределяет медиапотоки участников групповых звонков. Основные директивы в `livekit.yaml`:
- **`bind_addresses` и `port`**: Задаёт служебный HTTP-порт и WebSockets на порту `7880`.
- **`rtc.use_external_ip: true`**: Необходимая опция для серверов за NAT: указывает LiveKit определять публичный IP-адрес хоста (`--node-ip`) и передавать его подключающимся клиентам.
- **`rtc.port_range_start` и `rtc.port_range_end`**: Ограничивают диапазон динамических UDP-портов WebRTC: от `50000` до `50020`.
- **`room.auto_create: true`**: Разрешает автоматическое создание комнат при получении валидного JWT-токена от `lk-jwt-service`.
Конфигурационный файл `livekit.yaml`:
```yaml
port: 7880
bind_addresses:
- 0.0.0.0
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 50020
use_external_ip: true
room:
auto_create: true
logging:
level: info
```
---
## 4. Конфигурация Coturn Relay (turnserver.conf)
Coturn обеспечивает ретрансляцию трафика для звонков 1:1. Ключевые опции в `turnserver.conf`:
- **`listening-port=3478`**: Стандартный порт для приёма STUN/TURN-запросов по UDP и TCP.
- **`external-ip`**: Задаёт публичный IP-адрес сервера для корректного формирования адресов ретрансляции.
- **`min-port` и `max-port`**: Ограничивают диапазон динамических UDP-портов: от `49152` до `49172`.
- **`use-auth-secret` и `static-auth-secret`**: Включают авторизацию по секрету, совпадающему с `turn_shared_secret` в `homeserver.yaml`.
- **`realm`**: Доменное имя сервера, необходимое для проверки HMAC-токенов.
- **`no-multicast-peers`**: Блокирует попытки использовать релей для сканирования внутренних адресов сети.
Конфигурация `turnserver.conf`:
```conf
listening-port=3478
listening-ip=0.0.0.0
# Публичный IP-адрес вашего сервера
external-ip=203.0.113.10
min-port=49152
max-port=49172
fingerprint
use-auth-secret
static-auth-secret=YOUR_TURN_SHARED_SECRET
realm=matrix.example.com
total-quota=100
stale-nonce=600
log-file=stdout
simple-log
no-multicast-peers
```
---
## 5. Переменные окружения и генерация секретов (.env)
Вынос паролей и ключей в переменные окружения предотвращает их попадание в конфигурационные файлы и репозитории.
Секреты `DB_PASSWORD`, `LK_SECRET` и `TURN_SECRET` должны быть криптографически стойкими строками. Для их генерации подойдёт утилита `openssl`.
Шаблон файла `.env`:
```bash
# Инфраструктура
DOMAIN=matrix.example.com
SERVER_IP=203.0.113.10
ADMIN_EMAIL=admin@example.com
# База данных
DB_PASSWORD=YOUR_POSTGRES_PASSWORD
# LiveKit (Групповые звонки)
LK_KEY=matrix_lk_key
LK_SECRET=YOUR_LIVEKIT_SECRET
# Coturn (Звонки 1:1)
TURN_SECRET=YOUR_TURN_SHARED_SECRET
```
Генерация секретов с помощью OpenSSL:
```bash
# Выполните для создания DB_PASSWORD, LK_SECRET и TURN_SECRET
openssl rand -hex 32
```
---
## 6. Обратный прокси и автообнаружение (.well-known)
Обратный прокси перенаправляет внешние запросы к нужным сервисам и выполняет требования веб-клиентов:
1. **Заголовки CORS**: Веб-клиенты Element Web и Element Call выполняют междоменные запросы. Прокси должен возвращать заголовки `Access-Control-Allow-*`.
2. **Проксирование WebSockets (`/livekit/`)**: Для работы LiveKit необходимо проксирование постоянных WebSocket-соединений (`Upgrade: $http_upgrade` и `Connection: "Upgrade"`).
3. **Автообнаружение (`/.well-known/matrix/client` и `/.well-known/matrix/server`)**: Клиенты Matrix запрашивают эти URL при входе, чтобы автоматически определить адрес сервера и сервиса LiveKit JWT без указания нестандартных портов вручную.
Пример конфигурации **Nginx**:
```nginx
server {
listen 443 ssl http2;
server_name matrix.example.com;
ssl_certificate /etc/letsencrypt/live/matrix.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/matrix.example.com/privkey.pem;
# CORS-заголовки для веб-клиентов (Element Web / Element Call)
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Matrix-User-ID" always;
if ($request_method = 'OPTIONS') {
return 204;
}
# API клиентов и федерации Matrix
location /_matrix {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 50M;
}
# Сигнализация LiveKit SFU (WebSockets)
location /livekit/ {
rewrite ^/livekit/(.*) /$1 break;
proxy_pass http://127.0.0.1:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
# Сервис выписки JWT-токенов LiveKit для Element X
location /livekit/jwt/ {
rewrite ^/livekit/jwt/(.*) /$1 break;
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
# Автообнаружение клиента Matrix (.well-known)
location /.well-known/matrix/client {
default_type application/json;
return 200 '{"m.homeserver":{"base_url":"https://matrix.example.com"},"org.matrix.msc4186.stable":{"enabled":true},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://matrix.example.com/livekit/jwt"}]}';
}
# Автообнаружение федерации Matrix (.well-known)
location /.well-known/matrix/server {
default_type application/json;
return 200 '{"m.server":"matrix.example.com:443"}';
}
}
```
---
## 7. Создание аккаунтов и обслуживание
При отключённой публичной регистрации (`enable_registration: false`) новые аккаунты создаются вручную.
### Регистрация администратора через CLI
Выполните команду `register_new_matrix_user` внутри контейнера Synapse:
```bash
docker exec -it matrix-synapse register_new_matrix_user \
-c /data/homeserver.yaml http://localhost:8008 \
--user admin --password "SECURE_USER_PASSWORD" --admin
```
### Настройка SMTP для писем
Чтобы включить функцию восстановления паролей и подтверждения почты, добавьте блок `email` в `homeserver.yaml`:
```yaml
email:
smtp_host: "smtp.example.com"
smtp_port: 587
smtp_user: "notifications@example.com"
smtp_pass: "YOUR_SMTP_PASSWORD"
require_transport_security: true
notif_from: "Matrix Server <notifications@example.com>"
```
---
## Ресурсы
- [Документация Synapse](https://element-hq.github.io/synapse/)
- [Документация LiveKit Server](https://docs.livekit.io/)
- [Element lk-jwt-service GitHub](https://github.com/element-hq/lk-jwt-service)
- [MSC4143: Native Matrix RTC Foci](https://github.com/matrix-org/matrix-spec-proposals/pull/4143)
- [MSC4186: LiveKit Call Authentication](https://github.com/matrix-org/matrix-spec-proposals/pull/4186)