Docker и DevOps 13 мин чтения 2026-10-18

Совместная база знаний и документация в Docmost: развертывание открытой альтернативы Notion и Confluence на VDS в Docker Compose

Пошаговое руководство по развертыванию Docmost в Docker Compose на VDS: совместное редактирование в реальном времени, замена Notion и Confluence, Nginx Reverse Proxy и автоматические бэкапы.

Алексей Иванов Проверено инженерами SysKit.ru

После ужесточения условий и блокировок зарубежных облачных 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 Гбит/с.

Конфигурация
2 vCPU 3.3 ГГц • 2 ГБ RAM • 30 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Надежные облачные серверы

Отказоустойчивая инфраструктура в сертифицированных дата-центрах Tier III для бесперебойного доступа к корпоративной документации.

Конфигурация
2 vCPU • 2 ГБ RAM • 30 ГБ NVMe • Дата-центры Tier III
Простота и стабильность
🟠

Beget — Простота для веб-разработчиков

Мгновенное развертывание Nginx и сайтов в 1 клик, интуитивная панель управления сервером, бесплатные автоматические бэкапы и отзывчивая поддержка 24/7.

Конфигурация
2 vCPU • 2 ГБ RAM • 20 ГБ NVMe • Бесплатные бэкапы

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.

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Чем Docmost отличается от Outline, BookStack и Notion?
Docmost предоставляет современный блочный визуальный редактор с поддержкой перетаскивания (drag-and-drop), как в Notion, и совместное редактирование в реальном времени, как в Google Docs. В отличие от Outline, Docmost не требует обязательной настройки сторонних провайдеров OIDC/Google/Slack для входа — в нем есть полноценная локальная аутентификация по логину и паролю. По сравнению с BookStack, архитектура документов в Docmost более гибкая и не привязана к жесткой иерархии "книга-глава-страница".
Сколько оперативной памяти требуется для Docmost при команде в 15–20 человек?
Для комфортной работы команды из 15–20 одновременно активных пользователей рекомендуется сервер с 2 ГБ RAM (Docmost занимает около 250–400 МБ, PostgreSQL 18 — около 200–300 МБ, Redis 8 — до 50 МБ). На тарифе с 1 ГБ памяти стек также запустится, но при пиковой индексации поиска или совместном редактировании больших документов возможны задержки без активного Swap-файла.
Почему при совместном редактировании документов редактор выдает ошибку соединения?
Совместное редактирование документов в Docmost построено на WebSocket-соединениях через протокол Yjs. Если в Nginx или Caddy не настроены директивы Upgrade и Connection, либо proxy_read_timeout оставлен по умолчанию (60 секунд), обратный прокси будет принудительно обрывать неактивные WebSocket-сессии. Установка proxy_read_timeout 86400s полностью решает эту проблему.
Как перенести данные Docmost на другой сервер при переезде?
Достаточно перенести файл окружения .env, каталог данных /opt/docmost/data (где лежат загруженные вложения) и создать логический дамп базы данных PostgreSQL через pg_dump. На новом VDS вы разворачиваете тот же docker-compose.yml и импортируете дамп в чистую БД командой pg_restore.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи