Большинство платформ документации поставляются как стек. Вы получаете Node.js-приложение, базу данных PostgreSQL, кэш Redis, кластер Elasticsearch для поиска и обратный прокси Nginx, чтобы связать всё вместе. Пять сервисов, пять вещей, которые могут сломаться, пять вещей для мониторинга, обновления и патчинга.

DocPlatform поставляется как один файл. Скачайте, запустите, готово.

Это не маркетинговый трюк. Это архитектурное решение, принятое в первый день, и каждый последующий выбор проектирования вытекает из него. Вот почему.

Типичный стек документации

Давайте посмотрим, что вы реально развёртываете при настройке современной платформы документации:

┌─────────────┐
│   Nginx     │  ← обратный прокси, терминация TLS
├─────────────┤
│   Node.js   │  ← сервер приложения
├─────────────┤
│  PostgreSQL │  ← хранение контента
├─────────────┤
│    Redis    │  ← кэш сессий, очередь задач
├─────────────┤
│Elasticsearch│  ← полнотекстовый поиск
└─────────────┘

Это пять процессов, каждый со своими конфигурационными файлами, требованиями к версиям и режимами отказа. Docker Compose помогает с оркестрацией, но не уменьшает площадь атаки. Вам всё ещё нужно:

  • Мониторить каждый сервис на предмет падений и использования ресурсов
  • Запускать миграции базы данных при обновлениях
  • Настраивать размеры хипа и параметры индексов Elasticsearch
  • Управлять политиками вытеснения Redis при заполнении памяти
  • Ротировать логи Nginx и обновлять TLS-сертификаты

Для компании из Fortune 500 с командой платформы это рутина. Для стартапа из 10 человек, которому просто нужна внутренняя документация, это бесконечные накладные расходы.

Как выглядит один бинарный файл

Вот развёртывание DocPlatform:

┌──────────────────────────┐
│      docplatform          │  ← один бинарный файл Go
│  ┌────────┐ ┌──────────┐ │
│  │ SQLite │ │  Bleve   │ │
│  │  (БД)  │ │ (поиск)  │ │
│  └────────┘ └──────────┘ │
└──────────────────────────┘

Один бинарный файл. Один каталог данных. SQLite обрабатывает хранение контента, сессии и конфигурацию. Bleve обрабатывает полнотекстовый поиск. Оба — встроенные библиотеки, скомпилированные прямо в бинарный файл — никаких внешних процессов, никаких сетевых вызовов между сервисами.

Установка занимает 30 секунд:

curl -fsSL https://get.valoryx.org | sh
docplatform serve

Вот и всё. Никакого docker-compose up, никакой инициализации базы данных, никаких переменных окружения для строк подключения. Бинарный файл создаёт каталог данных при первом запуске и начинает обслуживать на порту 3000.

Дополнительные варианты установки — в руководстве по установке.

Почему Go делает это возможным

Мы выбрали Go именно потому, что он позволяет эту архитектуру. Три свойства важны:

Статическая компиляция

Go компилируется в один статически связанный бинарный файл. Никаких зависимостей времени выполнения, разделяемых библиотек, JVM, node_modules. Бинарный файл работает на голом сервере Linux без установки чего-либо ещё.

# Кросс-компиляция для Linux с любой ОС
GOOS=linux GOARCH=amd64 go build -o docplatform ./cmd/server/

Одна команда создаёт бинарный файл, который можно scp на сервер и запустить. Сравните с развёртыванием Node.js-приложения, где нужно установить Node, запустить npm install, надеяться, что нативные зависимости правильно скомпилируются на целевой архитектуре, и настроить менеджер процессов.

Горутины для конкурентности

Платформа документации должна обрабатывать параллельные запросы (просмотры страниц, поисковые запросы, сохранения из редактора), выполнять фоновые задачи (git-синхронизация, индексирование поиска) и управлять WebSocket-соединениями (совместная работа в реальном времени) — всё одновременно.

Горутины Go делают это дёшево. Каждое WebSocket-соединение получает свою горутину, стоящую примерно 2 КБ памяти. Node.js-серверу для обработки тех же соединений нужно управлять ими в одном event loop или выгружать в worker threads со сложностью разделяемой памяти.

Движок git-синхронизации, который опрашивает и согласовывает изменения между веб-редактором и git-репозиториями, работает как набор горутин внутри того же процесса. Никакого отдельного воркер-сервиса, очереди задач, Redis.

Встроенные базы данных

И SQLite, и Bleve написаны на C и Go соответственно, и оба компилируются прямо в бинарный файл через cgo (SQLite) и чистый Go (Bleve). Это означает:

  • Никакого сервера базы данных для установки, настройки или мониторинга
  • Никакой сетевой задержки между приложением и его данными
  • Бэкапы — это копирование файлов: cp data.db data.db.bak
  • Обновления автоматически сохраняют данные — новый бинарный файл читает старые файлы данных

SQLite обрабатывает миллиарды строк в продакшене в компаниях куда крупнее нашей. Для платформы документации, обслуживающей сотни параллельных пользователей, этого более чем достаточно.

Операционное преимущество

Подход с одним бинарным файлом окупается в эксплуатации:

Обновления — это замена одного файла. Остановите старый бинарный файл, скопируйте новый, запустите. Никаких миграций базы данных — приложение обрабатывает изменения схемы при запуске.

Бэкапы — это копирование двух файлов: базы SQLite и индекса Bleve. Или только базы — поисковый индекс можно пересобрать из контента.

Мониторинг — это наблюдение за одним процессом. Если он работает, всё работает. Если упал — перезапустите. Нет частичного отказа, когда база работает, а поиск нет.

Использование ресурсов предсказуемо. Один процесс, один объём памяти. Никаких неожиданных скачков памяти от JVM-хипа Elasticsearch или накопления ключей Redis.

Площадь безопасности минимальна. Один бинарный файл, один слушающий порт. Никакого межсервисного обмена для защиты, никакого Redis на сетевом порту, никакого кластера Elasticsearch со своим слоем аутентификации. См. нашу документацию по безопасности для полной модели.

Компромиссы, которые мы принимаем

У этой архитектуры есть ограничения, и мы честны о них:

Только вертикальное масштабирование. SQLite работает на одной машине. Нельзя распределить базу данных по кластеру. Для большинства сценариев документации — даже крупных с тысячами страниц — один современный сервер справляется с нагрузкой. Но если вам нужно горизонтальное масштабирование между дата-центрами, это не та архитектура.

Один писатель для SQLite. SQLite поддерживает параллельное чтение, но сериализует запись. На практике платформы документации нагружены чтением (много просмотров страниц, мало правок), поэтому это редко становится узким местом. Но команда из 200 человек, одновременно сохраняющих страницы, увидит некоторую конкуренцию за запись.

Без замены компонентов. Нельзя заменить Bleve на Elasticsearch, если хочется более продвинутых поисковых функций. Поисковый движок встроен, а не подключаем. Мы считаем компромисс оправданным — Bleve поддерживает стемминг, нечёткий поиск и бустинг полей, что покрывает потребности поиска по документации.

Примеры развёртывания

Один бинарный файл работает везде, где может работать процесс Linux/macOS/Windows:

Bare metal или ВМ:

# Скачайте, запустите, готово
curl -fsSL https://get.valoryx.org | sh
docplatform serve --port 3000

Systemd-сервис:

[Unit]
Description=DocPlatform
After=network.target

[Service]
ExecStart=/opt/docplatform/bin/docplatform serve
WorkingDirectory=/opt/docplatform
Restart=always

[Install]
WantedBy=multi-user.target

Docker (если хотите):

FROM scratch
COPY docplatform /docplatform
ENTRYPOINT ["/docplatform", "serve"]

Обратите внимание на FROM scratch — поскольку бинарный файл не имеет зависимостей, Docker-образ содержит буквально ничего, кроме самого бинарного файла. Размер образа менее 30 МБ.

Подробные варианты развёртывания — в руководстве по развёртыванию бинарного файла.

Что это значит для вашей команды

Каждый дополнительный сервис в вашем стеке — это сервис, который кто-то должен понять, мониторить и чинить в 2 часа ночи, когда он сломается. Инфраструктура документации должна уходить на задний план — это то, что вы настраиваете один раз и забываете.

Один бинарный файл, который встраивает всё необходимое, — самое близкое к этому идеалу, что мы нашли. Никаких контейнеров для оркестрации, баз данных для настройки, поисковых кластеров для мониторинга. Просто один файл, который обслуживает вашу документацию.

Установите DocPlatform за 30 секунд и убедитесь сами. Community Edition бесплатен — неограниченное число пользователей, неограниченное число страниц, без ограничения по времени.