После ужесточения условий и блокировок зарубежных облачных SaaS-платформ, таких как Notion, Confluence и Coda, сотни команд и системных администраторов столкнулись с необходимостью миграции корпоративной и личной базы знаний на независимую инфраструктуру. Хранить важную техническую документацию, регламенты разработки, архитектурные схемы и заметки на сторонних серверах стало не только дорого, но и рискованно с точки зрения непрерывности бизнес-процессов.
Долгое время альтернативами оставались либо тяжеловесные корпоративные монстры с громоздким интерфейсом, либо простые блокноты вроде Memos в Docker Compose, которые отлично подходят для коротких заметок, но не справляются со структурированной документацией проектов. Появившийся и быстро завоевавший популярность проект Docmost стал золотой серединой: современный интуитивный визуальный редактор в духе Notion, встроенная поддержка интерактивных диаграмм (Mermaid, Excalidraw, Draw.io) и главное — совместное редактирование в реальном времени без задержек.
В этом руководстве мы детально разберем промышленное развертывание Docmost на сервере под управлением Linux Ubuntu / Debian с использованием Docker Compose, базы данных PostgreSQL 18 (или 16 LTS), кэширующего сервера Redis 8, обратного прокси Nginx с поддержкой постоянных WebSocket-соединений и скрипта автоматического резервного копирования.
1. Архитектура Docmost: стек NestJS, совместное редактирование Yjs и хранение данных
В отличие от многих легковесных wiki-движков на файловой системе, Docmost спроектирован для интенсивной командной работы. Архитектура сервиса строится на трех ключевых компонентах:
- Бэкенд-сервер Docmost (Node.js / NestJS): обрабатывает бизнес-логику, авторизацию пользователей, разграничение прав по пространствам (Spaces), управление версиями страниц и предоставляет REST API. Клиентский редактор построен на базе блочного движка Tiptap (ProseMirror), а для совместного редактирования страниц несколькими участниками одновременно используется связка Hocuspocus + Yjs поверх WebSockets — алгоритм CRDT (Conflict-free Replicated Data Types) мгновенно сливает правки без конфликтов блокировки.
- База данных PostgreSQL: хранит пользователей, структуру рабочих пространств, метаданные страниц, комментарии и журналы изменений (поддерживаются стабильные ветки 16/17, а также upstream-образ 18 из репозитория проекта).
- Кэш и шина сообщений Redis: обеспечивает быструю синхронизацию состояний сессий Yjs в реальном времени, координацию воркеров и кэширование поисковых индексов.
- Файловое хранилище (Storage): локальный том Docker для хранения загруженных пользователями аватаров, скриншотов, PDF-файлов и архивов.
⚡ Особенность совместного редактирования в Nginx
Поскольку совместный редактор Docmost передает изменения документов через WebSockets в реальном времени, обратный прокси-сервер обязан поддерживать корректный апгрейд HTTP-соединений до протокола WS и удерживать сессию без сброса по стандартным 60-секундным тайм-аутам. Все необходимые директивы Nginx мы разберем в соответствующем разделе статьи.
Приведенные ниже замеры потребления оперативной памяти зафиксированы на практике с помощью утилиты docker stats на сервере Ubuntu 24.04 LTS при одновременной работе 5–7 активных авторов документации:
| Компонент | Назначение в стеке | Потребление RAM в простое | Потребление RAM под нагрузкой |
|---|---|---|---|
| Docmost App | Веб-интерфейс, NestJS API, Hocuspocus/Yjs сервер | ~180–240 МБ | ~350–500 МБ |
| PostgreSQL | Реляционная СУБД, хранение документов и истории | ~60–90 МБ | ~150–300 МБ |
| Redis 8 | Шина событий Pub/Sub и кэш сессий коллаборации | ~20–35 МБ | ~50–80 МБ |
| Nginx | Reverse Proxy, терминация SSL, раздача статики | ~15–25 МБ | ~30–50 МБ |
2. Подготовка Linux VDS: создание пользователя, изоляция каталогов и генерация секретов
Перед запуском контейнеров подготовим базовую безопасность хоста. Категорически не рекомендуется запускать стек из-под суперпользователя root или хранить рабочие файлы в каталоге /root.
Подключитесь к вашему VDS по SSH и обновите репозитории операционной системы:
# Обновляем пакетную базу Ubuntu / Debian
sudo apt update && sudo apt upgrade -y
# Устанавливаем базовые системные утилиты
sudo apt install -y curl wget git openssl jq ufw
Создадим изолированный рабочий каталог для сервиса и сгенерируем криптографические ключи, необходимые для шифрования сессий и пароля базы данных:
# Создаем структуру каталогов
sudo mkdir -p /opt/docmost/{data,postgres,redis}
cd /opt/docmost
# Генерируем 64-символьный криптографический секрет для APP_SECRET
openssl rand -hex 32
# Генерируем надежный пароль для пользователя PostgreSQL
openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 20; echo
Для быстрой генерации стойких паролей прямо в браузере вы также можете воспользоваться встроенным инструментом Генератор надежных паролей онлайн, который позволяет задать требуемый набор символов и исключить неоднозначные знаки.
3. Развертывание Docmost в Docker Compose с PostgreSQL и Redis
Для управления конфигурацией разделим переменные окружения и сам манифест сервисов. Создадим файл конфигурации окружения /opt/docmost/.env. Обратите внимание: переменная APP_URL обязательно должна содержать полный протокол https:// и боевой поддомен, по которому пользователи будут открывать базу знаний (например, https://wiki.example.com).
# /opt/docmost/.env
# Замените значения на сгенерированные в предыдущем шаге ключи!
APP_URL=https://wiki.example.com
APP_SECRET=d3b07384d113edec49eaa6238ad5ff00f9bb1bfb1c552093240e53a25ef7b9d5
# Параметры базы данных PostgreSQL
POSTGRES_DB=docmost
POSTGRES_USER=docmost_user
POSTGRES_PASSWORD=SuperSecretDbPassword2026
# Строки подключения для Docmost
DATABASE_URL=postgresql://docmost_user:SuperSecretDbPassword2026@db:5432/docmost?sslmode=disable
REDIS_URL=redis://redis:6379
⚠️ Важное правило составления пароля базы данных
Строка подключения DATABASE_URL парсится стандартным URI-парсером бэкенда. Если пароль к PostgreSQL содержит зарезервированные символы URL, такие как @, :, /, #, ? или !, подключение завершится ошибкой синтаксиса или сбоем аутентификации. Рекомендуется генерировать строго буквенно-цифровые пароли (например, через openssl rand -hex 16), либо экранировать спецсимволы по стандарту URL-encoding (например, %40 вместо @).
Защитим файл с паролями и токенами от чтения посторонними процессами:
chmod 600 /opt/docmost/.env
Теперь создадим основной манифест /opt/docmost/docker-compose.yml. Обратите особое внимание на публикацию портов приложения: мы привязываем порт 3000 строго к локальному интерфейсу 127.0.0.1:3000:3000. Это исключает классическую уязвимость, когда Docker публикует сервисы во внешнюю сеть в обход правил фаервола хоста (подробнее этот механизм разобран в статье о том, как закрыть порты Docker от обхода UFW). Для защиты VDS от OOM Killer мы также задаем прямые лимиты памяти mem_limit.
# /opt/docmost/docker-compose.yml
services:
docmost:
image: docmost/docmost:latest
container_name: docmost_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .env
environment:
NODE_ENV: production
ports:
# Проксируем только на локальный адрес! Доступ снаружи закрыт
- "127.0.0.1:3000:3000"
volumes:
- ./data:/app/data/storage
mem_limit: 800m
cpus: 1.5
deploy:
resources:
limits:
memory: 800M
cpus: '1.5'
db:
image: postgres:18 # Официальный образ upstream (для LTS-ветки также подходит postgres:16-alpine)
container_name: docmost_db
restart: unless-stopped
env_file:
- .env
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 512m
cpus: 1.0
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
redis:
image: redis:8-alpine
container_name: docmost_redis
restart: unless-stopped
command: ["redis-server", "--appendonly", "yes", "--maxmemory", "200mb", "--maxmemory-policy", "noeviction"]
volumes:
- ./redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 256m
cpus: 0.5
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
Запустим контейнеры стека в фоновом режиме:
# Запуск контейнеров
cd /opt/docmost
docker compose up -d
# Проверяем состояние всех служб
docker compose ps
Убедимся, что приложение успешно подключилось к базе данных и выполнило начальные миграции:
# Смотрим последние логи контейнера Docmost
docker compose logs -f docmost
Если в логах отображается строка Docmost server running on port 3000, все три службы работают синхронно. Проверим, что локальный сокет слушает запросы:
curl -I http://127.0.0.1:3000
4. Первичная инициализация, создание рабочей области и настройка прав доступа
При первом переходе по адресу вашей базы знаний Docmost встречает приветственным мастером первоначальной настройки. Вы создаете учетную запись главного администратора (имя, корпоративный email и надежный мастер-пароль).
🔒 Разграничение пространств (Spaces)
В Docmost вся база знаний делится на Пространства (Spaces). Для командной работы рекомендуется сразу разделить проект на логические зоны:
- Инженерия и DevOps: закрытое пространство с регламентами деплоя, доступами и архитектурой серверов (доступ только системным инженерам).
- Разработка (Backend & Frontend): API-контракты, стандарты написания кода, правила ревью.
- Общие знания (General): онбординг новичков, структура компании, инструкции для сотрудников.
Внутри редактора документов поддерживается форматирование Markdown, вставка сниппетов кода с подсветкой синтаксиса на базе Lowlight / Highlight.js для десятков популярных языков программирования, а также визуальные интерактивные доски:
- Mermaid: создание диаграмм последовательностей (Sequence diagrams), блок-схем и графиков прямо из текстового описания.
- Excalidraw & Draw.io: встроенные векторные редакторы для быстрых архитектурных набросков систем без переключения во внешние сервисы.
5. Требования к ресурсам VDS и выбор надежного хостинга
База знаний и корпоративная wiki — это критически важный сервис постоянной доступности. Когда сотрудники пишут код, согласовывают релизы или обращаются к внутренней документации во время устранения аварий, недоступность VDS парализует работу всей команды.
При выборе конфигурации виртуального сервера для стека Docmost обратите внимание на следующие ключевые параметры:
- Оперативная память (RAM): Минимальный объем для запуска стека Docmost + PostgreSQL 18 + Redis 8 составляет 1.5–2 ГБ. Если на сервере также работают фоновые задачи или Nginx, мы рекомендуем выбирать тариф минимум с 2 ГБ RAM. На серверах с 1 ГБ памяти необходимо обязательно подключить Swap-файл (1–2 ГБ), чтобы предотвратить срабатывание OOM Killer в моменты пиковой индексации документов.
- Дисковая подсистема (NVMe): PostgreSQL постоянно выполняет синхронизацию журнала упреждающей записи (WAL) и обновляет индексы полнотекстового поиска. Быстрые диски NVMe гарантируют мгновенное автосохранение правок и плавный отклик интерфейса даже при одновременной работе нескольких десятков авторов.
- Сетевой пинг и стабильность соединения: Для технологии совместного редактирования Yjs в реальном времени критически важна низкая сетевая задержка (Latency до 15–30 мс). Выбирайте дата-центры, расположенные максимально близко к вашей аудитории или офису (Москва, Санкт-Петербург).
🔍 Диагностика перед покупкой
Перед переносом критических сервисов на новый сервер проверьте сетевой маршрут и параметры доменного резолвинга с помощью нашего онлайн-инструмента DNS Lookup и Резолвер, а также убедитесь в доступности провайдера через Проверку хостинга и провайдера сайта.
Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud — Быстрые NVMe VDS
Высокочастотные процессоры 3.3+ ГГц для быстрой отдачи веб-страниц и совместного редактирования, NVMe-диски и надежный сетевой канал 1 Гбит/с.
Selectel — Надежные облачные серверы
Отказоустойчивая инфраструктура в сертифицированных дата-центрах Tier III для бесперебойного доступа к корпоративной документации.
Beget — Простота для веб-разработчиков
Мгновенное развертывание Nginx и сайтов в 1 клик, интуитивная панель управления сервером, бесплатные автоматические бэкапы и отзывчивая поддержка 24/7.
6. Безопасная публикация через Nginx Reverse Proxy с поддержкой WebSocket и SSL
Для безопасного доступа пользователей и шифрования передаваемых данных настроим веб-сервер Nginx в качестве обратного прокси с автоматическим выпуском бесплатного SSL-сертификата Let's Encrypt.
Установим Nginx и Certbot в операционную систему:
sudo apt install -y nginx certbot python3-certbot-nginx
Создадим конфигурационный файл виртуального хоста /etc/nginx/sites-available/docmost.conf:
# /etc/nginx/sites-available/docmost.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name wiki.example.com;
# Максимальный размер загружаемых документов и изображений
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# Заголовки для постоянных WebSocket-соединений (Yjs Collaboration)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
# Увеличенные тайм-ауты для предотвращения разрыва редактора
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
# Отключаем буферизацию для мгновенной отдачи потоковых данных
proxy_buffering off;
}
}
Для детальной кастомизации директив веб-сервера вы можете сгенерировать готовые сниппеты с помощью нашего интерактивного генератора конфигураций Nginx.
Активируем сайт и проверим синтаксис Nginx:
# Создаем символическую ссылку
sudo ln -s /etc/nginx/sites-available/docmost.conf /etc/nginx/sites-enabled/
# Проверяем корректность конфигурации
sudo nginx -t
# Перезагружаем Nginx
sudo systemctl reload nginx
Получим доверенный SSL-сертификат и настроим автоматический редирект с HTTP на HTTPS:
sudo certbot --nginx --redirect -d wiki.example.com
🔒 Проверка безопасности SSL и портов
После выпуска сертификата убедитесь в правильности цепочки TLS и отсутствии уязвимых протоколов с помощью инструмента Проверка SSL / TLS сертификата, а также проверьте, что порт базы данных 5432 и Redis 6379 не видны из интернета, через Сканер портов онлайн.
7. Автоматическое резервное копирование PostgreSQL и вложений на VDS
База знаний накапливает интеллектуальную собственность компании. Без регулярного бэкапа любой сбой диска или случайное удаление пространства обернется катастрофой. Реализуем надежный скрипт резервного копирования базы данных и загруженных файлов.
Создадим скрипт /opt/docmost/backup.sh:
#!/usr/bin/env bash
set -eo pipefail
BACKUP_DIR="/opt/docmost-backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
KEEP_DAYS=7
mkdir -p "${BACKUP_DIR}"
echo "[INFO] Начало резервного копирования Docmost: ${TIMESTAMP}"
# 1. Дамп базы данных PostgreSQL непосредственно из контейнера
docker exec docmost_db pg_dump -U docmost_user -d docmost -F c -b > "${BACKUP_DIR}/docmost_db_${TIMESTAMP}.dump"
# Проверка, что дамп не пустой
if [ ! -s "${BACKUP_DIR}/docmost_db_${TIMESTAMP}.dump" ]; then
echo "[ERROR] Дамп базы данных пуст или завершился сбоем!" >&2
exit 1
fi
# 2. Архивирование пользовательских файлов и вложений
tar -czf "${BACKUP_DIR}/docmost_files_${TIMESTAMP}.tar.gz" -C /opt/docmost data
# 3. Off-site репликация в независимое S3/WebDAV хранилище (rclone)
if command -v rclone &> /dev/null; then
rclone copy "${BACKUP_DIR}" s3-backup:docmost-backups/ --fast-list
fi
# 4. Удаление локальных копий старше 7 дней
find "${BACKUP_DIR}" -type f -name "docmost_*" -mtime +"${KEEP_DAYS}" -delete
echo "[INFO] Резервное копирование успешно завершено!"
☁️ Правило 3-2-1: почему нельзя хранить бэкапы только на VDS
Хранить резервные копии исключительно на локальном диске того же сервера — критическая архитектурная ошибка. При аппаратном сбое гипервизора, повреждении накопителя или повреждении файловой системы хоста вы потеряете и рабочую базу знаний, и бэкапы одновременно. Обязательно настройте утилиту rclone (или s3cmd) для ежедневной отправки дампов в независимое объектное S3-хранилище или на резервный домашний/офисный сервер по SSH.
Сделаем скрипт исполняемым и добавим его в системный планировщик cron для ежедневного запуска в 03:00 ночи:
chmod +x /opt/docmost/backup.sh
# Открываем crontab суперпользователя
sudo crontab -e
# Добавляем строку ежедневного бэкапа:
0 3 * * * /opt/docmost/backup.sh >> /var/log/docmost-backup.log 2>&1
8. Итоговый чек-лист ввода в эксплуатацию
Перед добавлением всей команды в рабочее пространство выполните контрольную проверку по нашему чек-листу:
📋 Чек-лист готовности Docmost к промышленной эксплуатации
- Порты изолированы: Контейнеры Docmost, PostgreSQL и Redis привязаны к
127.0.0.1и закрыты от прямого доступа извне. - SSL и редирект: Включен HTTPS с автоматическим перенаправлением с HTTP (проверено через SSL-чекер).
- Поддержка WebSockets: В Nginx настроены заголовки
Upgradeи увеличенproxy_read_timeout 86400s— редактор не теряет соединение при совместной работе. - Лимиты ресурсов: Для контейнеров заданы ограничения по оперативной памяти (Docker memory limits) во избежание падения хоста при пиках.
- Автоматические бэкапы: Скрипт дампа PostgreSQL и архивации файлов протестирован вручную и добавлен в cron.
- Криптографические ключи: Секрет
APP_SECRETи пароли БД сгенерированы уникальными, а права на файл.envустановлены вchmod 600.