Chatto — селф-хостинговый командный чат: комнаты, треды, обмен файлами, голос и видео с демонстрацией экрана. В этом гайде ставим его на VPS Medium от is*hosting через Docker Compose — путь развертывания, который документация проекта рекомендует для продакшена.
Что будет к концу: четыре контейнера (Chatto, NATS, LiveKit, Caddy) за автоматическим HTTPS, звонки через LiveKit, шифрованные на диске сообщения. От чистого dnf install до рабочего стека чуть меньше двух минут.
Что нужно до начала
- Домен, которым вы управляете, плюс его поддомен для LiveKit (пример Compose генерирует его автоматически с префиксом livekit. к домену чата).
- Учетка SMTP — нужна для встроенной регистрации по email/паролю, писем-подтверждений и сброса пароля.
- Docker CE и Docker Compose v2 (в этом гайде поставим оба).
- VPS, рассчитанный на четыре контейнера, которые крутятся одновременно: Chatto, NATS, LiveKit и Caddy.
Документация Chatto не публикует минимум по RAM или CPU, поэтому сайзинг ниже отражает то, что реально работает на машине, — четыре контейнера плюс накладные расходы самого Docker, с запасом под одновременные голос/видео звонки:
|
Сценарий |
RAM |
CPU |
is*hosting тариф |
|
Только текст, звонки выключены |
2 GB |
2 CPU |
Start VPS |
|
Небольшая команда или сообщество с голосом/видео |
4 GB |
3 CPU |
Medium VPS |
|
Крупное сообщество, одновременные звонки, транскодинг видео |
8 GB |
4 CPU |
Premium VPS |
На всех VPS тарифах is*hosting по умолчанию идет выделенный IPv4 и еженедельные бэкапы VPS. Здесь важно и то, и другое: IPv4 — для DNS и автоматического TLS в Caddy, бэкапы — как страховочный пол под собственной командой бэкапа Chatto.
Как установить Chatto на VPS: 5 шагов
1. Разворачиваем VPS и направляем на него DNS
Заказываем VPS Medium на CentOS 9 x64. Docker-образы Chatto запускаются на любом дистрибутиве Linux с установленным Docker — нет специфичного для дистрибутива пути установки, как бывает у инструментов, которые поставляются только RPM-пакетами под RHEL. Так что CentOS 9 x64 — нормальный дефолт.
При выдаче сервер подтверждает PRETTY_NAME="CentOS Stream 9", hostname server.domain.com, корневую ФС /dev/sda1.
Создаем две A-записи на выделенный IPv4 сервера: домен чата (chat.yourdomain.com) и его поддомен LiveKit (livekit.chat.yourdomain.com). Обе должны резолвиться до того, как Caddy пойдет за сертификатами.
2. Ставим Docker
dnf install docker-ce на CentOS Stream 9 падает без предварительного подключения репозитория Docker, поэтому используем convenience-скрипт:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker compose version
Это ставит Docker CE 29.6.1 и Docker Compose v5.3.1 и включает демон в автозагрузку — на свежем Medium укладывается меньше чем в минуту.
3. Клонируем репозиторий и генерируем окружение
git clone --depth 1 https://github.com/chattocorp/chatto.git
cd chatto/examples/dockercompose
./init-env.sh chat.yourdomain.com [email protected]
Скрипт пишет .env и livekit.generated.yaml со связанными сгенерированными секретами: токен авторизации NATS, ключи подписи cookie и шифрования Chatto, его core secret key и пару API key/secret для LiveKit, общую для обоих файлов. Ему нужен openssl, который в CentOS Stream 9 идет из коробки.
4. Настраиваем SMTP
Открываем .env и заменяем плейсхолдеры CHATTO_SMTP_* на реальные host, port, username и password вашего почтового провайдера.
Прямая регистрация по email/паролю, подтверждение и сброс пароля зависят целиком от этого — пропустите шаг, и работать будет только вход через SSO.
Дефолт после генерации — STARTTLS на порту 587; для провайдера с SMTPS на порту 465 выставьте CHATTO_SMTP_TLS=implicit.
SMTP-порты по умолчанию закрыты на тарифах Lite и Start, пока их не откроет поддержка; Medium и выше это не касается.
5. Проверяем состояние файрвола и поднимаем стек
Перед тем как что-то трогать, запустите systemctl status firewalld. На свежем Medium firewalld присутствует, но неактивен и отключен — его никто не трогал, Docker в том числе.
Весь стек живет в Docker: Caddy публикует 80 и 443 напрямую на хост, LiveKit так же публикует 7881/tcp, 3478/udp и 7882/udp, и все пять портов держат напрямую процессы docker-proxy.
Собственные правила iptables у Docker управляют этими пятью портами независимо от состояния firewalld. Порт 4222 у NATS вообще не всплывает в выводе ss — подтверждение, что он остается внутри сети Compose.
Если firewalld на вашей машине активен — убедитесь, что сервис ssh все еще в списке разрешенных, чтобы не потерять удаленный доступ; больше ничего здесь правила firewalld не требует.
docker compose pull -q
docker compose up -d
docker compose ps
От чистого пула образов все четыре контейнера отрапортовали healthy или running за 1 минуту 53 секунды.
Caddy при первом запуске сам запрашивает оба сертификата у Let’s Encrypt; смотрите docker compose logs caddy на две строки certificate obtained successfully — это подтверждает, что обе A-записи зарезолвились до того, как отработал ACME-челлендж.
VPS
KVM VPS с выделенным IPv4 и еженедельными бэкапами в комплекте — хватит на все четыре контейнера Chatto с запасом под голос и видео, в 40+ локациях рядом с командой.
Как пользоваться Chatto: комнаты, треды, звонки
Заходим на https://chat.yourdomain.com. Свежая установка уже должна быть с группой «Lobby» с двумя комнатами — #announcements (Universal, участник добавляется автоматически) и #general (можно вступить), так что запостить есть куда сразу.

Регистрация в два шага: вводите email, указанный в CHATTO_OWNERS_EMAILS, и подтверждаете код от Chatto, затем на втором экране задаете username и пароль. Как только email подтвержден, Chatto автоматически назначает роль владельца.

Вступите в #general, напишите сообщение и ответьте в треде — увидите, как Chatto держит контекст треда отдельно от основной ленты.

Чтобы прогнать связку с LiveKit целиком, нажмите иконку телефона в шапке комнаты и начните звонок: рабочий звонок с живым микрофоном и контролами демонстрации экрана подтверждает, что путь fallback через TCP 7881 и оба UDP-порта для медиа реально доступны снаружи VPS.
Создание новых комнат за иконкой шестеренки рядом с именем сервера, открывающей админку; оттуда Rooms → New Room создает комнату и привязывает ее к группе (каждая комната требует группу, а room.create — действие с проверкой прав). В том же разделе — участники, роли, права, модерация и лог событий.
Для админской работы на уровне аккаунтов вне браузера — например, сбросить пароль без веб-интерфейса:
docker compose exec -u chatto chatto /chatto operator user list --search [email protected]
docker compose exec -u chatto chatto /chatto operator user set-password USER_ID
Как обновлять Chatto
docker compose pull
docker compose up -d
Compose пересоздает только те контейнеры, у которых сменился образ; NATS и его том с данными обновление Chatto или LiveKit не трогает.
Добавьте bind-mount к сервису chatto в compose.yml:
chatto:
volumes:
- ./backups:/backups
Контейнер по умолчанию работает под UID/GID 1000 (PUID/PGID в .env), а entrypoint не чинит владельца рекурсивно на смонтированных томах — так что директория на хосте должна уже принадлежать этому UID, иначе бэкап упадет с ошибкой прав:
mkdir -p backups
chown -R 1000:1000 backups
docker compose up -d
Команда бэкапа еще и не примет интерактивный ввод пароля внутри docker compose exec. Ей нужен --passphrase-file, указывающий на файл, который контейнер может прочитать:
openssl rand -base64 32 > backups/backup-passphrase.txt
chmod 600 backups/backup-passphrase.txt
docker compose exec -u chatto chatto /chatto backup --encrypt --include-keys \
--passphrase-file /backups/backup-passphrase.txt \
-o /backups/chatto-$(date +%F).tar.gz.age
На почти пустом тестовом сервере это забэкапило четыре стрима NATS (события сервера, ключи шифрования, runtime-состояние, ассеты сервера), корректно пропустило один (эфемерный кэш присутствия) и выдало зашифрованный архив на 20 КБ за 33 миллисекунды.
Это все, что нужно, чтобы восстановить комнаты, сообщения и ключи для их чтения на чистый сервер, не трогая остальной VPS. Когда выйдете за пределы тестов, держите файл с паролем где-нибудь, кроме папки с архивами.
Backup Storage
Бесплатные еженедельные бэкапы VPS на всех тарифах — страховочный пол под собственными шифрованными бэкапами Chatto, чтобы комнаты и ключи сообщений пережили неудачное обновление.
Что в итоге работает
VPS Medium на CentOS 9 x64 (3 CPU, 4 GB RAM, 40 GB NVMe, $21,24/мес) прошел путь от голого dnf install до четырех healthy-контейнеров за 1 минуту 53 секунды — с установкой Docker включительно — и теперь крутит Chatto v0.4.12 за автоматическим HTTPS от Caddy, с выделенным контейнером NATS JetStream под хранилище и LiveKit, тянущим голос и видео целиком, включая демонстрацию экрана.
Стек занимает около 1 GB диска и примерно 660 MB RAM в простое — комфортный запас на тарифе с 4 GB.
Chatto выкатывает релизы достаточно часто, чтобы этот номер версии успел устареть к моменту вашей установки; проверяйте через docker compose exec chatto /chatto --version, а не полагайтесь на то, что он еще актуален.
Комнаты, треды, полнотекстовый поиск и шифрованные на диске сообщения уже живут на вашем домене, а команда зашифрованного бэкапа готова встать на расписание.
FAQ
С чем Chatto справится, а с чем нет?
Chatto поставляется как один бинарник на Go размером около 70 МБ или как Docker-образ, собранный из того же бинарника. Вместо привычной базы данных он хранит все — сообщения, пользователей, комнаты, вложения — в NATS с персистентностью через JetStream.
Для продакшена проект советует запускать NATS отдельным контейнером: тогда Chatto можно перезапускать, масштабировать на несколько реплик или обновлять без даунтайма, не трогая хранилище.
Поверх этой базы Chatto закрывает почти все, чего ждешь от командного чата: комнаты и группы комнат со своими границами прав, треды, реакции, личные сообщения, полнотекстовый поиск, вложения с генерацией превью и опциональным транскодингом видео через встроенный ffmpeg.
Голос и видео, включая демонстрацию экрана, идут через LiveKit — опенсорсный WebRTC-медиасервер, который в примере Docker Compose разворачивается рядом с Chatto.
Проект пока до 1.0 и двигается быстро: четыре патч-релиза (с v0.4.8 по v0.4.12) вышли примерно за неделю, пока писался этот гайд. Готовьтесь к багам, готовьтесь к тому, что публичный API поменяется без предупреждения, и читайте release notes перед каждым обновлением.
Еще Chatto принципиально не федерируется: каждый инстанс — отдельное изолированное сообщество со своими аккаунтами, связать два селф-хостинговых сервера между собой нельзя.
Chatto против Slack, Discord и Teams: когда селф-хостинг оправдан?
ChattoCorp прямо заявляет: премиум-тарифа не будет, оплаты за место не будет, рекламы в селф-хостинговом сервере тоже. Единственный платный продукт — управляемый хостинг Chatto Cloud, с которого можно съехать в любой момент.
Текст сообщений и поля личного аккаунта шифруются на диске персональными ключами, а удаление аккаунта уничтожает эти ключи, а не помечает строки как удаленные. Именно такая модель работы с данными — плюс то, что проект сделан в ЕС с прицелом на GDPR, — и есть настоящий аргумент запускать его у себя, а не доверять переписку команды чужой платформе.
И веб-приложение, и сигналинг звонков работают по обычным HTTPS и WebSocket, так что расположение сервера напрямую влияет на качество связи: 40+ локаций у is*hosting превращают выбор точки поближе к команде в опцию при оформлении, а не в будущую миграцию.
VPS в 40+ локациях
Выберите несколько VPS в разных регионах и управляйте всем из одного аккаунта.
От $5.94/месяц