Как я замену MAX’у искал, или «Matrix и XMPP на своем сервере для самых маленьких»

от автора

К - конкурентоспособность

К — конкурентоспособность

В свете небезызвестных событий в законотворческой области, столкнулся с необходимостью организовать канал для общения внутри семьи, т.к. пользоваться звонками в популярных мессенджерах – значит быть подверженным угрозам со стороны мошенников и спонсировать терроризм, а звонить по мобильной сети с ее ужасным качеством связи (несмотря на все потуги операторов в 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:

Certificate #142

Certificate #142

В нашем случае 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.


ссылка на оригинал статьи https://habr.com/ru/articles/942758/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *