Как отлаживать приложение Nodejs, работающее внутри контейнера Docker, через Google Cloud

Я обнаружил, что Google предоставляет некоторые рекомендации по как запускать Nodejs в пользовательской среде выполнения. Кажется, все в порядке, и мне удается запустить приложение Nodejs на локальном компьютере под управлением gcloud preview app run ..
Как я вижу, оно вероятно создает контейнер Docker и запускает там программу Nodejs. Я говорю "вероятно", потому что это мой первый опыт работы с Docker, однако я являюсь разработчиком Nodejs со стажем более 2 лет.

Итак, мой вопрос: как отлаживать (с остановками в точках останова) мою программу Nodejs, когда она работает внутри контейнера Docker? Используя инструменты разработчика Chrome или как настроить конфигурацию отладки Webstorm, чтобы она останавливалась в точках останова. Можно ли настроить Docker на то, как он запускает узел, или даже запустить Docker через gcloud внутри Webstorm, чтобы убедиться, что отладка работает? Любая помощь или разъяснения приветствуются.

Пожалуйста, не давайте ответы о том, как отлаживать приложение Nodejs вне контейнера Docker — я знаю, как это сделать очень хорошо.


person Nik Sumeiko    schedule 14.02.2015    source источник


Ответы (5)


Извините, но я знаю решение только с помощью node-spector, надеюсь, оно вам поможет:

person user1853777    schedule 11.03.2015
comment
Подтверждаю, что мне удалось запустить сеанс отладки в Chrome, используя Docker для Mac, используя 5858:5858 в разделе портов моего файла docker-compose. Использование сетевого режима Docker по умолчанию. Нет необходимости в --net=host, переадресации SSH или любых других трюках. Это Docker таким, каким он должен быть (изолирован). Кроме того, --web-host 0.0.0.0, который не везде упоминается, был недостающей частью моей конфигурации. Без node-debug запускается, но ничего не может подключиться к нему извне (отказ в соединении). С ним просто работает - person amateur barista; 30.11.2016
comment
Между запуском инспектора узлов и загрузкой файлов в исходный код в браузере проходит довольно много времени. Любая идея, почему это так? - person Jeremy; 09.02.2017

Есть более простой способ, по крайней мере, из Docker 0.11 или что-то в этом роде.

Запустите Docker только на своем компьютере для разработки с параметром --net="host". Это заставляет Docker напрямую связываться с локальным хостом, а не создавать сетевой адаптер-мост, поэтому машина Docker работает как любой другой процесс на вашем компьютере и открывает необходимые порты на локальном интерфейсе.

Таким образом, вы можете подключиться к порту отладки, как если бы Node не работал внутри Docker.

Дополнительная документация здесь: https://docs.docker.com/reference/run/

До Docker 0.11 у вас было два других способа отладки, помимо использования node-spector :

person Simone Gianni    schedule 30.06.2015

По умолчанию отладчик узла будет прослушивать только соединения для одного и того же хоста (127.0.0.1). Но в Docker нужно принимать соединения с любого хоста (0.0.0.0):

# inside Docker
node --inspect=0.0.0.0:9229 myapp.js

Также вы должны открыть порт отладки (9229). Затем приложение должно быть автоматически обнаружено и указано как удаленная цель в chrome://inspect/#devices в Chrome (проверено в Chrome 67).

Пример

Вот минимальный пример. Он запускает простое приложение JavaScript в Docker и показывает, как подключить к нему отладчик Chrome:

$ cat example.js
setInterval(() => console.log('Hallo world'), 1000);

$ cat Dockerfile
FROM node
COPY example.js /
CMD node --inspect=0.0.0.0:9229 /example.js

Бежать с:

$ docker build . -t myapp && docker run -p 9229:9229 --rm -it myapp
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM node
 ---> aa3e171e4e95
Step 2/3 : COPY example.js /
 ---> Using cache
 ---> 3ef6c0311da2
Step 3/3 : CMD node --inspect=0.0.0.0:9229 /example.js
 ---> Using cache
 ---> e760739c2802
Successfully built e760739c2802
Successfully tagged debug-docker:latest
Debugger listening on ws://0.0.0.0:9229/4177f6cc-85e4-44c6-9ba3-5d8e28e1b124
For help see https://nodejs.org/en/docs/inspector
Hallo world
Hallo world
Hallo world
...

Откройте Chrome и перейдите к chrome://inspect/#devices. Он должен вскоре после запуска приложения обнаружить его и перечислить.

Поиск проблемы

Для отладки проблем с сетью Docker полезно использовать docker inspect:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ae83d50e24c8        debug-docker        "/bin/sh -c 'node --…"   2 minutes ago       Up 2 minutes        0.0.0.0:9229->9229/tcp   blissful_sammet
$ docker inspect ae83d50e24c8
...
    "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "682d3ac98b63d4077c5d66a516666b6615327cbea0de8b0a7a2d8caf5995b0ae",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {
            "9229/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "9229"
                }
            ]
        },
   ...

Если вы хотите увидеть запросы, отправленные между Docker и Chrome, ngrep может помочь:

$ sudo ngrep -d any port 9229
interface: any
filter: (ip or ip6) and ( port 9229 )
############################
T ::1:38366 -> ::1:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
#####
T ::1:38368 -> ::1:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
##############
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
#
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
###
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
#
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
  l: no-cache..Content-Length: 465....                                        
#
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
  l: no-cache..Content-Length: 465....                                        
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  [ {.  "description": "node.js instance",.  "devtoolsFrontendUrl": "chrome-de
  vtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=[::
  1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",.  "faviconUrl": "https://node
  js.org/static/favicon.ico",.  "id": "f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",.
    "title": "/example.js",.  "type": "node",.  "url": "file:///example.js",. 
   "webSocketDebuggerUrl": "ws://[::1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a
  8e".} ]..                                                                   
#
person Philipp Claßen    schedule 17.04.2018
comment
Спасибо за эту информацию @philipp-claßen. Часть 0.0.0.0 была решающей и очень ценной. :недурно: - person mraxus; 24.04.2018

Насколько я вижу, вам нужно указать параметр --debug-brk= для node при запуске - это позволит отладить. После этого получите доступ к указанному порту в вашем док-контейнере. Вероятно, вам придется открыть его или туннелировать (используя ssh).

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

person mzedeler    schedule 03.07.2015

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

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

Например, контейнер инспектора узлов будет подключаться к локальному хосту: 5858, который затем будет сопоставлен портами с контейнером основного узла.

Если вы используете это на общедоступной виртуальной машине, я бы рекомендовал:

  • Убедитесь, что порт 5900 недоступен для общего доступа (например, брандмауэром).
  • Убедитесь, что порт инспектора узлов (например, 8080) нас общедоступен, чтобы вы могли к нему подключиться.

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

person rgareth    schedule 12.06.2016