- Зачем: - нужен согласованный вариант публикации сайта без зависимости от GitHub Pages. - Что: - описан контур Gitea Actions, host runner, nginx и резерв на GitHub Pages. - в архитектурный документ добавлена ссылка на новую спецификацию. - Проверка: - git diff --cached --check.
16 KiB
ADR: Архитектура сайта de-roadmap
Архитектурный документ. Проектные цели и требования — в PRD. Решения о публикации и custom domain заменены спецификацией «Публикация сайта через Gitea Actions и VPS». Решения о MkDocs, структуре файлов и ссылках остаются актуальными.
1. Ключевые архитектурные требования
Из PRD вытекают четыре жёстких ограничения, определяющих выбор инструментов:
- Сайт опционален. Репозиторий должен полноценно работать без сайта. Удалили конфиг — всё как было.
- Dual-compatible links. Внутренние ссылки между
.mdфайлами должны работать и на GitHub, и на сайте. - Один файл = один источник правды. Не должно быть копий или генерируемых
.md. Редактируем один раз — рендерится везде. - Zero-effort deploy. Push в
main→ сайт обновился. Без ручных шагов, без локальной сборки.
2. Выбор генератора статического сайта
Рассмотренные варианты
| Критерий | MkDocs Material | Docusaurus | Hugo | Astro |
|---|---|---|---|---|
| Язык/экосистема | Python | Node.js (React) | Go | Node.js |
| Порог входа | Минимальный — pip install, один YAML |
Средний — npm, React-компоненты | Средний — Go templates | Высокий — фреймворк |
| Поддержка Markdown «как есть» | Отличная, расширения через плагины | Хорошая, но MDX-ориентирован | Хорошая, но shortcodes вместо стандартного MD | Хорошая |
| Навигация по длинной странице | TOC sidebar из коробки | Есть, но заточен под многостраничность | Зависит от темы | Зависит от темы |
| Поиск | Встроенный (lunr.js), работает offline | Algolia (внешний сервис) или плагин | Нет из коробки | Нет из коробки |
| Тёмная тема | Из коробки, переключатель | Из коробки | Зависит от темы | Зависит от темы |
| GitHub Pages деплой | Одна команда / готовый Action | Готовый Action | Готовый Action | Готовый Action |
| Dual-compatible links | Поддерживает с настройкой use_directory_urls |
Преобразует ссылки, может ломать GitHub | Преобразует ссылки | Преобразует ссылки |
| Один мейнтейнер, Python-стек | ✅ Идеально | ❌ Node.js | ⚠️ Go, но бинарник | ❌ Node.js |
Решение: MkDocs Material
Почему:
- Python-based — совпадает со стеком автора,
pip installи готово. - Лучшая из коробки поддержка длинных страниц с TOC — именно наш сценарий.
- Встроенный поиск без внешних сервисов.
- Самый простой конфиг — один
mkdocs.yml. - Крупнейшее комьюнити среди генераторов документации, активно развивается.
- Dual-compatible links решаемы (см. раздел 4).
Почему не Docusaurus: Node.js-зависимость, ориентирован на многостраничные доки с MDX-компонентами — overkill для «красивый рендер Markdown». Преобразование ссылок может конфликтовать с GitHub-форматом.
Почему не Hugo: Быстрый, но Go-шаблоны сложнее отлаживать. Нет встроенного поиска. Для нашего объёма контента скорость сборки не критична.
Почему не Astro: Полноценный веб-фреймворк — избыточен. Подошёл бы, если бы мы строили маркетинговый сайт с интерактивом, но это не текущая цель.
3. Структура файлов
Решение открытого вопроса: docs/ vs корень репо
Решение: docs_dir: . (корень репо = корень сайта), с исключениями.
Причина: не создаём отдельную папку docs/, не дублируем и не перемещаем файлы. MkDocs умеет работать с корнем репо как источником, исключая ненужное.
# mkdocs.yml (в корне репо)
docs_dir: .
Решение открытого вопроса: README.md как index
Решение: плагин awesome-pages или конфигурация nav с явным указанием.
MkDocs по умолчанию ищет index.md. Но мы хотим сохранить README.md (GitHub его рендерит на главной репо). Есть два пути:
- Вариант A: Симлинк
docs/index.md → ../README.md. Но мы не используемdocs/. - Вариант B (выбран): В
mkdocs.ymlявно указатьREADME.mdкак главную:
nav:
- Роадмап: README.md
- Моделирование данных:
- Введение: dwh-modeling/README.md
- SCD: dwh-modeling/SCD.md
- Data Vault: dwh-modeling/DataVault.md
- "Домашка: STG → DDS → DM": dwh-modeling/Homework_Customer_Status_DDS_DM.md
MkDocs Material корректно обрабатывает README.md файлы — рендерит их как index.html соответствующей директории.
Исключения из сборки
Файлы и папки, которые не должны попасть на сайт:
exclude_docs: |
project/ # проектная документация (PRD, ADR)
postgres-bookings/ # скрипты стенда (не контент сайта)
AGENTS.md # конфигурация для AI-агентов
LICENSE # лицензия (есть в footer)
.gitignore
Итоговая структура репо
de-roadmap/
├── mkdocs.yml ← конфиг сайта (единственный новый файл в корне)
├── README.md ← главная страница сайта И главная страница GitHub
├── dwh-modeling/
│ ├── README.md ← подстраница «Введение в DWH»
│ ├── SCD.md ← подстраница
│ ├── DataVault.md ← подстраница
│ └── Homework_*.md ← подстраница
├── postgres-bookings/ ← исключён из сайта
├── project/ ← PRD, ADR — исключены из сайта
│ ├── PRD.md
│ └── ADR.md
├── .github/
│ └── workflows/
│ └── deploy-site.yml ← CI/CD pipeline
├── AGENTS.md ← исключён из сайта
└── LICENSE
4. Стратегия ссылок (Dual Compatibility)
Проблема
GitHub рендерит ссылки вида [текст](dwh-modeling/SCD.md) как переход к файлу.
MkDocs по умолчанию преобразует .md → .html и может менять структуру URL.
Решение
Комбинация настроек MkDocs:
use_directory_urls: true # /dwh-modeling/SCD/ вместо /dwh-modeling/SCD.html
И ссылки в Markdown пишем всегда как относительные пути к .md файлам:
<!-- Это работает и на GitHub, и в MkDocs -->
[Теория про SCD](dwh-modeling/SCD.md)
[Введение в DWH](dwh-modeling/README.md)
MkDocs Material автоматически резолвит .md ссылки в правильные URL сайта.
Кириллические якоря
GitHub генерирует якоря из кириллических заголовков с URL-encoding:
## Базы данных → #базы-данных
MkDocs Material по умолчанию делает то же самое через расширение toc:
markdown_extensions:
- toc:
slugify: !!python/object/apply:pymdownx.slugs.slugify
kwds:
case: lower
permalink: true
Риск: поведение может различаться на edge cases (спецсимволы, эмодзи в заголовках). Митигация — на этапе MVP протестировать все существующие якорные ссылки в README.
5. CI/CD Pipeline
GitHub Actions Workflow
# .github/workflows/deploy-site.yml
name: Deploy MkDocs to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch: # ручной запуск для отладки
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- run: pip install mkdocs-material
- run: mkdocs build --strict
# --strict: падает на warnings (битые ссылки, отсутствующие файлы)
- uses: actions/upload-pages-artifact@v3
with:
path: site/
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
Что даёт --strict
Сборка упадёт, если:
- Есть ссылка на несуществующий
.mdфайл. - Есть битый якорь.
- Есть warning от MkDocs.
Это наш автотест ссылок — бесплатно, в CI.
6. Конфигурация MkDocs Material
Минимальный mkdocs.yml для MVP
site_name: "DE Roadmap — Data Engineering с нуля до middle"
site_url: https://dementev-dev.github.io/de-roadmap/
site_description: "Роадмап по Data Engineering: SQL, Python, Airflow, Greenplum и далее"
site_author: Dmitry Dementev
repo_url: https://github.com/dementev-dev/de-roadmap
repo_name: dementev-dev/de-roadmap
docs_dir: .
site_dir: site
# Исключаем из сборки
exclude_docs: |
project/
postgres-bookings/
AGENTS.md
LICENSE
.gitignore
.github/
site/
nav:
- Роадмап: README.md
- Моделирование данных:
- Введение: dwh-modeling/README.md
- SCD: dwh-modeling/SCD.md
- Data Vault: dwh-modeling/DataVault.md
- "Домашка: STG → DDS → DM": dwh-modeling/Homework_Customer_Status_DDS_DM.md
theme:
name: material
language: ru
palette:
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Тёмная тема
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Светлая тема
features:
- navigation.top # кнопка «наверх»
- navigation.tracking # URL обновляется при скролле
- search.suggest # подсказки в поиске
- search.highlight # подсветка найденного
- toc.follow # TOC следит за скроллом
- content.code.copy # кнопка копирования кода
markdown_extensions:
- toc:
permalink: true
- admonition # сворачиваемые блоки (Спринт 2)
- pymdownx.details # для <details>
- pymdownx.superfences # вложенные блоки кода
- pymdownx.highlight # подсветка синтаксиса
- attr_list # атрибуты для элементов
plugins:
- search:
lang: ru
Что уже включено в MVP (бесплатно с Material)
- Тёмная/светлая тема с переключателем.
- Полнотекстовый поиск на русском.
- TOC (оглавление) в правом sidebar.
- Кнопка «наверх» на длинной странице.
- URL обновляется при скролле (можно дать ссылку на конкретный раздел).
- Подсветка синтаксиса в блоках кода.
- Кнопка копирования кода.
- Ссылка на GitHub-репозиторий в шапке.
7. Кастомный домен (Спринт 2)
Домен dementev.space уже есть. Для подключения:
- Создать CNAME-запись:
roadmap.dementev.space → dementev-dev.github.io. - Добавить файл
CNAMEв корень репо с содержимымroadmap.dementev.space. - В
mkdocs.ymlобновитьsite_url. - Включить HTTPS в настройках GitHub Pages.
8. Риски и митигации
| Риск | Митигация |
|---|---|
docs_dir: . подхватывает лишние файлы |
exclude_docs со списком исключений; --strict ловит проблемы |
| Кириллические якоря ведут себя по-разному | Тестируем все якорные ссылки из README при первом деплое |
README.md содержит GitHub-специфичный синтаксис |
Проверяем рендер; при необходимости используем MkDocs-совместимые альтернативы |
Зависимость от mkdocs-material |
Активный проект (30k+ stars), Python-пакет; при необходимости — заморозить версию в requirements.txt |
exclude_docs — относительно новая фича MkDocs |
Альтернатива: .mkdocsignore или плагин mkdocs-exclude; протестировать на MVP |
9. Порядок действий (Спринт 1)
- Создать ветку
feature/site. - Добавить
mkdocs.ymlв корень репо. - Добавить
.github/workflows/deploy-site.yml. - Добавить
project/PRD.mdиproject/ADR.md. - Проверить локально:
pip install mkdocs-material && mkdocs serve. - Протестировать все внутренние ссылки и якоря.
- При необходимости — адаптировать ссылки для dual compatibility.
- Merge в
main→ автодеплой → проверитьhttps://dementev-dev.github.io/de-roadmap/. - Включить GitHub Pages (Settings → Pages → Source: GitHub Actions).