Руководство по установке и использованию
Версия: 1.0
Дата: 19.04.2026
Статус: Утверждён
Полное руководство по развёртыванию документационной системы на базе Docusaurus + Decap CMS с Git-хранилищем.
Как это работает
docs/ (MD файлы)
└── Git репозиторий ← единственный источник правды
├── Docusaurus → сайт localhost:3000 (dev) / localhost:5000 (для людей)
└── Decap CMS → браузерная админка localhost:3000/admin/index.html
Принцип:
- Все документы — это MD файлы в папке
docs/ - Git хранит всю историю изменений
- Decap CMS редактирует те же файлы через браузер и автоматически делает git commit при сохранении
- Docusaurus читает эти файлы и строит сайт
Установка с нуля
Требования
- Node.js v18+ (проверить:
node --version) - Git
- WSL если на Windows (проект должен лежать на Linux FS, не на NTFS диске)
Важно про WSL и Windows
Проект обязательно должен лежать на Linux FS, не на диске D:/E: (NTFS).
Правильно:
/home/alex/sites/cms-docs/
Неправильно (будут ошибки npm install):
/mnt/d/SITES/CMS-DOCS/
Причина: NTFS не поддерживает атомарный rename который использует npm при установке пакетов. npm при установке временно переименовывает файлы — на NTFS это падает с ошибкой EPERM: operation not permitted, rename.
Если нужен доступ с Windows — открывай через VS Code путь \\wsl$\Ubuntu\home\alex\sites\cms-docs.
Шаги установки
1. Создать папку проекта на Linux FS
mkdir -p /home/alex/sites/cms-docs
cd /home/alex/sites/cms-docs
2. Инициализировать Git
git init
git config user.email "your@email.com"
git config user.name "Your Name"
Важно — переименовать ветку в main:
git branch -m master main
Это нужно сделать сразу. Decap CMS по умолчанию работает с веткой main. Если ветка называется master — CMS не сможет делать коммиты и будет выдавать ошибки авторизации или пустой список документов.
3. Развернуть Docusaurus
# Нельзя разворачивать в непустую папку — git уже создал .git
# Поэтому сначала создаём во временной папке
cd /tmp && npx create-docusaurus@latest cms-docs classic --typescript --skip-install
# Копируем в проект
cp -r /tmp/cms-docs/. /home/alex/sites/cms-docs/
cp /tmp/cms-docs/.gitignore /home/alex/sites/cms-docs/.gitignore
cd /home/alex/sites/cms-docs
4. Установить зависимости
npm install
npm install --save-dev decap-server
decap-server — это локальный proxy который позволяет Decap CMS работать с файловой системой без подключения к облаку.
5. Создать Decap CMS файлы
mkdir -p static/admin
Файл static/admin/index.html — содержит форму входа с проверкой пароля. Логин и пароль берутся из cms-config.json → admin. SHA-256 хэш пары логин:пароль прописан прямо в файле.
При смене пароля — пересчитать хэш и обновить CREDENTIALS_HASH в index.html:
echo -n "логин:пароль" | sha256sum | cut -d' ' -f1
Текущий файл static/admin/index.html хранится в репозитории — не создавать заново, редактировать существующий.
Файл static/admin/config.yml:
backend:
name: proxy
proxy_url: http://localhost:8083/api/v1
branch: main
media_folder: docs/_uploads
public_folder: /_uploads
editor:
preview: true
collections:
- name: docs
label: Документация
folder: docs
create: true
nested:
depth: 10
slug: "{{slug}}"
extension: md
format: frontmatter
meta: { path: { widget: string, label: Path, index_file: index } }
fields:
- { label: Заголовок, name: title, widget: string }
- { label: Черновик (снять с публикации), name: draft, widget: boolean, default: false, required: false }
- label: Содержимое
name: body
widget: markdown
buttons:
- bold
- italic
- strikethrough
- code
- heading-one
- heading-two
- heading-three
- heading-four
- heading-five
- heading-six
- quote
- bulleted-list
- numbered-list
- link
editor_components:
- image
- code-block
Важно про порт в proxy_url:
Порт 8083 выбран потому что 8081 и 8082 в системе могут быть заняты другими процессами (например Apache или другие сервисы). Порт в proxy_url должен совпадать с портом на котором запускается decap-server. Если меняешь порт запуска — меняй и здесь.
Как проверить какой порт свободен:
ss -tlnp | grep -E '808[1-9]'
Выбери порт которого нет в выводе.
Важно про nested: depth: 10:
Без этой настройки Decap CMS видит только файлы в корне папки docs/ и не видит файлы в подпапках. Число 10 — максимальная глубина вложенности папок.
Важно про buttons:
Decap CMS поддерживает строго определённый список кнопок тулбара. Невалидные значения вызывают ошибку загрузки CMS с сообщением "Config Errors". Валидные значения: bold, italic, strikethrough, code, heading-one ... heading-six, quote, bulleted-list, numbered-list, link. Кнопки image и color — невалидны и вызывают ошибку.
Чтобы получить тулбар по умолчанию со всеми валидными кнопками — убери секцию buttons из конфига полностью. CMS сама покажет полный набор:
- label: Содержимое
name: body
widget: markdown
editor_components:
- image
- code-block
Секция buttons при этом отсутствует — не пустая, а именно убрана. Это также защищает от ошибок при обновлении версии CMS.
6. Почистить шаблонный мусор Docusaurus
rm -rf docs/intro.mdx docs/tutorial-basics docs/tutorial-extras
rm -rf blog src/pages/index.tsx src/pages/index.module.css
rm -rf src/pages/markdown-page.mdx src/components
7. Настроить docusaurus.config.ts
Ключевые настройки:
const config: Config = {
title: 'Название проекта',
onBrokenLinks: 'warn', // 'throw' остановит сборку при битых ссылках
onBrokenMarkdownLinks: 'warn',
presets: [
['classic', {
docs: {
routeBasePath: '/', // docs открываются на корне сайта (/)
sidebarPath: './sidebars.ts',
},
blog: false, // блог отключён
}],
],
};
routeBasePath: '/' означает что документы доступны прямо на корне сайта — localhost:3000/имя-файла вместо localhost:3000/docs/имя-файла.
8. Настроить sidebars.ts
const sidebars: SidebarsConfig = {
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
};
Автогенерация — сайдбар строится из структуры папок автоматически. Порядок и названия групп управляются через _category_.json файлы.
9. Первый коммит
git add -A
git commit -m "init: Docusaurus + Decap CMS scaffold"
Запуск
Всегда нужно два процесса одновременно — в двух терминалах:
Терминал 1 — Decap proxy сервер:
cd /home/alex/sites/cms-docs
PORT=8083 npx decap-server
Порт можно выбрать любой свободный — главное чтобы он совпадал с proxy_url в static/admin/config.yml. Проверить занятость портов: ss -tlnp | grep -E '808[1-9]'.
Терминал 2 — Docusaurus dev сервер:
cd /home/alex/sites/cms-docs
npm start
После запуска:
- Сайт (для тебя, с черновиками):
http://localhost:3000 - Админка CMS:
http://localhost:3000/admin/index.html
⚠ Открывай именно /admin/index.html, а не /admin/ — при открытии /admin/ Docusaurus может отдать закешированную HTML-страницу вместо CMS.
Автозапуск через pm2 (опционально)
Если хочешь чтобы документация и CMS поднимались автоматически при старте системы (WSL, Linux) — используй pm2.
Установка pm2
npm install -g pm2
Конфиг ecosystem.config.js
Создай файл в корне проекта:
module.exports = {
apps: [
{
name: 'cms-docs-dev',
script: 'npm',
args: 'start',
cwd: '/home/alex/sites/cms-docs',
watch: false,
autorestart: true,
env: {
NODE_ENV: 'development',
},
},
{
name: 'cms-decap-server',
script: 'npx',
args: 'decap-server',
cwd: '/home/alex/sites/cms-docs',
watch: false,
autorestart: true,
env: {
PORT: '8083',
},
},
],
};
Что здесь:
name— имя процесса в pm2, можно любоеscript+args— команда запуска (аналогnpm startиPORT=8083 npx decap-server)cwd— рабочая папка, укажи свой путьautorestart: true— pm2 перезапустит процесс если он упадётwatch: false— не следить за изменениями файлов (это делает Docusaurus сам)env.PORT— порт для decap-server, должен совпадать сproxy_urlвconfig.yml
Запуск
cd /home/alex/sites/cms-docs
pm2 start ecosystem.config.js
Проверить что запустилось:
pm2 status
Вывод должен показать оба процесса в статусе online:
┌────┬──────────────────────┬─────────┬──────────┬──────────┐
│ id │ name │ status │ cpu │ mem │
├────┼──────────────────────┼─────────┼──────────┼──────────┤
│ 0 │ cms-docs-dev │ online │ 0% │ 72mb │
│ 1 │ cms-decap-server │ online │ 0% │ 92mb │
└────┴──────────────────────┴─────────┴──────────┴──────────┘
Посмотреть логи:
pm2 logs # все процессы вместе
pm2 logs cms-docs-dev # только Docusaurus
pm2 logs cms-decap-server # только decap-server
Автозапуск при старте системы
Шаг 1. Сохранить текущий список процессов:
pm2 save
Шаг 2. Сгенерировать команду автозапуска:
pm2 startup
pm2 выведет команду которую нужно выполнить с sudo — скопируй и выполни её. Выглядит примерно так:
sudo env PATH=$PATH:/home/alex/.nvm/versions/node/v24.14.1/bin \
/home/alex/.nvm/versions/node/v24.14.1/lib/node_modules/pm2/bin/pm2 \
startup systemd -u alex --hp /home/alex
Путь к node будет твой — pm2 подставляет его автоматически, просто скопируй.
После этого pm2 зарегистрируется в systemd и будет поднимать процессы при каждом старте WSL/Linux.
Проверка: перезапусти WSL и открой http://localhost:3000 — должно работать без ручного запуска.
Управление
pm2 status # статус всех процессов
pm2 restart all # перезапустить всё
pm2 stop all # остановить всё
pm2 start ecosystem.config.js # запустить из конфига
pm2 delete all # удалить все процессы из pm2
Если изменил ecosystem.config.js — перезапусти:
pm2 restart ecosystem.config.js --update-env
Конфликт портов при запуске
Если pm2 стартует, но процессы сразу падают (errored или частые рестарты) — скорее всего порты уже заняты другим процессом.
# Проверить что занимает порт 3000 или 8083:
ss -tlnp | grep -E '3000|8083'
# Убить процесс по PID:
kill <PID>
# Затем перезапустить pm2:
pm2 restart all
Структура папок
cms-docs/
docs/ ← сюда кладёшь MD файлы
vitiana-api-platform/
01_overview/
_category_.json ← название группы в сайдбаре
architecture_overview.md
02_layers/
_category_.json
api_layer.md
index.md ← ОСОБЫЙ ФАЙЛ — см. ниже
static/
admin/
index.html ← Decap CMS UI (форма входа с паролем)
config.yml ← настройки CMS
diagrams/ ← SVG и картинки (не в docs/!)
img/
tools/
import_bundle.sh ← импорт входящих бандлов
serve_preview.sh ← продакшн сервер для показа людям
.ops/
import-log/ ← логи импортов
locks/
state/
docusaurus.config.ts
sidebars.ts
package.json
Документы: правила и ограничения
Frontmatter (обязателен для каждого файла)
Каждый MD файл должен начинаться с блока frontmatter:
---
title: "Название документа"
---
# Название документа
...
Без frontmatter:
- CMS не видит файл нормально
- Название в сайдбаре берётся из имени файла (некрасиво)
- Тогл черновика не работает
Особый случай — корневая страница
Один файл должен иметь slug: / — это главная страница сайта. Без него при открытии localhost:3000 будет страница "404 Not Found".
---
title: "Главная"
slug: /
---
Особый случай — файл index.md в папке
Файл с именем index.md внутри папки имеет особое поведение — Docusaurus делает его страницей-оглавлением для этой папки. Он отображается при клике на название группы в сайдбаре.
Если ты переименовал какой-то файл в index.md случайно — он перестанет отображаться как обычный документ и станет страницей категории.
Картинки и SVG
Нельзя класть картинки и SVG в папку docs/ — Docusaurus их не сервирует оттуда, файл будет отдавать 404.
Правильно — класть в static/:
static/diagrams/schema.jpg
static/img/screenshot.jpg
Вставка в MD:
<img src="/diagrams/schema.jpg" alt="Схема" width="100%" />
Путь начинается с / — это абсолютный путь от корня сайта, не относительный от файла.
Обрати внимание — тег <img> в MDX должен быть самозакрывающимся (/>), иначе ошибка компиляции.
Что нельзя писать в MD файлах (MDX ограничения)
Docusaurus компилирует все MD файлы через MDX парсер который обрабатывает их как JSX. Это означает ряд ограничений на символы вне code-блоков.
< перед цифрой или спецсимволом вызывает ошибку компиляции:
❌ API response time: <200ms
✅ API response time: <200ms
❌ Cost: <€500
✅ Cost: <€500
<img> без самозакрытия вызывает ошибку:
❌ <img src="/img/photo.jpg">
✅ <img src="/img/photo.jpg" />
Незакрытые HTML теги вызывают ошибку:
❌ <div align="center">
<img src="/img/photo.jpg">
</div>
✅ <div align="center">
<img src="/img/photo.jpg" />
</div>
Правило: всё что выглядит как HTML тег вне code-блока — должно быть валидным JSX. Атрибуты в кавычках, теги закрыты, одиночные теги самозакрыты.
Code-блоки (между ```) — безопасны, внутри них любые символы.
Группировка документов по папкам
Просто создай папки в docs/ — Docusaurus автоматически строит из них сайдбар.
Чтобы задать красивое название группы вместо имени папки — создай файл _category_.json внутри папки:
{
"label": "Архитектура",
"position": 1
}
position — порядок в сайдбаре (1 = первый сверху).
Без _category_.json название группы = имя папки (например 01_overview).
Черновики
Черновик — документ который хранится в git, виден в dev режиме (localhost:3000), но не попадает в продакшн сборку (npm run build).
В dev режиме черновики показываются с пометкой "Draft page" вверху страницы — это нормально, только ты это видишь.
Через CMS (рекомендуется)
В админке localhost:3000/admin/index.html открой документ — вверху есть тогл "Черновик (снять с публикации)". Включи → нажми Publish → документ скрыт из продакшна.
Вручную
Добавь в frontmatter файла:
---
title: "Название"
draft: true
---
Редактирование через CMS
- Открой
http://localhost:3000/admin/index.html - Слева — список всех документов из
docs/(включая подпапки) - Кликни на документ → откроется редактор
- Редактируй текст через тулбар или переключись на вкладку Markdown для сырого текста
- Нажми Publish — изменения сохраняются в файл и автоматически делается git commit
- Сайт на
localhost:3000обновляется автоматически
Создать новый документ
Нажми New Документация в верхнем правом углу → заполни заголовок → пиши содержимое → Publish.
Файл создаётся в папке docs/ и сразу появляется в git.
Синхронный скролл в редакторе
Decap CMS v3 не поддерживает синхронный скролл между редактором и превью. Это архитектурное ограничение версии — превью обновляется но скроллится независимо. Решение — смотреть результат на localhost:3000 в соседней вкладке.
Показ документов другим людям
Для показа людям используется продакшн сборка — черновики в неё не попадают.
Скрипт tools/serve_preview.sh
Принимает один аргумент — номер порта (по умолчанию 3001). Делает два шага:
npm run build— собирает статический сайт в папкуbuild/, файлы сdraft: trueисключаютсяnpm run serve— запускает веб-сервер на указанном порту и отдаёт содержимоеbuild/
cd /home/alex/sites/cms-docs
tools/serve_preview.sh 5000
Или вручную (то же самое):
npm run build
npm run serve -- --port 5000 --no-open
- Твой dev:
http://localhost:3000(с черновиками) - Для людей:
http://localhost:5000(без черновиков)
Если нужно дать доступ по сети — людям нужно открывать http://<твой-IP>:5000.
Деплой на shared хостинг
npm run build
Папка build/ содержит чистый HTML — залей её содержимое в public_html/ через FTP или File Manager хостинга. Node.js на сервере не нужен.
Защита паролем на shared хостинге
Шаг 1. Создай файл .htpasswd с логином и хэшем пароля.
Через утилиту htpasswd (если установлен Apache utils):
htpasswd -c .htpasswd admin
# Спросит пароль — введи и подтверди
Или сгенерируй хэш без утилит — Python:
python3 -c "import crypt; print('admin:' + crypt.crypt('твой_пароль', crypt.mksalt(crypt.METHOD_SHA512)))"
Результат — одна строка вида:
admin:$6$соль$длинный_хэш_пароля
Скопируй её в файл .htpasswd.
Шаг 2. Загрузи .htpasswd на сервер за пределы public_html/ — в домашнюю папку аккаунта:
/home/username/.htpasswd
Если положить внутрь public_html/ — файл будет доступен по URL, это небезопасно.
Шаг 3. Создай файл .htaccess в public_html/:
AuthType Basic
AuthName "Документация"
AuthUserFile /home/username/.htpasswd
Require valid-user
Замени /home/username/ на реальный путь к домашней папке — он виден в панели хостинга (cPanel → Terminal или File Manager → адресная строка).
Проверка: открой сайт в браузере — должно появиться окно логина. Введи логин admin и пароль который задал.
Отдать комплект документов бандлом
Создать git bundle
cd /home/alex/sites/cms-docs
git bundle create docs-bundle-2026-04-20.bundle main
Получится один файл с полной историей git ветки main.
Получателю развернуть бандл
# Клонировать из бандла
git clone docs-bundle-2026-04-20.bundle cms-docs
cd cms-docs
# Переименовать ветку если нужно
git branch -m master main
# Установить зависимости
npm install
# Запустить
PORT=8083 npx decap-server &
npm start
Важно: получатель должен использовать тот же порт в proxy_url в config.yml. Если у него выбранный порт занят — он проверяет свободные порты (ss -tlnp | grep -E '808[1-9]'), меняет порт запуска decap-server и меняет proxy_url в static/admin/config.yml.
Принять входящий бандл (импорт чужих документов)
# Нормализовать в import/* ветку
tools/import_bundle.sh ./incoming/docs-bundle.bundle
# Посмотреть что изменилось
git diff main..import/bundle-2026-04-20-v01 --stat
# Смержить в main
git checkout main
git merge import/bundle-2026-04-20-v01
# Пересобрать для показа людям
tools/serve_preview.sh 5000
Связь с Git
| Действие | Что происходит в Git |
|---|---|
| Нажать Publish в CMS | Автоматический коммит в main |
Положить файл в docs/ руками | Нужно сделать git add + git commit вручную |
| Включить черновик в CMS | Коммит с draft: true в frontmatter |
tools/import_bundle.sh | Создаётся ветка import/bundle-YYYY-MM-DD-vNN |
git merge import/... | Объединение импорта с main |
Весь контент хранится в main. Импортированные бандлы — временные ветки import/* до merge.
Частые проблемы
Сайт не запускается — ошибка MDX компиляции
Ищи в тексте MD файла: < перед цифрой или символом не в code-блоке. Замени на <. Также проверь незакрытые HTML теги и <img> без />.
CMS не видит документы в подпапках
Проверь что в config.yml у коллекции есть nested: depth: 10. Без этого видит только файлы в корне docs/.
CMS показывает форму логина и не пускает
Проверь что в static/admin/index.html есть CREDENTIALS_HASH и он совпадает с SHA-256 хэшем пары логин:пароль из cms-config.json.
CMS не загружается — "Config Errors: must be equal to one of the allowed values"
В buttons в config.yml есть невалидное значение. Удали image и color из списка кнопок — они не поддерживаются.
Decap-server не запускается — порт занят
# Проверить какие порты заняты:
ss -tlnp | grep -E '808[1-9]'
# Запустить на свободном порту (например 8083):
PORT=8083 npx decap-server
Обнови proxy_url в static/admin/config.yml на тот же порт что выбрал.
CMS открывается с ошибкой "Error loading the CMS configuration" (YAMLSyntaxError: <!DOCTYPE html>)
Это значит браузер получил HTML вместо config.yml. Причина — Docusaurus закешировал страницу для URL /admin/.
Решение: открывай CMS по прямому URL:
http://localhost:3000/admin/index.html
а не /admin/ — при переходе через /admin/ Docusaurus может перехватить запрос и отдать SPA-страницу вместо файла.
npm install падает с ошибкой rename / EPERM
Проект лежит на NTFS (Windows диск /mnt/d/...). Перенеси на Linux FS (/home/...).
SVG не показывается на странице — пустое место или broken image
SVG лежит в docs/ а не в static/. Перенеси в static/diagrams/ и исправь путь в MD на /diagrams/имя.jpg.
При открытии localhost:3000 — страница "404 Not Found"
Ни один документ не имеет slug: / в frontmatter. Добавь slug: / к тому файлу который должен быть главной страницей.
Ветка называется master вместо main
git branch -m master main
После этого перезапусти decap-server — CMS начнёт видеть файлы.
Проблемы после обновления Decap CMS
Decap CMS загружается с CDN (unpkg.com) с версией ^3.0.0 — это значит браузер может подтянуть новый minor-релиз автоматически. При обновлении возможны два типа проблем.
1. Ошибка "Config Errors" на кнопках тулбара
Симптом: CMS не загружается, в консоли must be equal to one of the allowed values.
Причина: новая версия изменила список допустимых значений buttons в config.yml.
Что делать:
- Открыть консоль браузера (F12) — там будет указано какое именно значение невалидно
- Удалить это значение из списка
buttonsвstatic/admin/config.yml - Текущий валидный список:
bold,italic,strikethrough,code,heading-one…heading-six,quote,bulleted-list,numbered-list,link
2. Изменился формат сохранения frontmatter
Симптом: после сохранения документа через CMS в файле появились лишние поля или изменился порядок/формат frontmatter.
Причина: новая версия изменила способ сериализации YAML.
Что делать:
- Проверить через
git diffчто именно изменилось после сохранения - Если изменения некритичные (порядок полей) — принять как есть
- Если добавились лишние поля — удалить их вручную или добавить в
config.ymlявное описание полей чтобы CMS не генерировала лишнее
Рекомендуемый подход к версии
Использовать плавающую версию ^3.0.0 в static/admin/index.html:
s.src = 'https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js';
Не фиксировать точную версию (например @3.12.2) — некоторые минорные релизы содержат регрессии (сломанный тулбар редактора и др.). Плавающая ^3.0.0 берёт последнюю стабильную в рамках мажорной версии.
Текущую версию можно проверить: https://www.npmjs.com/package/decap-cms