# П23 · январь 2020 · локальная разработка в Docker — тройное ревью
Статус: **принят в publication registry 31 июля 2026 года**. В нём ровно три
revision для стабильных slug; registry сохраняет метаданные базового архива:
- editorial-2020-01-practice-docker-local;
- editorial-2020-01-mechanism-docker-local;
- editorial-2020-01-field-docker-local.
Модуль не содержит полей date и author;
articles.json, стандарт, очередь и package config не
перезаписывались.
## Проход 1. Факты и версионные границы — пройдено
| Утверждение | Первичный или официальный источник | Редакторская граница |
| --- | --- | --- |
| Январь 2020 зафиксирован веткой Docker Engine 19.03 | [Docker Engine 19.03 release notes](https://docs.docker.com/engine/release-notes/19.03/) | Тексты называют Engine 19.03 контекстом примеров, но не обещают идентичное поведение на всех Docker Desktop, ОС или удалённых daemon |
| Исторический пример использует docker-compose и верхнее version: '3.7' | [Docker Compose FAQ](https://docs.docker.com/compose/support-and-feedback/faq/), [legacy Compose file versions](https://docs.docker.com/reference/compose-file/legacy-versions/) | Не подставлены Compose v2, Dev Containers, Kubernetes или BuildKit как личная практика автора 2020 года |
| Bind mount связывает путь машины Docker daemon с путём контейнера и может скрыть прежнее содержимое целевого пути | [Docker bind mounts](https://docs.docker.com/engine/storage/bind-mounts/) | Статьи не называют mount копированием файлов в образ; путь working_dir проверяется отдельно от рабочей копии |
| Named volume хранится под управлением Docker и переживает пересоздание контейнера | [Docker volumes](https://docs.docker.com/engine/storage/volumes/) | Полевая статья отделяет чистую базу от пересборки образа и запрещает глобальную очистку вместо расследования |
| Сервисное имя работает во внутренней bridge-сети, а опубликованный порт нужен для доступа с хоста | [Docker bridge network driver](https://docs.docker.com/engine/network/drivers/bridge/) | localhost всегда привязан к наблюдателю: браузеру хоста или процессу внутри контейнера |
| Подстановка Compose YAML и переменная процесса контейнера — разные стадии | [Docker Compose environment variables](https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/) | docker-compose config не выдан за доказательство того, что Node уже прочитал переменную |
| Порядок запуска зависимости не доказывает её готовность принимать соединение | [Docker Compose startup order](https://docs.docker.com/compose/how-tos/startup-order/) | depends_on описан как порядок; статьи требуют отдельный лог или контрольный запрос, а не обещают работающий healthcheck |
Проверены три Compose-фрагмента: у web/api рабочая
директория совпадает с целевым bind mount, адрес PostgreSQL — db,
а postgres_data назван отдельным volume. Фрагменты не являются
снятым конфигом реального репозитория: Docker daemon не запускался, Compose не
поднимал контейнеры, PostgreSQL не принимал соединение. Поэтому все команды в
статьях сформулированы как маршрут проверки, а не как уже наблюдённый
production-результат.
Вердикт: **пройдено**. Факт API и файл-конфигурация отделены от поведения,
которое зависит от конкретного daemon, Dockerfile, ОС, сети и состояния базы.
## Проход 2. Редактура и голос М3 / январь 2020 — пройдено
| Ревизия | Проблема и цена в первых двух абзацах | Главный вопрос | Артефакт и честная граница |
| --- | --- | --- | --- |
| Практика | «Работает у автора», но ломается у коллеги; цена — случайные команды, скрытая причина и потерянное время onboarding | Как записать локальный контракт из кода, томов, сети и переменных | Compose-фрагмент, карта слоёв и два разных запроса; нет утверждения о совместимости со всеми ОС |
| Механизм | Запущенный API не видит базу, переменная не попадает в процесс, файл найден только на хосте; цена — ложная вера в одинаковую среду | Где проходят границы хоста, контейнера, сети и process env | Путь одного запроса и таблица наблюдателей; нет заявления, что зависимость уже готова только из-за depends_on |
| Полевой разбор | После миграции старая база остаётся, а глобальная очистка уничтожает данные; цена — потерянное состояние и нерасследованный дефект | Как проверить чистый запуск без удаления всего Docker | Классификация образа, контейнера, bind mount и volume; нет реального удаления данных или Docker run |
- Все три текста проходят жёсткий диапазон основного тела 5 000–15 000
знаков и не набивают объём общими вступлениями. В каждом первом абзаце
названы симптом и цена; далее повторяется практический порядок «симптом →
причина → проверка → действие → ограничение».
- Голос соответствует М3: автор уже уверенно связывает frontend и delivery,
но ещё учится дисциплине среды. Он работает с Dockerfile, Compose, логами,
service name, томами и маршрутом запроса; не изображает опыт
оркестратора, платформенной инженерии или поздних инструментов.
- У каждой статьи есть шесть или больше смысловых разделов, таблица с
caption и thead, figure с осмысленными
alt/figcaption, Compose или кодовый фрагмент,
нумерованный маршрут и минимум две официальные ссылки.
- Сам модуль останавливает импорт, если собственный текст без таблиц, кода и
рисунка выходит за 5 000–15 000 знаков. Отдельный draft gate дополнительно
проверяет stable slug, JSON-only CLI, количество ревизий, доступность
assets, обязательные структурные элементы и отсутствие date /
author.
Вердикт: **пройдено**. После самостоятельной вычитки удалены
ретроспективные названия поздних инструментов из авторского текста; остались
только необходимые исторические границы и проверяемые действия.
## Проход 3. Визуал и выпуск — пройдено в пределах автономного пакета
- docker-local-environment-2020.svg показывает различие
рабочей копии, bind mount, контейнера web, named volume
зависимостей, сети и postgres_data.
- docker-local-request-path-2020.svg ведёт от браузера на
хосте через опубликованный порт и process env API к db:5432 и
persistent state.
- docker-local-clean-start-2020.svg показывает безопасный
порядок: снимок до изменения, классификация слоя, ограниченное действие,
один контрольный маршрут.
- У каждого SVG есть title, desc,
role="img" и aria-labelledby. В них нет
JavaScript, внешних URL, foreignObject или raster data URI.
У каждого использования в статье есть самостоятельный alt-текст и подпись.
- Основной редактор отрисовал каждый SVG через Sharp в PNG шириной 375 px и
просмотрел результат. На трёх схемах не обнаружены обрезание, наложение
текста или горизонтальный выход; вторичные подписи намеренно набраны
короткими строками. Это статическая проверка SVG, а не browser-run.
- После подключения registry strict audit и production build пройдены.
Реальные Docker Compose, browser и production-прогоны не выполнялись и не
заявляются выполненными: сборка статического сайта не доказывает поведение
конкретного Compose-стека.
### Фактически выполненные проверки
| Проверка | Команда | Реальный результат |
| --- | --- | --- |
| Синтаксис модуля | node --check scripts/upgrade-2020-01.mjs из web/ | PASS |
| Import-safe export и draft gate | npm run audit:draft -- scripts/upgrade-2020-01.mjs из web/ | PASS: 9 834 / 8 999 / 8 879 знаков body |
| XML трёх схем | xmllint --noout public/assets/editorial/2020/docker-local-environment-2020.svg public/assets/editorial/2020/docker-local-request-path-2020.svg public/assets/editorial/2020/docker-local-clean-start-2020.svg из web/ | PASS |
| Визуальный mobile preflight | Sharp render трёх SVG в PNG шириной 375 px и ручной просмотр | PASS: нет клиппинга, наложения или горизонтального overflow |
| Strict audit после подключения registry | npm run audit:articles по трём slug | PASS: 9 834 / 8 999 / 8 879 знаков; по одному figure, table и code example |
| Production build | npm run build из web/ | PASS, code 0, 374 статические страницы |
| Scope/self-review | Проверка revision и выпуска | PASS: нет date/author, articles.json не перезаписан |
Выпусковой вердикт: **тройное ревью пройдено, пакет принят к публикации**.
Registry заменяет только редакционные поля по стабильному slug. Публикация не
подменяет проверку реального Docker daemon, browser или production-стека: эти
действия остаются отдельным сценарием конкретного проекта.