Перейти к содержимому

Диагностика проблем

Ваш стек перестал работать, деплой завис или dwe status светит красным там, где раньше был зелёный. Это руководство — карта для быстрой диагностики: куда смотреть первым делом, какая команда отвечает на какой вопрос и какие обходные пути есть, когда обычный способ не срабатывает.

Три команды покрывают девяносто процентов случаев, и ни одна из них не меняет состояние:

Окно терминала
dwe validate
dwe status
dwe logs <сервис>
  • dwe validate агрегирует все статические проверки — env-пробы, схему конфига, переводы и заданные проектом preflight-проверки. Запускайте её первой; если она красная — сначала разберитесь с этим, а уже потом ищите остальное.
  • dwe status показывает здоровье контейнеров, состояние деплоя, состояние git-рабочей копии и отложенные переключения сервисов, ожидающие деплоя. См. daily-workflow.md — о флагах секций и шорткатах.
  • dwe logs <сервис> выводит docker-логи одного контейнера в реальном времени. См. daily-workflow.md.

Если dwe validate зелёный, а dwe status показывает конкретный сбой — переходите к соответствующей секции ниже.

Host-порт, который DWE хочет опубликовать, занят другим процессом — другим проектом DWE, локальным dev-сервером, чем угодно, что привязано к этому порту.

Сначала диагностика:

Окно терминала
dwe validate env

Проба env.ports_free перечисляет каждый конфликт с указанием номера занятого порта. Чтобы переназначить порт, переопределите его в workspace/local.yml (машинно-локальный файл, в gitignore). Оверлей сливается с основным конфигом поэлементно, поэтому указывать нужно только те порты, которые вы меняете:

workspace/local.yml
services:
main:
ports:
http: 18080 # было 8080

Затем пере-деплой (или dwe deploy run --service main), чтобы изменение прошло через compose и обновило dwe info. Справочник: ../reference/config/services/fields.md.

И снова первым делом — dwe validate env. Здесь важны две пробы:

  • env.docker_bin — бинарь docker не в PATH или нечитаем.
  • env.docker_daemon — бинарь есть, но docker info не может достучаться до демона (Docker Desktop не запущен, проблемы с правами на сокет, недоступен remote-контекст).

Запустите Docker Desktop (или systemctl start docker, в зависимости от платформы), затем снова выполните dwe validate env. Если демон слушает нестандартный сокет, задайте DOCKER_HOST в шелле или через workspace/local.yml. Справочник: ../reference/config/validate.md.

Деплой завершился, но сервис нездоров или постоянно перезапускается. Сузить круг помогают три команды:

Окно терминала
dwe logs <сервис> # что контейнер реально говорит
dwe compose argv up <сервис> # точный набор compose-аргументов, который вызовет DWE
dwe compose files # список активных compose-файлов (с оверлеями)

Логи отвечают на «почему процесс упал?». Две compose-диагностики отвечают на «правильную ли compose-конфигурацию собрал DWE?» — удобно, когда локальный оверлей или неожиданный extends:-предок молча меняют то, что видит Docker. Справочник: ../reference/config/docker.md.

Три подвопроса — три команды:

Окно терминала
dwe deploy plan # итоговый список шагов для текущего состояния
dwe deploy state show # журнал: что прошло, что упало и когда
dwe deploy state clear # сбросить журнал и форсировать полный прогон

dwe deploy plan показывает деплой, который DWE сейчас реально запустит, включая шаги, которые будут пропущены из-за совпадения config_hash или неизменившихся входных данных. Если ожидаемый шаг пропускается — журнал объясняет, почему.

dwe deploy state show выводит зафиксированный результат последней попытки — статус по шагам, фрагменты ошибок и записанный config_hash. dwe deploy state clear удаляет .dwe/deploy/state.yml, чтобы при следующем dwe deploy все шаги прогнались заново. Это нужно, когда вы подозреваете, что ошибается сам журнал, а не проект. Справочник: ../reference/config/state/management.md, ../reference/config/state/hashing.md.

«Подтянул ветку коллеги — деплой говорит изменений нет, но сервис сломан»

Заголовок раздела ««Подтянул ветку коллеги — деплой говорит изменений нет, но сервис сломан»»

Симптом: вы переключились на ветку, которая меняет шаги деплоя, прогнали dwe deploy, и DWE пропустил почти всё, сославшись на отсутствие изменений. Либо деплой прошёл, но работающий контейнер всё ещё ведёт себя как до переключения.

Причина почти всегда — устаревший журнал деплоя: .dwe/deploy/state.yml хранит config_hash, который совпал с предыдущей веткой, и механизм пропуска шагов ему доверяет. Решение — сбросить журнал и пере-деплоить:

Окно терминала
dwe deploy state clear
dwe deploy

Если дело в одном сервисе — сузьте прогон:

Окно терминала
dwe deploy run --service <имя>

Это же помогает в случае, когда вы прыгали между ветками, которые включают разные опциональные сервисы — журнал не в курсе, что ваш local.yml тем временем изменился.

Когда стек залип настолько, что пошаговый разбор обходится дороже, чем начать заново:

Окно терминала
dwe reset run

dwe reset run останавливает все контейнеры, удаляет их и прогоняет reset-пайплайн проекта (workspace/reset.yml). Что переживёт сброс — определяется проектом: обычно именованные тома Docker с базами и кэшами остаются, а журнал и runtime-состояние — нет. Прежде чем делать выводы о том, что сохранится, прочтите reset.yml проекта (и dwe reset plan для итогового списка шагов).

Если нужно стереть и stateful-данные — включите это явно. Reset-пайплайн проекта может предоставлять шаг docker_remove_project_volumes — проверьте dwe reset plan — либо удалите именованные тома Docker руками после чистой остановки.

Перед любым деструктивным reset делайте снапшот. Даже одной строкой dwe snapshot create pre-reset вы получаете откат на случай, если reset окажется агрессивнее ожидаемого. См. switching-tasks-with-snapshots.md — о работе со снапшотами.

Справочник: ../reference/config/reset.md.

Когда обёртка DWE мешает — нужен флаг, который DWE не пробрасывает, или хочется проверить, проблема в DWE или в самом compose:

Окно терминала
dwe compose raw -- ps -a
dwe compose raw -- exec main env
dwe compose raw -- config

dwe compose raw — это низкоуровневый прямой вызов docker compose: DWE определяет список compose-файлов и имя проекта, а остальные аргументы передаёт в docker compose без изменений. Никаких policy-аргументов, никаких оверлеев сверх тех, что уже на диске. Используйте как диагностику, не как повседневный инструмент — высокоуровневые команды dwe существуют не зря — но это правильный инструмент, когда вы дебажите сам DWE или воспроизводите проблему напрямую через compose CLI. Справочник: ../reference/config/docker.md.

Когда обычного вывода не хватает, чтобы понять, почему DWE сделал то или иное — какая docker-команда реально выполнилась, почему шаг был пропущен, что решил движок, — включите диагностический канал. Им управляют два ортогональных флага, и оба пишут только в stderr, поэтому stdout (включая --output json) остаётся чистым машиночитаемым контрактом.

Окно терминала
dwe run -v # подробно: эхо команд + ключевые решения
dwe run --verbose # то же самое
dwe run --debug # firehose: всё, что показывает -v, плюс внутренности
DWE_DEBUG=1 dwe run # env-эквивалент --debug

-v, --verbose выводит эхом команды, которые выполняет DWE (lifecycle docker/compose, прямые docker stop/restart/rm, sh -c …, вложенные dwe …, git) — каждую отдельной копируемой строкой $ …, — плюс ключевые решения пайплайна: какой шаг выполнился или был пропущен и почему (результаты when:, фазовые гейты, state: already deployed, files-gate), а также сводку preflight (прошёл/не прошёл).

--debug (или DWE_DEBUG=1) — это надмножество -v. Поверх подробного потока он добавляет firehose: read-only docker-пробы (docker compose ps), тайминги и коды выхода подпроцессов, полные переопределения окружения compose и рабочую директорию, внутренности разрешения конфига и всё, что эмитится через log/slog на уровне Debug. --debug устанавливает slog-обработчик уровня Debug; -v — нет. Если флаг и переменная окружения противоречат друг другу, побеждает флаг; DWE_DEBUG=0 (а также false/no/off/пусто) трактуется как выключено.

Оба флага рассчитаны на чистую совместную работу со всем остальным:

  • Read-only пробы не попадают в verbose. dwe status -v не засыпает выводом docker compose ps — эти пробы только на уровне Debug. Если нужно их увидеть, используйте dwe status --debug.
  • JSON остаётся чистым. dwe status -v --output json | jq . парсится: на stdout только JSON-документ, каждая диагностическая строка — в stderr. То же верно для --debug. Для недиагностических команд, если команда падает с ошибкой, конверт {"error":{…}} по-прежнему остаётся финальной структурой в stderr. Диагностические команды вроде dwe validate — исключение: они всегда выводят диагностику как данные в stdout, даже при severity=error.
  • Нулевые накладные расходы, когда выключено. Без флагов нет диагностического вывода, slog-обработчик не устанавливается, а поведение существующих Warn/Error не меняется.

Куда смотреть: перенаправьте stderr в файл, чтобы отделить диагностику от обычного вывода —

Окно терминала
dwe run --debug 2>debug.log # диагностика в debug.log, stdout не тронут
dwe deploy -v 2>&1 | less # оба потока вперемешку в пейджере
  • daily-workflow.md — повседневные команды, к которым отсылают секции выше.
  • switching-tasks-with-snapshots.md — чек-пойнт перед рискованным сбросом и восстановление после.