node.js - dockerize - Cómo depurar la aplicación Nodejs que se ejecuta dentro del contenedor Docker a través de Google Cloud
mongodb docker compose (5)
He descubierto que Google proporciona algunas pautas sobre cómo ejecutar Nodejs en un entorno de tiempo de ejecución personalizado . Todo parece estar bien y estoy logrando iniciar mi aplicación Nodejs en la máquina local ejecutando la gcloud preview app run .
.
Como puedo ver, probablemente crea un contenedor Docker y ejecuta el programa Nodejs allí. Estoy diciendo "probablemente" , porque es mi primera experiencia con Docker, sin embargo, tengo más de 2 años de experiencia en el desarrollador de Nodejs.
Entonces mi pregunta es cómo depurar (con el punto de interrupción se detiene) mi programa Nodejs cuando se ejecuta dentro del contenedor Docker. Utilizando las herramientas de desarrollo de Chrome o cómo puedo configurar la configuración de depuración de Webstorm para que se detenga en los puntos de interrupción. ¿Es posible configurar Docker sobre cómo inicia el nodo o incluso iniciar Docker a través de gcloud
dentro de Webstorm para asegurar que la depuración esté funcionando? Cualquier ayuda o aclaración es apreciada.
No proporciones respuestas sobre cómo depurar la aplicación Nodejs fuera del contenedor Docker: sé cómo hacerlo muy bien.
Hay una manera más fácil, al menos de Docker 0.11 o algo así.
Ejecute, solo en su máquina de desarrollo, Docker con --net = "host". Esto hace que Docker se vincule al localhost directamente y no cree un adaptador de red puenteante, por lo que la máquina Docker se ejecuta como cualquier otro proceso en su máquina y abre los puertos que necesita en la interfaz local.
De esta forma, puede conectarse a su puerto de depuración como si Node no se estuviera ejecutando dentro de Docker.
Más documentación aquí: https://docs.docker.com/reference/run/
Antes de Docker 0.11 tiene otras dos formas de depuración, además de usar node-inspector:
- Ejecute sshd dentro de su máquina Docker y configure un túnel ssh, como si fuera a depurar en una máquina remota.
- "Mess up" con ip-tables para "revertir" la asignación de Docker de los puertos locales. Aquí hay algo al respecto. Exponer un puerto en un contenedor Docker en vivo .
Lo siento, pero solo conozco una solución con node-inspector, espero que pueda ayudarte:
- Puede instalar el paquete node-inspector dentro de su contenedor: https://github.com/node-inspector/node-inspector
- Asigne el puerto 8080 de su contenedor en su host (ejecute su contenedor con el parámetro -p 8080: 8080)
Ejecuta esto dentro de tu contenedor (con docker exec, o docker-enter)
node-debug --web-host 0.0.0.0 yourScript.js
Por defecto, el depurador de nodos escuchará solo las conexiones para el mismo host ( 127.0.0.1
). Pero en Docker, necesitas aceptar conexiones desde cualquier host ( 0.0.0.0
):
# inside Docker
node --inspect=0.0.0.0:9229 myapp.js
También debe exponer el puerto de depuración (9229). Luego, la aplicación se debe detectar automáticamente y enumerar como un objetivo remoto en chrome://inspect/#devices
en Chrome (probado en Chrome 67).
Ejemplo
Aquí hay un ejemplo mínimo. Ejecuta una aplicación de JavaScript simple en Docker y muestra cómo adjuntar el depurador de 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
Corre con:
$ 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
...
Abre Chrome y ve a chrome://inspect/#devices
. Poco después del inicio de la aplicación, debe detectarlo y enumerarlo.
Solución de problemas
Para la depuración de problemas de red Docker, Docker docker inspect
es útil:
$ 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"
}
]
},
...
Si desea ver las solicitudes enviadas entre Docker y Chrome, ngrep puede ayudar:
$ 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".} ]..
#
Por lo que puedo ver, debe proporcionar el parámetro --debug-brk = al nodo al inicio - esto habilitará la depuración. Después de eso, acceda al puerto especificado en su contenedor de docker. Probablemente tengas que exponerlo o tunelizar (usando ssh).
Después de eso, señale el depurador remoto de Tormenta web en el puerto especificado, y debe configurarlo.
Si está utilizando una red puente para sus contenedores, y no desea instalar el inspector de nodos dentro del mismo contenedor que su proceso de nodo, he encontrado que esta es una solución conveniente:
- En el contenedor principal node.js, asigne el puerto 5858 al host
- Ejecute el proceso del nodo principal con la depuración habilitada
- Use un contenedor separado para ejecutar node-inspector
- Usar la red de host para el contenedor de inspectores de nodos
Por ejemplo, el contenedor del inspector de nodos se conectará a localhost: 5858, que luego se asignará al puerto al contenedor del nodo principal.
Si está ejecutando esto en una máquina virtual pública, le recomendaría:
- Asegúrese de que el puerto 5900 no esté expuesto públicamente (por ejemplo, mediante el firewall)
- Asegúrese de que el puerto del inspector de nodos (p. Ej. 8080) esté expuesto públicamente, para que pueda conectarse a él
Escribí algunos detalles más aquí: https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector