
В свете небезызвестных событий в законотворческой области, столкнулся с необходимостью организовать канал для общения внутри семьи, т.к. пользоваться звонками в популярных мессенджерах – значит быть подверженным угрозам со стороны мошенников и спонсировать терроризм, а звонить по мобильной сети с ее ужасным качеством связи (несмотря на все потуги операторов в VoLTE и прочие VoiceHD) в 2025 году – какой-то моветон. А MAX на мои устройства устанавливаться отказался, не знаю почему, я даже не пробовал. Может быть потому что я слишком мало времени провожу в лифте и на парковке?
Еще с 2013 года я заразился NAS'остроением, поэтому проблем с выбором VDS/VPS у меня небыло: домашний "NAS" за это время превратился из WD MyCloud с установленным OpenMediaVault в уже вполне себе самостоятельный мини-сервер, но все с тем же OpenMediaVault в качестве хостовой системы (да-да, Debian с веб-мордой, я пробовал и Proxmox и все остальное – не зашло по тем или иным причинам. Если статья зайдет аудитории Хабра - напишу подробно про все этапы превращения домашней файлопомойки во вполне себе функциональный ящичек).
Одиноко скучающий детёныш сервера

В качестве среды для всего, что мы сегодня будем городить, я предпочел Docker. А разворачивать все это лично мне удобнее через Portainer.
Первым вопросом встал выбор протокола, который будет использоваться для звонков вместо всех этих мошеннических Telegram и террористических WhatsApp.
Судя по форумам, в качестве протоколов самое популярное и доступное для селфхостинга – Matrix и XMPP. Определиться, что же лучше, по описаниям и отзывам я не смог – поэтому решил поставить сразу два сервера, под каждый протокол, и уже по ходу дела выбрать победителя.
В качестве сервера Matrix выбор пал на Synapse, в качестве сервера XMPP - Ejabberd. Возможно, есть что-то лучше, но у этих двоих довольно понятные мануалы и оба без проблем разворачиваются в Docker.
При выборе клиентов я руководствовался по большей части эстетическими соображениями, выбирая на основании юзабельности и симпатичности клиентов, ведь использовать все это будут в том числе родители и супруга, а как известно, женщина – лучший показатель применимости технологии. Если женщина начала чем-то пользоваться – значит оно действительно работает. Больше всего приглянулся Element для Matrix (не X, в Х чтоб поднять звонки нужно было слишком уж заморочаться) – мультиплатформенный, без лишних рюшечек, и Conversation для XMPP, но так как с мультиплатформенностью у него туго - на iOS в качестве клиента выбор пал на Monal.
Element на Android и iOS соответственно


Клиенты XMPP на Android и iOS соответственно


Итого "стек" технологий выглядел примерно так: разворачивать все будем в Docker с помощью Portainer, для неискушенного командной строкой пользователя это вполне доступный метод.
Протокол Matrix у нас будет обеспечиваться сервером Synapse, XMPP – Ejjaberd.
Так же для работы аудиозвонков нам потребуется сервер Coturn, который будет пробиваться за NAT (с ним кстати плясок с бубнами оказалось больше всего).
На сервере у меня установлен Nginx Proxy Manager (далее для краткости – NPM), который разрешает доменные имена третьего уровня и получает сертификаты, через него наши клиенты и будут обращаться к серверной части.
Если представить все в виде блок-схемы, то получим такое:

В этом руководстве я подразумеваю, что у вас уже установлен Docker, Portainer, NPM, имеется доменное имя и вы +/- представляете, что с этим всем делать. Я не претендую на идеальную правильность приведенных ниже решений – я у мамы инженер-физик, а не программист, поэтому с удовольствием прислушаюсь к вашим советам и рекомендациям. Итак, начинаем.
Первым что нам необходимо сделать – зарегистрировать записи в DNS. Представим что ваш личный сервер имеет адрес myserver.ru. Идем к регистратору и создаем следующие записи:
А‑запись: synapse.myserver.ru — для обращения к серверу Synapse;
А‑запись: element.myserver.ru — для обращения к web‑клиенту Element;
А‑запись: xmpp.myserver.ru — для обращения к Ejabberd, через нее же будем подключаться к Coturn и возьмем для него сертификаты;
SRV‑запись: xmpp‑client.tcp.myserver.ru с указанием target xmpp.myserver.ru и порта 5222 — для подключения клиентов xmpp;
SRV‑запись: xmpp‑server.tcp.myserver.ru с указанием target xmpp.myserver.ru и порта 5269 — для подключения федерации серверов xmpp.
Вторым – создадим папки на сервере, где будут храниться конфиги и прочие потроха сервисов. Для упрощения будем считать что вы выделили под все это папку в разделе /opt и назвали ее /myservice.
Создаем следующую структуру папок:

mkdir -p /opt/myservice/ejabberd/{certs,conf,data,logs,upload} /opt/matrix/{data,element,pg}
Теперь создадим конфиги под наши будущие сервисы:
Сервер Ejabberd:
делаем в терминале
nano /opt/myservice/ejabberd/conf/ejabberd.yml
и вставляем туда следующий конфиг:
ejabberd.yml
loglevel: 4 # Уровень логирования (0 - минимум, 5 - максимум). 4 = подробные логи
log_rotate_size: 10485760 # Максимальный размер файла лога (10 МБ)
log_rotate_count: 1 # Количество сохраняемых старых файлов логов (1 — только один архив)
hosts: # Список доменов, обслуживаемых сервером XMPP
- "xmpp.myserver.ru" # Основной XMPP-домен сервера
acl: # Access Control Lists — списки доступа
admin: # Группа администраторов
user:
- "admin@xmpp.myserver.ru" # Пользователь с правами администратора
acme:
auto: false # Автоматическое получение SSL-сертификатов через Let's Encrypt выключено
access_rules: # Правила доступа для различных сервисов
local: # Локальные подключения (например, скрипты)
allow: all # Разрешены всем
c2s: # Client-to-Server (подключение клиентов)
allow: all # Разрешено всем пользователям
s2s: # Server-to-Server (федерация XMPP)
allow: all # Разрешено соединение с любыми серверами
configure: # Доступ к административным функциям
allow: admin # Разрешено только администраторам
listen: # Конфигурация прослушиваемых портов
- port: 5222 # TCP-порт для клиентских подключений (c2s)
module: ejabberd_c2s # Модуль для Client-to-Server соединений
starttls: true # Поддержка STARTTLS
starttls_required: true# Обязательно использовать TLS
max_stanza_size: 65536 # Максимальный размер XMPP-сообщения (в байтах)
shaper: c2s_shaper # Ограничение скорости для клиентов
- port: 5269 # TCP-порт для серверных соединений (s2s)
module: ejabberd_s2s_in# Модуль для Server-to-Server соединений
max_stanza_size: 131072# Максимальный размер пакета (128 КБ)
shaper: s2s_shaper # Ограничение скорости для серверов
- port: 5280 # HTTP-интерфейс
module: ejabberd_http # Модуль веб-доступа
request_handlers: # Обработчики путей
"/admin": ejabberd_web_admin # Веб-интерфейс админики
"/api": mod_http_api # HTTP API
"/bosh": mod_bosh # BOSH (HTTP-подключение XMPP-клиентов)
"/ws": ejabberd_http_ws # WebSocket-подключения
"/upload": mod_http_upload # HTTP File Upload
tls: false # HTTPS не используется (работает только через HTTP)
- port: 3478 # UDP-порт для STUN/TURN (VoIP, WebRTC)
transport: udp
module: ejabberd_stun # Модуль STUN/TURN
use_turn: true # Включен TURN (ретрансляция медиа-трафика)
turn_min_port: 49152 # Минимальный порт для медиапотоков
turn_max_port: 65535 # Максимальный порт для медиапотоков
- port: 5349 # TCP-порт для STUN/TURN с TLS
transport: tcp
module: ejabberd_stun
use_turn: true
tls: true # Поддержка шифрования TLS
turn_min_port: 49152
turn_max_port: 65535
certfiles: # Пути к SSL-сертификатам
- "/etc/letsencrypt/fullchain.pem" # Полная цепочка сертификатов
- "/etc/letsencrypt/privkey.pem" # Приватный ключ
default_db: internal # Используется встроенная база данных ejabberd (Mnesia)
modules: # Подключенные модули ejabberd
mod_adhoc: {} # Ad-hoc команды (XEP-0050)
mod_admin_extra: {} # Дополнительные административные функции
mod_announce: # Модуль объявлений (broadcast)
access: admin # Только администраторы могут рассылать
mod_avatar: {} # Поддержка аватаров пользователей
mod_blocking: {} # Блокировка контактов (XEP-0191)
mod_bosh: {} # Поддержка BOSH
mod_caps: {} # Entity Capabilities (XEP-0115)
mod_carboncopy: {} # Сообщения копируются на все устройства (XEP-0280)
mod_client_state: {} # Состояние клиента (idle/active)
mod_configure: {} # Конфигурация через XMPP
mod_disco: {} # Service Discovery (XEP-0030)
mod_http_api: {} # REST API
mod_http_upload: # HTTP File Upload (XEP-0363)
put_url: "https://xmpp.myserver.ru/upload" # URL для загрузки файлов
get_url: "https://xmpp.myserver.ru/upload" # URL для скачивания файлов
docroot: "/home/ejabberd/upload" # Папка для хранения файлов
max_size: 104857600 # Максимальный размер файла (100 МБ)
mod_last: {} # Последняя активность пользователя (XEP-0012)
mod_mam: # Message Archive Management (XEP-0313)
default: always # Всегда сохранять сообщения
mod_muc: # Multi-User Chat (XEP-0045)
access: all # Доступен всем
access_create: all # Любой может создавать комнаты
access_persistent: all # Разрешены постоянные комнаты
access_admin: admin # Администрирование комнат — только админ
mod_ping: {} # Ping (XEP-0199)
mod_privacy: {} # Privacy Lists (XEP-0016)
mod_private: {} # Хранение приватных данных (XEP-0049)
mod_pubsub: # PubSub (XEP-0060)
access_createnode: all # Разрешено всем создавать узлы
plugins: # Подключенные плагины
- "flat" # Простая структура
- "pep" # Personal Eventing Protocol (XEP-0163)
force_node_config: # Настройки по умолчанию для узлов
"urn:xmpp:microblog:0": # Микроблоги
deliver_payloads: true # Доставлять данные сразу
notify_retract: true # Уведомлять об удалении
persist_items: true # Хранить данные
max_items: 100 # Максимум 100 сообщений
mod_push: {} # Push-уведомления
mod_push_keepalive: {} # Поддержка keepalive для push
mod_register: # Регистрация пользователей
access: none # Отключена (запрет регистрации)
ip_access: none # Нельзя регистрироваться ни с какого IP
registration_watchers: # Уведомления о регистрации
- "admin@xmpp.myserver.ru" # Администратор получает уведомления
Сохраняем и переходим к конфигу Synapse.
Делаем:
nano /opt/myservice/matrix/data/homeserver.yaml
и вставляем в него следующее:
homeserver.yaml
server_name: "synapse.myserver.ru" # Основное имя сервера Matrix
pid_file: /data/homeserver.pid # Файл, где будет храниться PID процесса Synapse
# Задаем порты и протоколы для клиентов и федерации
listeners:
- port: 8008 # Порт, на котором работает Synapse
tls: false # TLS выключен
type: http # Тип протокола
x_forwarded: true # Разрешает доверять заголовку X-Forwarded-For от прокси
resources:
- names: [client, federation] # Разрешённые ресурсы: клиентские запросы и федерация
compress: false # Отключено сжатие (для производительности)
# Настройки базы данных (PostgreSQL)
database:
name: psycopg2 # Используемый драйвер PostgreSQL
txn_limit: 10000 # Максимальное число транзакций в одном пуле
args:
user: synapse # Пользователь БД
password: mypassword # Пароль
database: synapse # Имя базы данных
host: synapse-db # Хост базы данных (контейнер/сервер)
port: 5432 # Порт PostgreSQL
cp_min: 5 # Минимальное число соединений в пуле
cp_max: 10 # Максимальное число соединений в пуле
# Настройки логов (раскомментировать при необходимости)
#log_config: "log.yaml"
# Директория для хранения медиа (файлы, изображения и т.п.)
media_store_path: /data/media_store
# Убирает предупреждение о key сервере
suppress_key_server_warning: true
# Максимальный размер загружаемых файлов
max_upload_size: 400M
# Регистрация новых пользователей запрещена (false)
enable_registration: false
# Включена федерация с другими Matrix-серверами
matrix_synapse_federation_enabled: true
matrix_synapse_federation_port_enabled: true
# Общий секрет для регистрации пользователей через API
registration_shared_secret: "mypassword"
# Разрешает поиск по всем пользователям сервера
search_all_users: true
# Предпочитать локальных пользователей (вместо удалённых из федерации)
prefer_local_users: true
# Настройки TURN-сервера (для звонков и WebRTC)
turn_uris:
- "turn:xmpp.myserver.ru:3478?transport=udp"
- "turn:xmpp.myserver.ru:3478?transport=tcp"
- "turns:xmpp.myserver.ru:5349?transport=udp"
- "turns:xmpp.myserver.ru:5349?transport=tcp"
turn_shared_secret: "mysecret" # Секретный ключ для генерации учетных данных TURN
turn_user_lifetime: 86400000 # Время жизни учётной записи (мс)
turn_allow_guests: true # Разрешить гостям использовать TURN
turn_server_name: "synapse.myserver.ru" # Имя TURN-сервера
# Список администраторов сервера
admin_users:
- "@admin:synapse.myserver.ru"
# Отправлять анонимную статистику разработчикам Synapse
report_stats: false
# Секретные ключи для подписи токенов
macaroon_secret_key: "mnogobukv"
form_secret: "mnogobukv"
# Ключ для подписи событий (не удалять - сообщения потом не расшифруются)
signing_key_path: "/data/synapse.myserver.ru.signing.key"
# Экспериментальные функции Matrix (включены новые спецификации)
experimental_features:
call: true
msc3266_enabled: true
msc4222_enabled: true
msc4140_enabled: true
# Максимальная задержка доставки события
max_event_delay_duration: 24h
# Ограничения скорости отправки сообщений (rate limiting)
rc_message:
per_second: 0.5 # Средняя скорость (0.5 сообщений в секунду)
burst_count: 30 # Максимальный "всплеск" сообщений
# Ограничения на управление отложенными событиями
rc_delayed_event_mgmt:
per_second: 1
burst_count: 20
# Политика хранения медиа (очистка старых файлов)
media_retention:
local_media_lifetime: 120d # Срок хранения локальных файлов
remote_media_lifetime: 120d # Срок хранения удалённых файлов
затем
nano /opt/myservice/matrix/config.json
и вставляем:
config.json
{
"homeserver_url": "https://synapse.myserver.ru",
"enable_presence_by_hs_url": {
"https://synapse.myserver.ru": true
},
"turn": {
"urls": [
"turn:xmpp.myserver.ru:3478?transport=udp",
"turn:xmpp.myserver.ru:3478?transport=tcp",
"turns:xmpp.myserver.ru:5349?transport=udp",
"turns:xmpp.myserver.ru:5349?transport=tcp"
],
"secret": "mysecret",
"expiry": 864000000,
"turn_allow_guest": true
},
"terms_and_conditions_links": [
{
"url": "https://myserver.ru/privacy",
"text": "Privacy Policy"
},
{
"url": "https://myserver.ru/cookie-policy",
"text": "Cookie Policy"
}
],
"privacy_policy_url": "https://myserver.ru/privacy"
}
Теперь настроим клиент Element-web:
снова создаем файл
nano /opt/myservice/matrix/element/config.json
и вставляем
config.json
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://synapse.myserver.ru",
"server_name": "synapse.myserver.ru"
},
"io.element.call": {
"url": "https://call.element.io"
},
"io.element.e2ee": {
"default": true
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"disable_custom_urls": true,
"disable_guests": true,
"disable_login_language_selector": true,
"disable_3pid_login": true,
"brand": "My Personal Server",
"enable_element_call": true,
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
"uisi_autorageshake_app": "element-auto-uisi",
"default_country_code": "RU",
"show_labs_settings": false,
"features": {},
"default_federate": false,
"default_theme": "light",
"room_directory": {
"servers": ["synapse.myserver.ru"]
},
"element_call": {
"url": "https://call.element.io",
"participant_limit": 8,
"brand": "Element Call"
},
"enable_presence_by_hs_url": {
"https://synapse.myserver.ru": true
},
"terms_and_conditions_links": [
{
"url": "https://element.io/privacy",
"text": "Privacy Policy"
},
{
"url": "https://element.io/cookie-policy",
"text": "Cookie Policy"
}
],
"privacy_policy_url": "https://element.io/cookie-policy"
}
Не забываем все это сохранять и убедитесь что ваш Docker имеет права на эти папки и файлы!
Идем запускать контейнеры.
Первым пойдет Coturn.
Идем в Portainer, раздел Stacks и нажимаем Add Stack:

Пишем в названии стека coturn, в окно web-editor вставляем следующее:
coturn
services:
coturn:
image: coturn/coturn # Образ coturn
container_name: coturn # Имя контейнера
restart: unless-stopped # Автоперезапуск
ports: # Пробрасываем порты наружу
- "3478:3478/udp" # TURN (UDP)
- "3478:3478/tcp" # TURN (TCP)
- "5349:5349/tcp" # TLS-over-TCP (TURNs)
- "5349:5349/udp" # TLS-over-UDP (TURNs)
- "49152-65535:49152-65535/udp" # Диапазон портов для передачи медиаданных (нужно открыть на роутере)
volumes:
- /opt/myservices/ejabberd/certs:/etc/letsencrypt:ro # Подключаем сертификаты Let's Encrypt (только для чтения)
command: >
-n # Режим запуска
--turn_allow_guests=true # Разрешаем гостевые подключения без учётки
--use-auth-secret # Используем динамическую аутентификацию
--static-auth-secret=mysecret # Секрет для генерации временных логинов/паролей
--rearm=xmpp.myserver.ru # Разрешаем подключение
--cert=/etc/letsencrypt/fullchain.pem # Путь к TLS-сертификату
--pkey=/etc/letsencrypt/privkey.pem # Путь к приватному ключу
Запускаем все это дело и смотрим в логи. Должен ругнуться на сертификаты, их пока нет, но будут. Останавливаем чтоб не мешал.
Далее поднимаем Ejabberd:
Аналогично как и с Coturn, открываем окно Web-editor, обзываем стек и вставляем туда следующее:
ejabberd
services:
ejabberd:
image: ejabberd/ecs # Образ ejabberd
container_name: ejabberd # Имя контейнера
restart: unless-stopped # Автоперезапуск контейнера
environment:
- ERLANG_NODE=ejabberd@localhost # Имя Erlang-ноды, используемой ejabberd
- XMPP_DOMAIN=xmpp.myserver.ru # Домен XMPP сервера (Jabber ID будет вида user@xmpp.myserver.ru)
volumes:
- /opt/myservice/ejabberd/conf:/home/ejabberd/conf # Конфиги ejabberd
- /opt/myservice/ejabberd/data:/home/ejabberd/database # Хранилище данных (базы)
- /opt/myservice/ejabberd/logs:/home/ejabberd/logs # Логи сервера
- /opt/myservice/ejabberd/upload:/home/ejabberd/upload # Файлы, загружаемые пользователями
- /opt/myservice/ejabberd/certs:/etc/letsencrypt:ro # Сертификаты Let's Encrypt для TLS (только чтение)
ports:
- "5222:5222" # Клиентский порт XMPP (TCP, STARTTLS)
- "5269:5269" # Порт федерации XMPP (сервер-сервер)
- "5280:5280" # HTTP(S) порты (веб-админка)
Запускаем, останавливаем.
Далее – стек Synapse:
synapse
services:
synapse:
image: matrixdotorg/synapse:latest # Образ Synapse
container_name: matrix-synapse # Имя контейнера
restart: unless-stopped # Автоперезапуск контейнера
environment:
- SYNAPSE_SERVER_NAME=synapse.myserver.ru # Домен сервера
- SYNAPSE_REPORT_STATS=false # Отправка анонимной статистики разработчикам
volumes:
- /opt/myservice/matrix/data:/data # Тут храним конфиги Synapse
ports:
- 8008:8008 # Порт для клиентов
- 8448:8448 # Порт для федерации с другими серверами
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8008/health"] # Проверка что не сдох
interval: 30s # Проверять каждые 30 секунд
timeout: 10s # Таймаут на выполнение healthcheck
retries: 5 # Количество повторных попыток
element-web:
image: vectorim/element-web:latest # Образ Element Web
container_name: element-web
restart: unless-stopped
volumes:
- /opt/myservice/matrix/element/config.json:/app/config.json # Конфиги Element Web
ports:
- 8009:80 # Внешний порт для доступа к веб-клиенту
synapse-db:
image: docker.io/postgres:latest # Образ PostgreSQL для Synapse
container_name: synapse-db
hostname: synapse-db
restart: unless-stopped
environment:
TZ: "Europe/Moscow" # Часовой пояс
POSTGRES_USER: synapse # Пользователь БД
POSTGRES_PASSWORD: password # Пароль БД
POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C # Инициализация базы с правильной локалью
volumes:
- /opt/myservice/matrix/pg:/var/lib/postgresql/data # Данные БД сохраняются вне контейнера
synapse-admin:
image: awesometechnologies/synapse-admin:latest # Веб-интерфейс для управления Synapse
container_name: synapse-admin
restart: unless-stopped
ports:
- 8007:80 # Внешний порт для доступа к веб-админке
environment:
- SYNAPSE_ADMIN_API=http://matrix-synapse:8008 # Адрес админки
Запустили, остановили. Идем получать сертификаты.
Открываем NPM и добавляем проксируемые хосты:
Для xmpp.myserver.ru:

Во вкладке SSL не забываем получить сертификаты, их мы будем активно использовать далее.
Важное примечание для xmpp – чтоб клиенты могли обмениваться файлами – ему надо указать куда эти файлы ложить и откуда брать, поэтому в разделе Custom Location делаем так, указывая IP вашего сервера в локалке:
Для synapse.myserver.ru:

Тут тоже есть нюанс, чтоб Element нормально работал – ему нужен .well-known, поэтому в раздел Advanced вставляем следующее:
.well-known
location /.well-known/matrix/server {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.server": "synapse.myserver.ru:443"}';
}
location /.well-known/matrix/client {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{
"m.homeserver": {
"base_url": "https://synapse.myserver.ru"
},
"io.element.e2ee": {
"default": true
}
}';
}
proxy_read_timeout 360s;
proxy_buffering off;
Для Element-Web:

Тут тоже надо дописать в Advanced:
location
location /.well-known/matrix/client {
add_header Access-Control-Allow-Origin "*";
add_header Content-Type "application/json";
return 200 '{"m.homeserver":{"base_url":"https://synapse.myserver.ru"}}';
}
По итогу всего этого у вас должно получиться примерно так:

Хосты настроили, теперь идем за сертификатами. Которые вы естественно для каждой записи в NPM получили. Не забыли же? По умолчанию NPM сохраняет сертификаты к себе в папку /live/npm-xxx, где ххх – номер проксируемого хоста. Поэтому идем за ними. Смотрим какой номер у сертификата xmpp.myserver.ru:
В нашем случае 142, копируем их к нам в папку, не забываем менять путь к папке с сертификатами на свой! В моем случае папка NPM расположена по пути /portainer/npm/live/:
cp /portainer/npm/live/npm-142/fullchain.pem /opt/myservice/ejabberd/certs/fullchain.pem
cp /portainer/npm/live/npm-142/privkey.pem /opt/myservice/ejabberd/certs/privkey.pem
Когда сертификаты скопированы, возвращаемся в Portainer и запускаем наши контейнеры.
Для Ejabberd нужно создать админскую учетку, для этого заходим в консоль и выполняем следующее:
docker exec -it ejabberd ejabberdctl register admin myserver.ru password
Для Synapse мы его уже прописали в homeserver.yaml
После всего проделанного
Админка Ejabberd будет доступна по адресу ip:5280/admin

Админка Synapse будет доступна по адресу ip:8007

Web-клиент Element будет находится по адресу element.myserver.ru

Если нигде не ошиблись – можно скачивать понравившиеся вам клиенты и подключаться.
В итоге, попользовавшись всем этим несколько дней, остановился на Synapse и Element. Хотя визуально Conversation и выглядит просто отлично - ничего лишнего, все работает, но XMPP мне не зашел, подвели устройства Apple, на которых ни один из клиентов не захотел работать в фоне. Сообщения можно было получить только открыв приложение и подождав пока они загрузятся. Плюс не понравилось хранение и передача файлов по сути ссылками на открытые папки. Если кто подскажет путь решения этих проблем - буду благодарен.
Одним из жирных плюсов для себя так же выделил разделение потоков информации - новости, мемчики и котики в Telegram, семья - в Element.
Комментарии (25)
ddr5
01.09.2025 11:16а звонить по мобильной сети с ее ужасным качеством связи
Еще до 2022 качество звонков в мессенджерах часто было отстойным, потому что нужен стабильный интернет у обоих участников. А, как правило, это не так.
Ни разу не оправдываю блокировку звонков, но лично они меня всегда люто бесили по причине того, что позвонить по телефону гораздо быстрее. А еще входящие звонки в мессенджер часто прячутся куда-то в шторку, откуда их нужно выковыривать. Но многие почему-то упорно пытались вызвонить меня в мессенджере.
Так что, как ни прискорбно, но лучше старой доброй мобильной связи еще ничего не придумали. А то что работало, сломали.
unwrecker
01.09.2025 11:16Битрейт у мобильной связи маловат. После мессенджеров - такое себе. Опять же, по мобильной связи нельзя говорить с гарнитуры на компе.
ddr5
01.09.2025 11:16Да пофиг на битрейт, важно чтобы собеседник тебя нормально слышал, а ты его, без постоянного "але але меня слышно ква-ква".
Опять же, по мобильной связи нельзя говорить с гарнитуры на компе.
Увы, это так и тут на помощь придут три волшебные буквы.
unwrecker
01.09.2025 11:16Ну тут выбор меджу чистым узнаваемым голосом, но требующим хорошей сети, и маленьким битрейтом с сильной компрессией, который работает везде.
3 волшебных буквы - это SIP? Но как получить его на тот же мобильный номер?
lifespirit
01.09.2025 11:16Купить любой сип номер у кучи сип провайдеров и настроить безусловную переадресацию на симке мобильного телефона.
unwrecker
01.09.2025 11:16Вариант, но я так понимаю, что переадресация будет с поминутной оплатой?
lifespirit
01.09.2025 11:16Нет. однократное списание за факт переадрескации. голос не замыкается на мобильном номере при переадресации. Просто звонок сигнализацией уходит на сип провайдера сразу.
lifespirit
01.09.2025 11:16Проверил у своего оператора, действительно теперь поминутная оплата. Просто жесть.... Остаётся только открывать ИП и на него открывать sip стык с оператором. Но это уже не так просто и дёшево.
UPD: ну или забить вообще на номер симки и пользоваться только SIP номером.
inkelyad
01.09.2025 11:16Опять же, по мобильной связи нельзя говорить с гарнитуры на компе.
Вряд ли это так. Компьютер с bluetooth адаптером может притворяться 'гарнитурой' для сотового телефона. Собственно, даже Android Auto - вроде бы 'под капотом' так и делает, пользуясь этим костылем для обхода собственных ограничений Android телефонов на захват голоса для программной обработки.
lifespirit
01.09.2025 11:16У Element, если я правильно помню, припроетарный протокол для звонков, основанный на Livekit и lk-jwt-service . + нужно вставить анонс кастомного RFC в .well-known . Иначе нельзя будет в любой группе сделать звонок, а только в специально помеченной как "голосовая". А этот плагин ломает авторизацию на сервере.
Есть ещё вариант на SIP'е от Belledonne Communications . Flexisip + linphone работает великолепно. Платформа изначально заточена на голос. При желании для андройда можно пересобрать linphone со совоей push подпиской и тогда вообще хорошо.
gridmal
01.09.2025 11:16Я на данный момент тестирую Nextcloud Talk внутри семьи для звонков с видео. Настройка много проще. Качество - лучше WhatsApp
ArtemSmit Автор
01.09.2025 11:16Nextcloud Talk тащит за собой весь монструозный Nextcloud. Ушел от него на SeaFile и с тех пор про Nextcloud вспоминаю с содроганием ))) Плюсом, чтоб пользователь мог звонить в Nextcloud Talk - его нужно пустить в сам Nextcloud. Одно дело когда это внутри семьи, а если как у меня еще коллеги - уже не очень хочется быть общественной файлопомойкой.
JBFW
01.09.2025 11:16Годная тема.
Хотя если честно - вообще не понимаю концепции голосовых звонков, если вы не курьер, которому надо открыть шлагбаум. Уже сотни лет известна письменность!
ddr5
01.09.2025 11:16Ну если охота пальцы ломать, то никто не может запретить. Но от других этого ждать не стоит.
inkelyad
01.09.2025 11:16Ну если охота пальцы ломать, то никто не может запретить.
Голосовой набор - существует. И работает даже с локальным распознаванием.
ddr5
01.09.2025 11:16Зачем нужны эти костыли, если можно просто набрать номер?
zartarn
01.09.2025 11:16Чтоб осталась история разговора/обсуждения по которой есть нормальный поиск?
K0styan
01.09.2025 11:16Это нужно далеко не во всех сценариях, особенно в семье. Зато есть другие, в которых критична именно синхронность - например, когда нужно встретиться в месте, одному из участников малознакомом.
Бонус: голос передаёт эмоции.
Ivnika
Статью еще не успел прочитать, но заглавная картинка не бровь, а в глаз! ))