# П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-стека: эти действия остаются отдельным сценарием конкретного проекта.