Files
dev-conventions/arch/app-directories.md
T
av 4a59c71737 заведён канон общих конвенций для личных проектов
- 13 конвенций по осям arch / lang / stack / common; репозитории берут
  оттуда копии в свой docs/conventions/ и коммитят их у себя
- conv — синхронизация копий: add / status / diff / pull / push, локальные
  регионы исключены из сравнения, поэтому расхождение не даёт шума
2026-07-25 18:18:18 +03:00

98 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: рекомендуемая
---
# Категории директорий приложения
Всё, что приложение пишет на диск, делится на три категории по принципу
создания и ценности содержимого:
- **конфигурация** — то, что восстанавливается прогоном деплоя, в том числе
секреты;
- **данные** — то, что генерирует приложение и что нужно бэкапить;
- **кеш** — то, что генерирует приложение и что не нужно бэкапить:
приложение перегенерирует заново.
Цель — упростить оперирование данными. Категория сразу отвечает на два
вопроса, которые иначе приходится выяснять по коду приложения: **кто
создаёт** содержимое и **что будет, если его потерять**.
## Категории
| Категория | Директория | Создаёт | Потеря содержимого | Бэкап |
| --- | --- | --- | --- | --- |
| Конфигурация | `config/` | деплой | восстанавливается прогоном | не нужен |
| Данные | `data/` | приложение | невосполнима | обязателен |
| Кеш | `cache/` | приложение | приложение перегенерирует | не нужен |
Имена в таблице — умолчание для случая «одна директория на категорию».
**Категория может состоять из нескольких директорий**, и это нормально:
крупные файлы отделяют от базы, чтобы двигать их между дисками независимо
(`media/`, `uploads/` — та же категория «данные», что и `data/`).
Принадлежность к категории задаётся не именем, а участием в списке бэкапа.
Тест на границе данных и кеша: что будет, если сделать `rm -rf` и поднять
приложение заново. Поднимется само и наверстает — кеш. Не поднимется или
поднимется пустым — данные.
Конфигурацию бэкапить не только не нужно, но и не стоит: там лежат секреты,
а бэкапы уезжают в облако. Источник истины для конфигурации — репозиторий и
хранилище секретов, а не снапшот бэкапа.
## Данные, которые нельзя копировать на живую
Файловый снапшот работающей СУБД не гарантирует консистентности:
скопированный каталог может не восстановиться. Поэтому у категории «данные»
есть два способа попасть в бэкап:
- **копированием** — если файлы самодостаточны на любой момент времени;
- **дампом** — если консистентность обеспечивает только сама СУБД. Тогда
бэкапится директория дампов, а сырой каталог базы — нет.
Директория дампов — тоже данные, просто производные. Решение «копировать
или дампить» принимается **при заведении приложения**, а не при первой
неудачной попытке восстановления.
## Контракт с приложением
Категории — не только про деплой. Приложение **разводит свои записываемые
пути по категориям в конфигурации**, а не складывает всё в один каталог:
иначе категорию нельзя определить снаружи и список бэкапа приходится
составлять вручную, читая код.
- Путь к БД, загруженным файлам, сгенерированным артефактам — данные.
- Миниатюры, распакованные ассеты, кеш внешних ответов, индексы, которые
перестраиваются, — кеш. Даже если их дорого перестраивать: дорого ≠
невосполнимо.
- Приложение не пишет в директорию конфигурации: она может быть доступна
только на чтение.
Если приложение не умеет разделять, это его дефект, а не повод смешивать
категории в раскладке.
## Список бэкапа выводится, а не составляется
Список бэкапа получается из категорий по правилу: туда идут данные, не идут
конфигурация и кеш. Правило механическое — но его применяет человек или
шаблон, поэтому список обязан ссылаться на **те же** переменные путей, что
и создание директорий. Независимо набранный список — источник расхождения
между тем, что бэкапится, и тем, что нужно.
## Область действия
Раскладка меняется вместе с миграцией данных, поэтому конвенция применяется
к **новым приложениям**; существующие переезжают по мере касания, отдельной
кампанией не переписываются. Разделять данные и кеш задним числом имеет
смысл тогда, когда кеш заметен по объёму в бэкапе, а не ради самой схемы.
<!-- local:отступления -->
<!-- /local -->
## Связано
<!-- local:эталон -->
<!-- /local -->
<!-- local:связано -->
<!-- /local -->