--- 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 " ``` --- ## Ресурсы - [Документация 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)