Debug Nodejs внутри контейнера Docker

Я планирую рабочий процесс для обычного разработчика в приложении nodejs. Я предполагаю, что большинство из вас:

git clone [appcode] + (Dockerfile с отображением томов на локальный путь) > docker-compose build > docker-compose up

Затем я редактирую код, желательно используя IDE, например Webstorm или текстовый редактор Sublime и т.д. Затем терминал Ctrl + C, чтобы убить текущий процесs > docker-compose up (или настроить ваш контейнер для использования nodemon для просмотра изменений кода) и обновите браузер, чтобы увидеть, как работает последний локальный код.

Все ли это выглядит довольно стандартно?

Мой главный вопрос: кто-нибудь отлаживает либо IDE, либо node -inspect в контейнере?

Я попытался разоблачить порты и т.д. Соединение отказано. Я верю, потому что node.js разрешит отладку только на 127.0.0.1:5858

Ответ 1

Мне удалось запустить его. Мне хотелось бы запустить node -инспектор в качестве контейнера sidekick, он будет настолько чистым (EDIT: возможно, см. Конец ответа). К сожалению, глядя в источники node -inpector, невозможно запустить node -инспектор удаленно (потому что node -инспектор должен получить доступ к файлам, чтобы он мог их отображать), поэтому даже соединение с контейнером выходит из окна. Возможно, в какой-то момент он будет поддерживать его.

Вот мое решение:

В Dockerfile установите node -инспектор. Я решил сделать его глобальным, поэтому я могу использовать один и тот же контейнер для отладки всех моих приложений.

RUN npm install -g node-inspector

Вместо обеда node в команде CMD используйте bash script, который позволит вам запустить более одного процесса. Это не способ Докера, но, как я уже сказал, ограничение в node -inpector не позволяет нам использовать контейнер sidekick. Вы также можете использовать более надежное решение для управления процессами, например supervisor, но для отладки простого script достаточно, на мой взгляд.

CMD ["/bin/bash", "start.sh"]

Этот script проверяет наличие переменной среды DEBUG для запуска node и включает отладку.

#!/bin/bash

if [ -z ${DEBUG+x} ]; then
  node server.js
else
  node-inspector --web-port 9080 &
  node --debug server.js
fi

Думаю, вы могли бы использовать тот же трюк для установки или не node -инспектор. У вас даже может быть условный оператор в команде RUN, если вы хотите пропустить script для установки.

Затем, когда вы хотите отладить контейнер, запустите его так:

docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
    -v /home/docker/sources/.../:/usr/src/app custom-node

Теперь вам просто нужно нажать на daemon ip-dock для отладки, так как мы выставили порт отладки, указанный в script (9080) в команде docker run. Мой Dockerfile уже предоставляет мой основной порт, поэтому я использовал -P для этого.

Если ваш контейнер работает на локальной виртуальной машине и вы устанавливаете за прокси-сервер, убедитесь, что он поддерживает локальные адреса или отключает его перед отладкой.


EDIT: теперь работает с контейнером sidekick

Вот содержимое моего контейнера node -debug Dockerfile

FROM node:4.2.1

EXPOSE 9080

RUN npm install -g node-inspector

CMD ["node-inspector", "--web-port", "9080"]

Docker предоставляет нам 2 функции, чтобы сделать так, как будто node -инспектор запускался локально с процессом node.

  • Несмотря на то, что node -инспектор подразумевает, что вы можете подключиться к удаленному компьютеру, сообщив вам подключиться к 127.0.0.1:8080/?ws=127.0.0.1&port=5858, я не смог найти код, который анализировал параметр ws, поэтому я использовал docker net config, чтобы поместить контейнер node -debug в тот же сетевой стек, что и мой отлаженный процесс: --net=container:mysvc. Таким образом, node -инспектор может открыть соединение с websocket to localhost:5858.

  • Используя ту же точку монтирования, что и ваш отладочный процесс, вы можете подделать локальность файла в процесс node -indpector.

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

Если вы хотите запустить node в отладке или нет, продолжайте использовать start.sh script (удалите команду инспектора node, хотя). Интересно, можем ли мы использовать сигнал с докером, хотя это полностью устранит зависимость от start.sh.

if [ -z ${DEBUG+x} ]; then
  node server.js
else
  node --debug server.js
fi

Создайте контейнер данных:

docker create -v /home/docker/sources/.../:/usr/src/app  \
    --name my_service-src custom-node /bin/true

Запустите приложение node и откройте node -spectoror debug port:

docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
    --volumes-from my_service-src custom-node

Запустить node -debug container:

docker run -d --net=container:my_service --volumes-from my_service-src \
    --name node-debug node-debug

Таким образом, вы можете быстро создать контейнер node -debug на лету, чтобы отладить процесс node.

Подключитесь к docker ip и наслаждайтесь сеансом отладки!

Ответ 2

Использование двух разных изображений для отладчика (node -debug) и сервера приложений (custom- node) не имеет смысла в этом случае. Так как контейнеру custom- node нужны также двоичные файлы-хранители w633 > . В противном случае ошибка "Не удается найти модуль" /usr/lib/ node_modules/node-inspector/lib/InjectorServer.js помещается в клиентскую консоль клиента node -indpector, и ничто не отлаживается также.

Ответ 3

У меня есть альтернативное решение, которое аналогично Eric выше, но использует хост, а не контейнерную сеть.

  • В главном контейнере node.js отобразите порт 5900 на хост
  • Запустите основной node процесс с включенной отладкой
  • Используйте отдельный контейнер для запуска node -inspector
  • Использовать сеть хоста для контейнера node -inspector

Я написал несколько подробностей об этом здесь: https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector

Ответ 4

После некоторого времени, чтобы заставить это работать, я обнаружил, что добавление:

--inspect-brk=0.0.0.0:9229

вместо обычного inspect-brk

сделал работу.

Вам также необходимо правильно отобразить порты в вашей команде запуска docker:

-p 9229:9229

Полный пример:

docker run -ti -p 3000:3000 -p 9229:9229 -v `pwd`:/app/ myImage bash

node --inspect-brk=0.0.0.0:9229 /app/index.js

Затем перейдите в chrome://проверьте

И нажмите "Открыть выделенный DevTools для Node", и все должно работать:)