Отладка Node.js-приложения в Docker-контейнере кажется сложнее обычного запуска, но на практике схема довольно предсказуема. Если правильно пробросить порт инспектора, запустить процесс с нужными флагами и собрать конфигурацию в Visual Studio Code, вы получите привычную пошаговую отладку прямо внутри контейнера.
Такой подход удобен, когда приложение повторяет production-окружение, зависит от конкретных версий библиотек или запускается через Docker Compose. Вместо долгих догадок о том, почему код ведет себя иначе локально, можно подключиться к контейнеру и посмотреть значения переменных, стек вызовов и точки останова в реальном процессе.
Что нужно подготовить
Для начала убедитесь, что у вас установлены Docker, Visual Studio Code и расширение JavaScript Debugger, которое обычно входит в стандартный набор возможностей VS Code. Также пригодится установленный Node.js-проект, собранный так, чтобы его можно было запускать внутри контейнера без лишних ручных шагов.
Главная идея простая: Node.js должен стартовать с включенным инспектором на порту 9229, а этот порт нужно пробросить наружу из контейнера. После этого VS Code подключится не к файлу или папке, а к уже работающему процессу в контейнере.
Важно: если контейнер запускается без флага —inspect или без проброса порта, VS Code не сможет подключиться к отладчику.
Как запустить Node.js в контейнере для отладки
Чаще всего удобнее всего добавить отдельную команду запуска для режима отладки. Например, в package.json можно использовать скрипт, который поднимает Node.js с инспектором и следит за изменениями кода через nodemon, если это нужно в вашем проекте.
В Dockerfile или docker-compose.yml важно не забыть про порт 9229. Сам контейнер может слушать приложение на 3000, а отладочный порт будет отдельным, и именно он нужен VS Code для подключения.
Пример запуска внутри контейнера может выглядеть так:
"node": "node --inspect=0.0.0.0:9229 src/index.js"
Адрес 0.0.0.0 здесь важен, потому что инспектор должен быть доступен не только внутри контейнера, но и снаружи. Если оставить значение по умолчанию, подключение из VS Code часто не сработает.
Пример настройки Docker Compose
Если вы используете Docker Compose, добавьте проброс порта и отдельную команду запуска. Такой вариант удобен тем, что отладочная конфигурация остается рядом с остальными сервисами и ее проще повторять на разных машинах.
services:
app:
build: .
command: node --inspect=0.0.0.0:9229 src/index.js
ports:
- "3000:3000"
- "9229:9229"
Если приложение запускается через npm-скрипт, можно вместо прямого вызова Node.js использовать npm run debug. Важно лишь, чтобы итоговая команда поднимала процесс с инспектором и не закрывала его сразу после старта.
Настройка Visual Studio Code
Теперь нужно создать конфигурацию в .vscode/launch.json. В ней указывается тип отладки Node.js, режим подключения к уже запущенному процессу и адрес хоста, на котором доступен контейнер.
Для локального Docker-сценария обычно достаточно конфигурации типа attach. Она подключается к процессу по сети, а не пытается запускать его самостоятельно, что как раз и нужно в контейнере.
Обычно используется такая структура:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach to Docker",
"port": 9229,
"address": "localhost",
"restart": true,
"localRoot": "${workspaceFolder}",
"remoteRoot": "/usr/src/app"
}
]
}
Параметры localRoot и remoteRoot особенно важны, если пути на вашей машине и в контейнере отличаются. Без них VS Code может открыть отладчик, но не сопоставить исходники с выполняемым кодом.
Как не запутаться в путях
Если код копируется в контейнер, например, в /app или /usr/src/app, этот путь нужно указать в remoteRoot. Локальная папка проекта в VS Code должна соответствовать localRoot, иначе точки останова будут вести себя странно или вовсе станут пустыми.
Еще один полезный прием — запускать контейнер с примонтированным томом, когда вы активно меняете код. Тогда правки на хосте сразу видны внутри контейнера, и не нужно каждый раз пересобирать образ ради маленького изменения.
Пошаговая отладка на практике
Сначала запустите контейнер, затем откройте панель Run and Debug в Visual Studio Code и выберите созданную конфигурацию. После подключения поставьте breakpoint в нужной строке, воспроизведите ошибку или дойдите до нужного участка кода.
Если все настроено верно, VS Code остановит выполнение в нужном месте, и вы сможете посмотреть переменные, стек вызовов и значения выражений. Это особенно удобно при работе с асинхронным кодом, где логов часто недостаточно, чтобы понять последовательность событий.
Когда отладка не подключается, сначала проверьте порт 9229, затем адрес хоста и соответствие путей. Еще одна частая причина — контейнер уже запущен без инспектора, и в этом случае его нужно перезапустить с правильной командой.
Полезные мелочи, которые экономят время
Если контейнер стартует слишком быстро и вы не успеваете подключиться, добавьте небольшой паузу или используйте режим, где процесс ждет отладчик. Это полезно при автоматизированных сценариях, когда приложение сразу переходит в рабочий режим и не оставляет времени на attach.
Для проектов с несколькими сервисами удобнее держать отдельную конфигурацию только для нужного контейнера. Так вы не смешиваете отладку API, очереди и базы данных в одном профиле и быстрее понимаете, куда именно подключаться.
Когда отладка уже работает, имеет смысл сохранить удачную конфигурацию в репозитории. Тогда коллегам не придется заново собирать параметры подключения, а вы сами сможете быстро вернуться к привычной схеме после чистой установки окружения.
Отладка Node.js в Docker через Visual Studio Code хорошо помогает там, где важны повторяемость и контроль над средой. Если один раз аккуратно настроить инспектор, проброс порта и сопоставление путей, дальше процесс становится почти таким же удобным, как локальная отладка без контейнера.
