Общение с клиентами через разрозненные каналы — чат на сайте, переписку в Telegram, электронную почту и социальные сети — быстро превращается в операционный хаос. Популярные зарубежные платформы клиентской поддержки (Intercom, Crisp, Zendesk, HelpScout) либо заблокировали регистрацию для проектов из России, либо не принимают отечественные банковские карты, а их тарифные планы при команде из 3–5 операторов легко перешагивают планку в $150–300 ежемесячно. Российские SaaS-виджеты также требуют постоянной подписки за каждого подключенного менеджера и хранят чувствительную переписку с клиентами на сторонних серверах.
Оптимальным решением для малого и среднего бизнеса, интернет-магазинов и веб-студий является переход на собственный автономный центр клиентской поддержки. Лидером в классе open-source платформ для коммуникаций с клиентами выступает Chatwoot (более 23 000 звёзд на GitHub). Система предоставляет полноценный live-чат для сайта, единый почтовый ящик (Shared Inbox), бесшовную интеграцию с Telegram-ботом, мобильные приложения для iOS/Android и распределение диалогов между операторами без каких-либо искусственных лимитов.
💡 Почему Chatwoot стал стандартом среди self-hosted платформ поддержки
В отличие от простых веб-виджетов, Chatwoot спроектирован как полноценная омниканальная система: один оператор в едином интерфейсе видит сообщения с сайта, заявки из Telegram-бота и письма с корпоративной почты. История переписки сохраняется в едином профиле клиента, а операторы могут обмениваться приватными внутренними заметками прямо внутри тикета.
1. Архитектура Chatwoot: микросервисы Rails, фоновые очереди Sidekiq, pgvector и веб-сокеты ActionCable
Для стабильной эксплуатации платформы важно понимать её внутреннее устройство. Chatwoot построен на зрелом промышленном стеке и состоит из нескольких ключевых компонентов, изолированных в отдельных контейнерах:
- Rails Web Server: основной бэкенд приложения на Ruby on Rails. Обрабатывает HTTP-запросы панели управления, REST API, виджета чата и входящие вебхуки от внешних каналов (включая Telegram Bot API).
- ActionCable (WebSockets): модуль полнодуплексной передачи данных в реальном времени. Обеспечивает мгновенную доставку сообщений между клиентом на сайте и оператором без задержек и перезагрузки страниц.
- Sidekiq Workers: фоновый процессор очередей на базе Redis. Выполняет асинхронные задачи: отправку почтовых уведомлений, генерацию превью вложений, обработку событий вебхуков и маршрутизацию диалогов по операторам.
- PostgreSQL 16 с расширением pgvector: реляционная база данных для хранения учетных записей, профилей клиентов, текстовых диалогов и настроек. Начиная с современных версий, Chatwoot активно использует
pgvectorдля векторного поиска и интеграции встроенных ИИ-функций. - Redis 7: высокоскоростное in-memory хранилище для очередей Sidekiq, кэширования сессий пользователей и pub/sub брокера для мгновенной доставки веб-сокетов.
| Компонент | Базовый образ | Назначение | Память (RAM) |
|---|---|---|---|
rails |
chatwoot/chatwoot:latest |
Веб-интерфейс, API, сокеты ActionCable | 800–1200 МБ |
sidekiq |
chatwoot/chatwoot:latest |
Асинхронные очереди, вебхуки, рассылки | 600–900 МБ |
postgres |
pgvector/pgvector:pg16 |
Основная база данных и векторные индексы | 250–500 МБ |
redis |
redis:7-alpine |
Очереди задач, pub/sub для веб-сокетов | 50–100 МБ |
2. Подготовка операционной системы Linux VDS: системные требования, Swap-файл и генерация криптостойких секретов
Для развертывания Chatwoot рекомендуется виртуальный сервер (VDS) под управлением Ubuntu 24.04 LTS или Debian 12. Минимальная рекомендуемая конфигурация — 2 vCPU и 4 ГБ RAM. На серверах с 2 ГБ оперативной памяти запуск также возможен, однако обязательным условием является создание файла подкачки (Swap) объемом не менее 2–4 ГБ во избежание срабатывания Linux OOM Killer во время компиляции ассетов и пиковых очередей Sidekiq.
Создадим и активируем Swap-файл размером 2 ГБ:
# Проверяем текущее состояние оперативной памяти и подкачки
free -h
# Создаем файл подкачки размером 2 ГБ
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Закрепляем активацию swap при перезагрузке сервера
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Устанавливаем умеренную агрессивность сброса страниц в swap
sudo sysctl vm.swappiness=20
echo 'vm.swappiness=20' | sudo tee -a /etc/sysctl.conf
Создадим изолированный рабочий каталог для проекта и сгенерируем криптостойкие секретные ключи:
# Создаем структуру каталогов в /opt
sudo mkdir -p /opt/chatwoot
cd /opt/chatwoot
# Генерируем мастер-ключ SECRET_KEY_BASE (строка hex из 64 байт)
openssl rand -hex 64
# Генерируем надежные пароли для базы данных PostgreSQL и брокера Redis
openssl rand -hex 24
openssl rand -hex 24
⚠️ Требования к переменной SECRET_KEY_BASE
Значение SECRET_KEY_BASE используется фреймворком Rails для шифрования пользовательских сессий, подписания cookies и защиты от подделки запросов (CSRF). Этот ключ обязан содержать только алфавитно-цифровые символы и быть строго постоянным. Если вы измените или потеряете его после запуска, все активные сессии операторов будут аннулированы, а зашифрованные системные токены каналов связи станут нечитаемыми.
Для генерации стойких паролей вы также можете воспользоваться встроенным инструментом SysKit «Генератор надежных паролей онлайн».
3. Манифест Docker Compose: запуск Chatwoot с PostgreSQL 16, Redis 7 и изоляцией портов
Конфигурация Chatwoot разделяется на два файла: файл переменных окружения .env и оркестрационный манифест docker-compose.yml. Создадим файл /opt/chatwoot/.env со всеми необходимыми директивами для производственного контура:
# Переходим в каталог проекта
cd /opt/chatwoot
# Создаем файл переменных окружения
cat << 'EOF' > .env
# Среда выполнения Rails и базовый домен приложения
RAILS_ENV=production
NODE_ENV=production
INSTALLATION_ENV=docker
FRONTEND_URL=https://chat.example.com
# Секретный ключ для сессий и cookies (подставьте сгенерированный hex)
SECRET_KEY_BASE=a1b2c3d4e5f60718293a4b5c6d7e8f90123456789abcdef0123456789abcdef0
# Локализация по умолчанию (русский язык для интерфейса и операторов)
DEFAULT_LOCALE=ru
# Запрет открытой публичной регистрации новых аккаунтов (защита от спамеров)
ENABLE_ACCOUNT_SIGNUP=false
FORCE_SSL=true
# Параметры подключения к PostgreSQL 16
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DATABASE=chatwoot_production
POSTGRES_USERNAME=chatwoot
POSTGRES_PASSWORD=SuperSecurePostgresPassword2026
# Параметры подключения к Redis 7
REDIS_URL=redis://redis:6379
REDIS_PASSWORD=SuperSecureRedisPassword2026
# Лимиты хранилища и загрузки медиафайлов
ACTIVE_STORAGE_SERVICE=local
EOF
Теперь создадим манифест docker-compose.yml. В соответствии со стандартами безопасности SysKit служебные порты СУБД и Redis изолированы внутри виртуальной Docker-сети chatwoot-net и физически не публикуются наружу на сетевых интерфейсах сервера. Порт веб-приложения 3000 жестко привязан к локальной петле 127.0.0.1, что полностью исключает прямой доступ в обход фаервола:
services:
base: &base
image: chatwoot/chatwoot:latest
env_file: .env
volumes:
- storage_data:/app/storage
networks:
- chatwoot-net
rails:
<<: *base
container_name: chatwoot_rails
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "127.0.0.1:3000:3000"
environment:
- NODE_ENV=production
- RAILS_ENV=production
- INSTALLATION_ENV=docker
entrypoint: docker/entrypoints/rails.sh
command: ["bundle", "exec", "rails", "s", "-p", "3000", "-b", "0.0.0.0"]
mem_limit: 1536m
cpus: 1.5
sidekiq:
<<: *base
container_name: chatwoot_sidekiq
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
- NODE_ENV=production
- RAILS_ENV=production
- INSTALLATION_ENV=docker
command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
mem_limit: 1024m
cpus: 1.0
postgres:
image: pgvector/pgvector:pg16
container_name: chatwoot_postgres
restart: unless-stopped
environment:
POSTGRES_DB: chatwoot_production
POSTGRES_USER: chatwoot
POSTGRES_PASSWORD: SuperSecurePostgresPassword2026
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- chatwoot-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U chatwoot -d chatwoot_production"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 1024m
cpus: 1.0
redis:
image: redis:7-alpine
container_name: chatwoot_redis
restart: unless-stopped
command: ["sh", "-c", "redis-server --requirepass \"$REDIS_PASSWORD\""]
env_file: .env
volumes:
- redis_data:/data
networks:
- chatwoot-net
healthcheck:
test: ["CMD", "redis-cli", "-a", "$REDIS_PASSWORD", "ping"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 256m
cpus: 0.5
networks:
chatwoot-net:
driver: bridge
volumes:
storage_data:
postgres_data:
redis_data:
💡 Защита портов баз данных от внешнего сканирования
Обратите внимание: сервисы postgres и redis вообще не содержат блока ports. Контейнеры обмениваются трафиком через изолированный bridge-драйвер по внутренним DNS-именам postgres:5432 и redis:6379. Проверить отсутствие утечек портов в публичный интернет можно с помощью инструмента SysKit «Сканер портов онлайн».
4. Первичная инициализация базы данных и создание учетной записи суперадминистратора
Перед первым запуском стека необходимо подготовить схему реляционной базы данных PostgreSQL. В Chatwoot предусмотрена специальная rake-задача db:chatwoot_prepare, которая автоматически создает таблицы, применяет миграции и наполняет начальные справочники:
# Запускаем инициализацию базы данных в изолированном контейнере
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
Процесс первичной инициализации занимает от 1 до 3 минут. По завершении вы увидите сообщение об успешном выполнении всех миграций схемы (Active Record schema loaded). Теперь запускаем все сервисы в фоновом режиме:
# Запускаем стек контейнеров Chatwoot
docker compose up -d
# Проверяем статус работы и показатели здоровья (healthcheck)
docker compose ps
Все 4 контейнера должны перейти в статус Up (healthy). Убедимся, что веб-сервер Rails успешно слушает локальный сокет на порту 3000:
# Проверяем локальный ответ сервиса
curl -I http://127.0.0.1:3000/api/v1/profile
Сервис вернет корректный HTTP-ответ 401 Unauthorized (что подтверждает активность API и ожидание авторизационного токена).
5. Расчет серверных ресурсов VDS и выбор надежного хостинга
Потребление ресурсов экземпляром Chatwoot зависит от количества одновременно подключенных операторов, суточного объема диалогов и интенсивности отправки медиафайлов. Основная нагрузка приходится на процесс Rails Puma и фоновые потоки Sidekiq, которые удерживают сокетные соединения и обрабатывают очереди задач.
| Масштаб проекта | Операторы | Диалогов в сутки | Рекомендуемая конфигурация |
|---|---|---|---|
| Стартап / Небольшой сайт | 1–3 оператора | до 300 | 2 vCPU • 3–4 ГБ RAM • 25 ГБ NVMe |
| Интернет-магазин / Агентство | 4–12 операторов | до 2 000 | 4 vCPU • 6–8 ГБ RAM • 50 ГБ NVMe |
| Корпоративный центр поддержки | 15+ операторов | от 5 000 | 6–8 vCPU • 16 ГБ RAM • 100 ГБ NVMe |
При выборе хостинга для Chatwoot критически важны три фактора:
- Высокая тактовая частота процессора (от 3.0 ГГц): обработка сокетов ActionCable и рендеринг веб-хуков требовательны к производительности на одно ядро.
- Быстрые NVMe-накопители: транзакционная активность PostgreSQL 16 и операции с индексами требуют минимального времени отклика I/O.
- Стабильный сетевой канал в РФ: клиенты на сайте и операторы в панели не должны сталкиваться с обрывами WebSocket-соединений из-за сетевых задержек.
Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud — Быстрые NVMe VDS
Высокочастотные процессоры 3.3+ ГГц для моментальной отдачи веб-сокетов ActionCable, NVMe-диски и быстрый канал до 1 Гбит/с.
Selectel — Надежные облачные серверы
Отказоустойчивая инфраструктура в сертифицированных дата-центрах Tier III для бесперебойного приема обращений клиентов 24/7.
Beget — Простота для веб-разработчиков
Интуитивная панель управления сервером, надежная виртуализация KVM, автоматические ежедневные бэкапы и отзывчивая поддержка 24/7.
6. Настройка Nginx Reverse Proxy: SSL-сертификат Let's Encrypt и бесперебойные WebSocket-сессии
Сервис Chatwoot взаимодействует с браузерами операторов и клиентами на сайте через постоянные двусторонние соединения WebSocket (ActionCable). Если обратный прокси-сервер настроен некорректно или обрывает неактивные TCP-сессии по стандартному таймауту в 60 секунд, виджет на сайте будет регулярно отключаться, а операторы перестанут получать новые сообщения без ручной перезагрузки вкладки.
Создадим виртуальный хост Nginx для домена панели управления (например, chat.example.com). Для предотвращения проблемы «курицы и яйца» (когда Nginx не может запуститься из-за еще не выпущенных SSL-сертификатов) сначала настроим базовую конфигурацию на 80 порту:
# /etc/nginx/sites-available/chatwoot.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name chat.example.com;
# Директория для прохождения ACME HTTP-01 challenge
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Критически важно для работы ActionCable WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Увеличенные таймауты для предотвращения дисконнекта сокетов
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
# Разрешаем загрузку вложений и скриншотов до 50 МБ
client_max_body_size 50M;
}
}
Активируем конфигурацию и выпустим бесплатный SSL-сертификат Let's Encrypt через Certbot с флагом принудительного редиректа на HTTPS:
# Создаем символическую ссылку и проверяем синтаксис
sudo ln -sf /etc/nginx/sites-available/chatwoot.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Выпускаем SSL-сертификат с автоматической модификацией конфига и редиректом
sudo certbot --nginx -d chat.example.com --redirect --agree-tos -m admin@example.com --no-eff-email
После выпуска сертификата убедитесь в корректности цепочки доверия и актуальности криптографических протоколов TLS с помощью чекера SysKit «Проверка SSL / TLS сертификата».
7. Подключение каналов связи: виджет онлайн-чата для сайта и интеграция с Telegram-ботом
После успешного входа в веб-панель суперадминистратора по адресу https://chat.example.com перейдем к настройке каналов приема обращений.
1. Виджет онлайн-чата для веб-сайта
Чтобы разместить виджет живого чата на вашем интернет-магазине или корпоративном портале:
- В панели Chatwoot перейдите в раздел Настройки $ ightarrow$ Входящие каналы (Inboxes) $ ightarrow$ Добавить канал.
- Выберите тип Веб-сайт (Website).
- Укажите название канала (например, «Основной сайт»), домен сайта и приветственное сообщение для посетителей.
- Назначьте операторов, которые будут получать уведомления о новых диалогах.
- Chatwoot сгенерирует готовый легковесный JavaScript-код:
<!-- Chatwoot Live Chat Widget SDK -->
<script>
(function(d,t) {
var BASE_URL = "https://chat.example.com";
var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
g.src = BASE_URL + "/packs/js/sdk.js";
g.defer = true;
g.async = true;
s.parentNode.insertBefore(g,s);
g.onload = function() {
window.chatwootSDK.run({
websiteToken: 'ВАШ_УНИКАЛЬНЫЙ_ТОКЕН_ВИДЖЕТА',
baseUrl: BASE_URL
});
}
})(document,"script");
</script>
Этот код достаточно вставить перед закрывающим тегом </body> в шаблон вашей CMS (WordPress, Bitrix, Tilda) или одностраничного лендинга. Виджет адаптируется под смартфоны и планшеты, поддерживает прикрепление файлов, эмодзи и звуковые оповещения.
2. Подключение канала Telegram-бота
Интеграция с Telegram позволяет объединить обращения клиентов из мессенджера в тот же общий инбокс:
- Откройте официального бота @BotFather в Telegram и создайте нового бота командой
/newbot. Задайте имя и юзернейм, после чего скопируйте выданный токен авторизации (HTTP API Token). - В панели Chatwoot добавьте новый входящий канал типа Telegram.
- Вставьте скопированный токен бота. Chatwoot автоматически свяжется с Telegram Bot API и зарегистрирует вебхук по адресу
https://chat.example.com/webhooks/telegram/<token>.
💡 Как работает связка с Telegram на практике
Когда клиент находит вашего бота в Telegram и пишет ему сообщение, Chatwoot мгновенно создает новый диалог в общей очереди. Оператор видит аватар и никнейм пользователя Telegram и отвечает прямо из панели управления Chatwoot. Ответ оператора немедленно отправляется в чат клиента в Telegram от имени бота. Если клиенту отвечает другой оператор, вся история переписки остается непрерывной.
8. Резервное копирование базы данных PostgreSQL, вложений и регламент обновления контейнеров
Для защиты истории переписки, карточек клиентов и загруженных файлов необходимо настроить регулярное резервное копирование. Создадим автоматический bash-скрипт /opt/chatwoot/backup.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
BACKUP_DIR="/var/backups/chatwoot"
TIMESTAMP="$(date +'%Y%m%d_%H%M%S')"
mkdir -p "$BACKUP_DIR"
# 1. Дамп базы данных PostgreSQL в формате gzip
echo "[$(date)] Создание дампа PostgreSQL..."
docker compose -f /opt/chatwoot/docker-compose.yml exec -T postgres \
pg_dump -U chatwoot -d chatwoot_production | gzip -9 > "$BACKUP_DIR/db_${TIMESTAMP}.sql.gz"
# 2. Архивация вложений и загруженных медиафайлов
echo "[$(date)] Архивация пользовательских вложений..."
tar -czf "$BACKUP_DIR/storage_${TIMESTAMP}.tar.gz" -C /var/lib/docker/volumes/chatwoot_storage_data/_data .
# 3. Установка безопасных прав (чтение только для root)
chmod 600 "$BACKUP_DIR"/*${TIMESTAMP}*
# 4. Ротация: удаление локальных архивов старше 14 дней
find "$BACKUP_DIR" -type f -name "*.gz" -mtime +14 -delete
echo "[$(date)] Резервное копирование успешно завершено!"
Сделайте скрипт исполняемым и добавьте задание в системный планировщик cron на запуск каждую ночь в 03:30:
sudo chmod +x /opt/chatwoot/backup.sh
(crontab -l 2>/dev/null; echo "30 3 * * * /opt/chatwoot/backup.sh >> /var/log/chatwoot_backup.log 2>&1") | crontab -
Регламент обновления Chatwoot
Обновление стека выполняется без риска потери пользовательских данных:
cd /opt/chatwoot
# 1. Создаем свежий бэкап перед обновлением
./backup.sh
# 2. Скачиваем обновленные образы контейнеров
docker compose pull
# 3. Запускаем миграции структуры базы данных
docker compose run --rm rails bundle exec rails db:migrate
# 4. Перезапускаем веб-сервер и воркеры Sidekiq
docker compose up -d --remove-orphans
Разверните собственный центр поддержки клиентов на надежном VDS
Для комфортной работы Chatwoot, стабильных сокетов и моментальной обработки входящих обращений критически важны низкий пинг и надежные NVMe-диски. Выберите проверенный виртуальный сервер в российском дата-центре Tier III с каналом до 1 Гбит/с и защитой от DDoS-атак.