MkDocs: генератор документации из Markdown
Документация в репозитории устаревает быстрее, чем её читают: ссылки в README ведут в никуда, разделы разбросаны по docs/, wiki/ и confluence, а поиск по сайту не работает. MkDocs решает это предсказуемо — берёт папку с .md файлами и собирает статический сайт. Один конфиг, одна команда для прода, привычный Markdown.
Что такое MkDocs
MkDocs — статический генератор сайта документации на Python. На входе: каталог с Markdown-файлами и YAML-конфиг. На выходе: готовый site/ с HTML, который отдаётся любым веб-сервером или хостится на GitHub Pages, GitLab Pages, S3. Сам MkDocs ядро рендеринга, а внешний вид и фичи задаёт тема. Стандарт де-факто — Material for MkDocs.
MkDocs не использует Jinja-шаблоны и не требует базы данных. Это статика, которая собирается локально или в CI за пару секунд.
Установка
Минимальные требования — Python 3.8+. Ставить лучше в виртуальное окружение, чтобы не засорять системный pip.
Проверка:
Типичный вывод — mkdocs, version 1.6.x. Версия важна, потому что темы и плагины часто требуют конкретный диапазон.
Полезные пакеты, которые ставятся вместе с базой или отдельно:
| Пакет | Зачем |
|---|---|
mkdocs-material | Тема Material, навигация, поиск, tabs |
mkdocstrings | Генерация документации из docstring Python-кода |
pymdown-extensions | Дополнительные расширения Markdown для Material |
mkdocs-minify-plugin | Минификация HTML/CSS/JS в site/ |
В requirements.txt фиксируйте версии тем и плагинов. Material ломает совместимость между минорными релизами, как и mkdocstrings.
Создание проекта
Команда mkdocs new создаёт скелет:
Появится каталог docs/ с index.md и пустой mkdocs.yml. Это и есть рабочий минимум — больше ничего обязательного нет.
Структура каталогов
docs/ — единственный источник Markdown. Иерархия каталогов напрямую превращается в URL. Файл docs/guide/install.md становится /guide/install/. Файл index.md в корне docs/ — главная страница.
Сайт собирается в каталог site/ рядом с mkdocs.yml. Этот каталог — артефакт сборки, его коммитят только при ручном деплое, обычно его собирает CI.
Конфигурация mkdocs.yml
Минимальный рабочий конфиг:
Полный набор ключей, которые реально используются в продакшене:
| Ключ | Назначение |
|---|---|
site_name | Заголовок сайта и <title> по умолчанию |
site_url | Канонический URL, нужен для sitemap.xml и robots.txt |
site_description | Описание, попадает в мета-теги |
docs_dir | Каталог с Markdown, по умолчанию docs |
site_dir | Куда собирать HTML, по умолчанию site |
theme | Тема и её параметры |
nav | Явная навигация, перекрывает авто-сборку |
plugins | Плагины в порядке загрузки |
markdown_extensions | Включённые расширения Markdown |
extra | Произвольные переменные, читаются темой |
Пример с навигацией, расширениями и плагинами:
Включайте search явно, если используете список plugins. В новых версиях Material он не подтягивается автоматически из темы.
Наполнение контентом
Markdown-файлы — обычный CommonMark с расширениями. Полезные конструкции, которые работают «из коробки» при включённых расширениях из примера выше.
Admonitions:
Табы с pymdownx.tabbed:
Подсветка кода с указанием языка:
Используйте якоря в заголовках, чтобы ссылаться между страницами. Material рендерит иконку # рядом с заголовком при toc.permalink: true.
Внутренние ссылки — относительные пути от текущего файла:
Внешние ссылки по умолчанию открываются в той же вкладке. Чтобы открывать в новой:
Сборка и локальный сервер
Локальная разработка — запуск live-сервера:
По умолчанию слушает http://127.0.0.1:8000. Полезные флаги:
| Флаг | Эффект |
|---|---|
--dev-addr 0.0.0.0:9000 | Сменить адрес и порт, удобно в контейнере |
--strict | Сборка падает на любом warning, включая битые ссылки |
--livereload | Перезагрузка страницы в браузере без F5 (по умолчанию включён) |
--no-livereload | Отключить автообновление |
--clean | Удалить site/ перед сборкой |
Сборка артефакта для деплоя:
--strict — обязателен в CI, иначе опечатки в ссылках и отсутствующие файлы в nav будут молча собираться. Код возврата при warning — ноль, поэтому без --strict пайплайн пройдёт зелёным с битой документацией.
Не запускайте mkdocs serve в проде. Это dev-сервер без аутентификации и с включённой перезагрузкой файлов.
Типовые ошибки при первом запуске:
WARNING - A relative path to '...' is included in the 'nav' config. Файл указан вnav, но отсутствует вdocs/. Проверьте регистр и путь.WARNING - Documentation file 'x.md' is not included in the 'nav' configuration. Файл есть, но в навигацию не добавлен. Либо добавьте вnav, либо положитесь на авто-навигацию, убрав секциюnavцеликом.ERROR - Config value 'theme': The theme 'mkdocs' is not installed. Не установлен пакет темы, либо опечатка в имени.
Material for MkDocs: навигация, поиск, tabs
Material расширяет базовый MkDocs тремя вещами, которые нужны почти всегда.
Навигация. Включается через features в секции theme:
Связка navigation.tabs + navigation.sections даёт привычное «приклеенное» меню. Без sections табы уезжают вверх вместе с контентом.
Поиск. Плагин search идёт в составе Material, но регистрируется отдельно:
Для русской документации важно включить стемминг — search.lang: ru в конфиге theme. Список поддерживаемых языков Material публикует в документации, новые добавляются регулярно.
Tabs внутри страницы. Делаются расширением pymdownx.tabbed, которое уже подключено выше. Альтернативный синтаксис через !!! example блоки в некоторых темах не работает — это частая причина «почему табы не отрисовываются».
Подсветка кода и копирование. Кнопка «скопировать» включается фичей content.code.copy. Номера строк — расширением pymdownx.highlight с linenums: true либо глобально через markdown_extensions:
pymdownx.superfences нужен для подсветки внутри admonitions и tabbed-блоков. Без него код рендерится как обычный блок без подсветки.
Тёмная тема — обязательная опция для документации, которую читают ночью по алертам. В примере конфига выше переключатель настроен через palette с двумя схемами: default и slate. Чтобы Material отдавал правильную схему при первом заходе, добавьте в <head> пользовательский скрипт или используйте theme.palette.toggle с media — это работает без JS и учитывает системные настройки пользователя.