Установка Matrix

20 марта 2026
5

Полный гайд: Matrix Synapse + PostgreSQL + Element + Synapse-Admin в Docker Compose

Содержание

  1. Введение

  2. Требования к серверу

  3. Установка Docker и Docker Compose

  4. Подготовка структуры директорий и переменных окружения

  5. Создание файла docker-compose.yml

  6. Настройка базы данных PostgreSQL

  7. Конфигурация Synapse (homeserver.yaml)

  8. Настройка клиентской части и админ-панели

  9. Конфигурация Nginx

  10. Получение SSL-сертификатов

  11. Запуск сервисов

  12. Создание пользователей через консоль

  13. Автоматическое обновление сертификатов

  14. Управление и обслуживание

  15. Проверка работоспособности


Введение

Протокол Matrix стал стандартом для организации безопасных коммуникаций с поддержкой сквозного шифрования. В этой статье мы рассмотрим развертывание полного стека сервисов (сервер Synapse, база данных PostgreSQL, веб-клиент Element и панель администратора) в изолированной среде Docker.

Использование Docker Compose позволяет описать всю инфраструктуру в одном файле конфигурации, что упрощает развертывание, обновление и перенос сервера между хостинг-провайдерами.

Требования к серверу

Для установки потребуется VDS или выделенный сервер со следующими характеристиками:

  • ОС: Ubuntu 22.04 или 24.04 LTS.

  • Домен: Зарегистрированное доменное имя.

  • DNS-записи: Необходимо настроить A-записи для трех поддоменов, указывающих на IP-адрес сервера:

    • matrix.sitename.ru (для API сервера)
    • element.sitename.ru (для веб-клиента)
    • matrix-admin.sitename.ru (для панели управления)
  • Порты: В фаерволе должны быть открыты порты 80, 443, 8448 (TCP) и 3478, 5349 (UDP/TCP для голосовых звонков).

Вместо sitename.ru используйте имя вашего сайта

Установка Docker и Docker Compose

Обновим пакеты системы и установим Docker Engine вместе с плагином Compose.

apt update && apt upgrade -y

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

apt install docker-compose-plugin -y

docker --version
docker compose version

Вернуться к содержанию

Подготовка структуры директорий и переменных окружения

Создадим корневую директорию для проекта и подпапки для конфигураций каждого сервиса.

mkdir -p /opt/matrix-stack/{synapse,element,synapse-admin,postgres,coturn,nginx,certs}
cd /opt/matrix-stack

Для безопасности работы сервисов необходимо сгенерировать случайные секретные ключи. Создадим файл .env, в котором будут храниться пароли и доменные имена.

REGISTRATION_SECRET=$(openssl rand -hex 32)
TURN_SECRET=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$(openssl rand -hex 32)
MACAROON_SECRET=$(openssl rand -hex 32)

cat > .env << EOF
DOMAIN=matrix.sitename.ru
ELEMENT_DOMAIN=element.sitename.ru
ADMIN_DOMAIN=matrix-admin.sitename.ru
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
REGISTRATION_SECRET=${REGISTRATION_SECRET}
TURN_SECRET=${TURN_SECRET}
MACAROON_SECRET=${MACAROON_SECRET}
EOF

chmod 600 .env
source .env

Важно: Сохраните файл .env в надежном месте. Потеря секретных ключей сделает невозможным восстановление доступа к существующим аккаунтам при переустановке сервера.

Вернуться к содержанию

Создание файла docker-compose.yml

В корневой директории создадим файл docker-compose.yml. Он описывает все необходимые контейнеры, сети и тома.

services:
  postgres:
    image: postgres:15-alpine
    container_name: matrix-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: matrix
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: postgres
    volumes:
      - ./postgres//var/lib/postgresql/data
      - ./postgres/init:/docker-entrypoint-initdb.d:ro
    networks:
      - matrix-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U matrix -d matrix"]
      interval: 10s
      timeout: 5s
      retries: 5

  synapse:
    image: ghcr.io/matrix-org/synapse:latest
    container_name: matrix-synapse
    user: "0:0"
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      - SYNAPSE_SERVER_NAME=${DOMAIN}
      - SYNAPSE_REPORT_STATS=no
      - SYNAPSE_CONFIG_PATH=/conf/homeserver.yaml
    volumes:
      - ./synapse//data
      - ./synapse/config:/conf
      - ./synapse/media:/media
    networks:
      - matrix-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8008/_matrix/client/versions"]
      interval: 30s
      timeout: 10s
      retries: 3

  element:
    image: docker.io/vectorim/element-web:latest
    container_name: matrix-element
    restart: unless-stopped
    volumes:
      - ./element/config.json:/app/config.json:ro
    networks:
      - matrix-network
    depends_on:
      - synapse

  synapse-admin:
    image: docker.io/awesometechnologies/synapse-admin:latest
    container_name: matrix-synapse-admin
    restart: unless-stopped
    environment:
      - REACT_APP_SERVER=https://${DOMAIN}
    networks:
      - matrix-network
    depends_on:
      - synapse

  coturn:
    image: docker.io/coturn/coturn:latest
    container_name: matrix-coturn
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./coturn/turnserver.conf:/etc/turnserver.conf:ro
    command: -c /etc/turnserver.conf
    depends_on:
      - synapse

  nginx:
    image: docker.io/nginx:alpine
    container_name: matrix-nginx
    restart: unless-stopped
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./certs:/etc/letsencrypt:ro
      - ./certs/webroot:/var/www/certbot:ro
    ports:
      - "80:80"
      - "443:443"
      - "8448:8448"
    networks:
      - matrix-network
    depends_on:
      - synapse
      - element
      - synapse-admin

networks:
  matrix-network:
    driver: bridge

Вернуться к содержанию

Настройка базы данных PostgreSQL

Synapse требует специфической кодировки базы данных. Создадим скрипт инициализации, который выполнится при первом запуске контейнера PostgreSQL.

mkdir -p postgres/init
cat > postgres/init/01-create-matrix-db.sql << EOF
DROP DATABASE IF EXISTS matrix;
CREATE DATABASE matrix WITH OWNER matrix ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0;
EOF

Подготовим директорию для данных Synapse и установим корректные права доступа:

mkdir -p synapse/{config,data,media}
chmod -R 777 synapse

Вернуться к содержанию

Конфигурация Synapse (homeserver.yaml)

Основной конфигурационный файл сервера. В нем прописываются параметры подключения к БД, пути к медиафайлам, настройки шифрования и TURN-сервера.

cat > synapse/config/homeserver.yaml << EOF
server_name: "${DOMAIN}"
pid_file: /data/homeserver.pid
report_stats: false

listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['0.0.0.0']
    resources:
      - names: [client, federation]
        compress: false
  - port: 8448
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['0.0.0.0']
    resources:
      - names: [federation]
        compress: false

database:
  name: psycopg2
  args:
    user: matrix
    password: ${POSTGRES_PASSWORD}
    database: matrix
    host: postgres
    port: 5432
    cp_min: 5
    cp_max: 10

log_config: "/config/log.config"
media_store_path: /media
uploads_path: /media/uploads
signing_key_path: "/data/${DOMAIN}.signing.key"
trusted_key_servers:
  - server_name: "matrix.org"

max_upload_size: 100M
enable_registration: false
registration_shared_secret: "${REGISTRATION_SECRET}"

turn_uris:
  - "turn:${DOMAIN}:3478?transport=udp"
  - "turn:${DOMAIN}:3478?transport=tcp"
turn_shared_secret: "${TURN_SECRET}"
turn_user_lifetime: 86400000

admin_users:
  - "@admin:${DOMAIN}"

enable_federation: false
federation_port: 8448

macaroon_secret_key: "${MACAROON_SECRET}"
EOF

Также создадим файл конфигурации логирования:

cat > synapse/config/log.config << 'EOF'
version: 1
formatters:
  precise:
    format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    formatter: precise
    level: INFO
  file:
    class: logging.handlers.RotatingFileHandler
    formatter: precise
    level: INFO
    filename: /data/homeserver.log
    maxBytes: 104857600
    backupCount: 10
loggers:
  synapse.storage.SQL:
    level: WARNING
root:
  level: INFO
  handlers: [console, file]
disable_existing_loggers: false
EOF

chmod 644 synapse/config/log.config

Вернуться к содержанию

Настройка клиентской части и админ-панели

Element Web

Файл config.json указывает клиенту адрес сервера для подключения.

cat > element/config.json << EOF
{
    "default_server_config": {
        "m.homeserver": {
            "base_url": "https://${DOMAIN}",
            "server_name": "${DOMAIN}"
        }
    },
    "disable_custom_urls": true,
    "disable_guests": true,
    "disable_login_language_selector": false,
    "disable_3pid_login": true,
    "brand": "Element",
    "default_theme": "light",
    "show_labs_settings": false,
    "features": {},
    "default_federate": false
}
EOF

Coturn (TURN-сервер)

Необходим для прохождения NAT при голосовых и видеозвонках.

cat > coturn/turnserver.conf << EOF
listening-port=3478
tls-listening-port=5349
fingerprint
use-auth-secret
static-auth-secret=${TURN_SECRET}
realm=${DOMAIN}
user-quota=100
total-quota=1200
no-tcp-relay
syslog
no-multicast-peers
no-loopback-peer
EOF

Вернуться к содержанию

Конфигурация Nginx

Nginx будет выступать в роли обратного прокси, распределять трафик между сервисами и обрабатывать SSL-сертификаты.

Создадим основной конфиг nginx.conf:

mkdir -p nginx/conf.d

cat > nginx/nginx.conf << 'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;
    include /etc/nginx/conf.d/*.conf;
}
EOF

Создадим конфигурацию виртуальных хостов matrix.conf:

cat > nginx/conf.d/matrix.conf << EOF
# Редирект HTTP на HTTPS
server {
    listen 80;
    server_name ${DOMAIN} ${ELEMENT_DOMAIN};
    return 301 https://\$host\$request_uri;
}

# Matrix Synapse API
server {
    listen 443 ssl http2;
    server_name ${DOMAIN};

    ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
        default_type "text/plain";
    }

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location ~ ^(/|/_matrix|/_synapse/client) {
        proxy_pass http://synapse:8008;
        proxy_set_header X-Forwarded-For \$remote_addr;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_set_header Host \$host;
        client_max_body_size 100M;
        proxy_http_version 1.1;
    }
}

# Порт федерации
server {
    listen 8448 ssl http2;
    server_name ${DOMAIN};

    ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;

    location / {
        proxy_pass http://synapse:8008;
        proxy_set_header X-Forwarded-For \$remote_addr;
        proxy_set_header Host \$host;
    }
}

# Element Web
server {
    listen 443 ssl http2;
    server_name ${ELEMENT_DOMAIN};

    ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
        default_type "text/plain";
    }

    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    location / {
        proxy_pass http://element:80;
        proxy_set_header X-Forwarded-For \$remote_addr;
        proxy_set_header Host \$host;
    }
}

# Synapse Admin
server {
    listen 443 ssl http2;
    server_name ${ADMIN_DOMAIN};

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
        default_type "text/plain";
    }

    ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;

    location / {
        # Рекомендуется ограничить доступ по IP
        # allow 1.2.3.4;
        # deny all;

        proxy_pass http://synapse-admin:80;
        proxy_set_header X-Forwarded-For \$remote_addr;
        proxy_set_header Host \$host;
    }
}
EOF

Вернуться к содержанию

Получение SSL-сертификатов

Для работы HTTPS необходимы сертификаты. Используем Certbot в режиме standalone. Перед запуском убедитесь, что порт 80 свободен (если запущен другой веб-сервер, его нужно временно остановить).

docker run --rm -it \
    -v ./certs:/etc/letsencrypt \
    -p 80:80 \
    certbot/certbot certonly \
    --standalone \
    -d ${DOMAIN} \
    -d ${ELEMENT_DOMAIN} \
    -d ${ADMIN_DOMAIN} \
    --email your@email.com \
    --agree-tos \
    --non-interactive

Вернуться к содержанию

Запуск сервисов

Сначала запустим базу данных для инициализации, затем поднимем весь стек.

docker compose up -d postgres
sleep 30

docker compose up -d

Проверим статус контейнеров:

docker compose ps

Можно отследить логи Synapse для контроля процесса запуска:

docker compose logs -f synapse

Вернуться к содержанию

Создание пользователей через консоль

После настройки сервера возникает необходимость добавления новых участников. Это можно сделать двумя способами: создать обычного пользователя или сразу наделить его правами администратора.

Создание обычного пользователя

Для регистрации стандартного аккаунта используется утилита register_new_matrix_user. Ключ -a (admin) в этом случае не указывается.

Выполните команду внутри контейнера Synapse:

docker exec -it matrix-synapse register_new_matrix_user \
    -c /conf/homeserver.yaml \
    http://localhost:8008 \
    -u username \
    -p secure_password

Где:

  • username — желаемое имя пользователя (без домена, например ivan).

  • secure_password — пароль для входа.

Пример:

docker exec -it matrix-synapse register_new_matrix_user \
    -c /conf/homeserver.yaml \
    http://localhost:8008 \
    -u ivanov \
    -p Str0ngP@ssw0rd

В ответ система выдаст подтверждение создания пользователя и его полный MXID (например, @ivanov:matrix.sitename.ru). Этот пользователь сможет войти через веб-клиент Element, но не будет иметь доступа к панели администрирования.

Примечание: Если в файле homeserver.yaml параметр enable_registration установлен в false (что рекомендуется для безопасности после первоначальной настройки), регистрация новых пользователей возможна только через эту консольную команду или панель администратора. Веб-форма регистрации в клиенте будет недоступна.

Создание пользователя с правами администратора

Если необходимо создать нового администратора, используется та же команда, но с добавлением флага -a:

docker exec -it matrix-synapse register_new_matrix_user \
    -c /conf/homeserver.yaml \
    http://localhost:8008 \
    -u admin_name \
    -p secure_password \
    -a

Флаг -a автоматически добавляет созданного пользователя в список admin_users и наделяет полными правами управления сервером через Synapse-Admin.

Интерактивный режим

Если не указывать логин и пароль в аргументах команды, утилита запустится в интерактивном режиме и запросит данные пошагово:

docker exec -it matrix-synapse register_new_matrix_user \
    -c /conf/homeserver.yaml \
    http://localhost:8008

Система последовательно запросит:

  1. Username (имя пользователя).

  2. Password (пароль).

  3. Confirm password (подтверждение пароля).

  4. Make admin [y/N] (сделать администратором: да/нет).

Этот способ удобен, чтобы избежать передачи паролей через историю команд оболочки (history).

Вернуться к содержанию

Автоматическое обновление сертификатов

Добавим скрипт в cron для регулярного продления сертификатов Let’s Encrypt.

cat > /etc/cron.daily/certbot-renew << 'EOF'
#!/bin/bash
cd /opt/matrix-stack

docker run --rm \
    -v ./certs:/etc/letsencrypt \
    -v ./certs/webroot:/var/www/certbot \
    certbot/certbot certonly \
    --webroot -w /var/www/certbot \
    -d ${DOMAIN} -d ${ELEMENT_DOMAIN} -d ${ADMIN_DOMAIN} \
    --email your@email.com --agree-tos --non-interactive

docker compose restart nginx
EOF

chmod +x /etc/cron.daily/certbot-renew

Вернуться к содержанию

Управление и обслуживание

Основные команды для управления стеком:

  • Остановка: docker compose down

  • Перезапуск: docker compose restart

  • Обновление образов: docker compose pull && docker compose up -d

  • Просмотр логов: docker compose logs -f [имя_сервиса]

Для резервного копирования данных достаточно архивировать тома с данными:

tar -czf matrix-backup-$(date +%Y%m%d).tar.gz \
    postgres/data synapse/data synapse/media certs

Вернуться к содержанию

Проверка работоспособности

Убедитесь, что сервисы доступны по следующим адресам:

Сервис URL Порт
Element Web https://element.sitename.ru 443
Matrix API https://matrix.sitename.ru 443
Synapse Admin https://matrix-admin.sitename.ru 443
Federation matrix.sitename.ru 8448

Вернуться к содержанию

Источником для данного руководства послужили материалы с сайта habr.ru

Мы используем файлы cookie для предоставления наших услуг, а также для аналитики и маркетинга. Продолжая просматривать наш веб-сайт, вы соглашаетесь на использование нами файлов cookie.
ОК