The snikket_server image includes a TURN server that is enabled by default (SNIKKET_TWEAK_TURNSERVER=1). A separate coturn container conflicts on port 3478 and adds unnecessary complexity for a standard deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Snikket Server
XMPP-сервер на базе Snikket (обёртка над Prosody с предварительной конфигурацией).
Состав сервисов
| Сервис | Образ | Назначение |
|---|---|---|
snikket_server |
snikket/snikket-server:stable |
Ядро — Prosody XMPP-сервер |
snikket_proxy |
snikket/snikket-web-proxy:stable |
Веб-прокси (nginx) |
snikket_certs |
snikket/snikket-cert-manager:stable |
Автоматическое получение TLS-сертификатов (Let's Encrypt) |
snikket_portal |
snikket/snikket-web-portal:stable |
Веб-портал для управления пользователями и инвайтами |
s3_upload_handler |
собирается из ./s3-upload-handler |
Обработчик загрузки файлов — принимает файлы от XMPP-клиентов и сохраняет в S3 |
postgres |
postgres:15 |
База данных PostgreSQL для Prosody |
Все сервисы работают в режиме network_mode: host.
Требования
DNS-записи
Для домена chat.example.org необходимо создать 3 записи:
| Тип | Имя | Значение |
|---|---|---|
| A | chat.example.org |
IP-адрес сервера |
| CNAME | groups.chat.example.org |
chat.example.org |
| CNAME | share.chat.example.org |
chat.example.org |
Опционально: AAAA-запись для IPv6, SRV-запись _xmpps-client._tcp для подключения через порт 443.
Порты
| Порт | Протокол | Назначение |
|---|---|---|
| 80 | TCP | HTTP (ACME challenges, редирект на HTTPS) |
| 443 | TCP | HTTPS (веб-портал, file sharing) |
| 5222 | TCP | XMPP client-to-server |
| 5269 | TCP | XMPP server-to-server (федерация) |
| 5000 | TCP | Proxy65 (передача файлов) |
| 5050 | TCP | S3 upload handler (HTTP Upload External) |
| 5432 | TCP | PostgreSQL |
| 3478 | TCP+UDP | STUN/TURN |
| 5349 | TCP+UDP | TURNS (TURN over TLS) |
| 49152–65535 | UDP | TURN relay (аудио/видео данные) |
Настройка файрвола (UFW)
# XMPP и веб
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 5222/tcp
ufw allow 5269/tcp
ufw allow 5000/tcp
# STUN/TURN (голосовые и видеозвонки)
ufw allow 3478/udp
ufw allow 3478/tcp
ufw allow 5349/tcp
ufw allow 5349/udp
ufw allow 49152:65535/udp
Конфигурация
prosody.cfg.lua
Кастомная конфигурация Prosody, монтируется в контейнер snikket_server как /etc/prosody/conf.d/custom.cfg.lua. Содержит:
- PostgreSQL —
storage = "sql"с драйвером PostgreSQL (подключение к127.0.0.1:5432) - HTTP Upload External —
mod_http_upload_externalдля загрузки файлов через внешний S3 upload handler
secrets.env
Файл с секретами, не коммитится в git (добавлен в .gitignore). Перед первым запуском необходимо создать его и заполнить реальными значениями:
cp secrets.env.example secrets.env
# отредактировать secrets.env
| Переменная | Описание |
|---|---|
UPLOAD_SECRET |
Shared secret (должен совпадать с http_upload_external_secret в prosody.cfg.lua) |
AWS_ACCESS_KEY_ID |
Ключ доступа AWS/S3 |
AWS_SECRET_ACCESS_KEY |
Секретный ключ AWS/S3 |
POSTGRES_PASSWORD |
Пароль PostgreSQL |
S3 Upload Handler (environment)
Несекретные параметры задаются в docker-compose.yml в секции environment сервиса s3_upload_handler:
| Переменная | Описание |
|---|---|
S3_BUCKET |
Имя S3-бакета |
S3_REGION |
Регион S3 |
S3_ENDPOINT |
URL S3-совместимого хранилища (MinIO и др.), не задавать для AWS |
PRESIGN_EXPIRE |
Время жизни presigned URL для скачивания (секунды, по умолчанию 3600) |
snikket.conf
Обязательные параметры
| Переменная | Описание |
|---|---|
SNIKKET_DOMAIN |
Домен сервера. Нельзя изменить после первого запуска. |
SNIKKET_ADMIN_EMAIL |
Email администратора (используется для Let's Encrypt) |
Основные параметры
| Переменная | По умолчанию | Описание |
|---|---|---|
SNIKKET_SITE_NAME |
значение SNIKKET_DOMAIN |
Человекочитаемое имя сервера |
SNIKKET_RETENTION_DAYS |
7 |
Сколько дней хранить сообщения (MAM) и загруженные файлы |
SNIKKET_UPLOAD_STORAGE_GB |
без лимита | Лимит дискового пространства для загруженных файлов (напр. 1.5) |
SNIKKET_LOGLEVEL |
info |
Уровень логирования: error, warn, info, debug |
SNIKKET_ABUSE_EMAIL |
— | Публичный email для жалоб |
SNIKKET_SECURITY_EMAIL |
— | Публичный email для сообщений о безопасности |
SNIKKET_UPDATE_CHECK |
1 |
Установить 0 чтобы отключить проверку обновлений |
Параметры reverse proxy
| Переменная | По умолчанию | Описание |
|---|---|---|
SNIKKET_TWEAK_HTTP_PORT |
80 |
HTTP-порт (изменить при работе за reverse proxy) |
SNIKKET_TWEAK_HTTPS_PORT |
443 |
HTTPS-порт (изменить при работе за reverse proxy) |
Параметры TURN-сервера
| Переменная | По умолчанию | Описание |
|---|---|---|
SNIKKET_TWEAK_TURNSERVER |
1 |
Установить 0 для отключения встроенного TURN |
SNIKKET_TWEAK_TURNSERVER_DOMAIN |
значение SNIKKET_DOMAIN |
Домен внешнего TURN-сервера |
SNIKKET_TWEAK_TURNSERVER_PORT |
3478 |
Порт TURN-сервера |
SNIKKET_TWEAK_TURNSERVER_SECRET |
автогенерация | Shared secret для аутентификации TURN |
Прочие параметры
| Переменная | По умолчанию | Описание |
|---|---|---|
SNIKKET_TWEAK_IPV6 |
1 |
Установить 0 для отключения IPv6 |
SNIKKET_TWEAK_STORAGE |
files |
Бэкенд хранения: files или sqlite (превью) |
SNIKKET_TWEAK_EXTRA_CONFIG |
— | Путь/glob к дополнительным файлам конфигурации Prosody |
SNIKKET_PROXY65_PORT |
5000 |
Порт proxy для передачи файлов |
SNIKKET_TWEAK_DNSSEC |
— | Включить поддержку DNSSEC и DANE |
Запуск
cd server
# 1. Настроить конфигурацию
# отредактировать snikket.conf значениями вашего домена
# 2. Заполнить секреты
cp secrets.env.example secrets.env
# отредактировать secrets.env реальными значениями
# 3. Запустить
docker compose up -d
# 3. Создать admin-аккаунт
docker exec snikket create-invite --admin --group default
Инвайт-ссылку открыть в браузере для регистрации администратора.
Обновление
cd server
docker compose pull
docker compose up -d
Хранение данных
Данные хранятся в Docker volumes:
| Volume | Содержимое |
|---|---|
snikket_data |
Данные сервера: аккаунты, сообщения, TLS-сертификаты |
acme_challenges |
Временные файлы ACME (Let's Encrypt) |
postgres_data |
Данные PostgreSQL |
Загруженные файлы хранятся в S3-бакете (не в volumes).
Бэкап
Необходимо сохранить volume snikket_data и базу PostgreSQL:
# Snikket data
docker run --rm -v jabogram_snikket_data:/data -v $(pwd):/backup alpine \
tar czf /backup/snikket-backup.tar.gz -C /data .
# PostgreSQL
docker exec snikket-postgres pg_dump -U snikket snikket | gzip > snikket-pg-backup.sql.gz
Хранение файлов (S3)
Загруженные файлы (HTTP File Upload, XEP-0363) хранятся в S3-бакете через кастомный s3_upload_handler.
Схема работы:
- XMPP-клиент запрашивает у Prosody слот для загрузки файла
- Prosody (
mod_http_upload_external) генерирует подписанный URL, указывающий наs3_upload_handler - Клиент загружает файл по этому URL
s3_upload_handlerпроверяет HMAC-подпись и сохраняет файл в S3- При скачивании — handler генерирует presigned S3 URL и делает redirect