I am planning the workflow for typical dev on a nodejs app. I presume most of you would:
git clone [appcode] + (Dockerfile with volume mapping to local path) > docker-compose build > docker-compose up
Then I edit some code, preferably using an IDE like Webstorm or text editor Sublime etc. Then terminal Ctrl+C to kill current process > docker-compose up (or configure your container to use nodemon to watch for code changes) and refresh browser to see latest local code running.
Does all the above look pretty standard?
My main question is does anyone debug either with an IDE or node-inspect into the container?
I've tried exposing ports etc.. Connection Refused. I believe because node.js will only allow debug on 127.0.0.1:5858
The Docker extension currently supports debugging Node. js, Python, and . NET applications within Docker containers.
I managed to make it run here. I wish I could run node-inspector as a sidekick container, it would be so clean(EDIT: It is possible, see end of answer). Unfortunately, looking into node-inspector sources, it is not possible to run node-inspector remotely(because node-inspector needs to access files so it can display them) so even container linking is out the window. Maybe it will support it at some point.
Here's is my solution:
In Dockerfile, install node-inspector. I decided to make it global so I can use the same container to debug all my apps.
RUN npm install -g node-inspector
Instead of lunching node in the CMD
command, use a bash script that will let you launch more than a single process. This is not the Docker way but as I stated, limit in node-inspector prevent us from using sidekick container. You could also use a more robust solution for process management like supervisor but for debugging a simple script is enough in my opinion.
CMD ["/bin/bash", "start.sh"]
This script checks for the presence of a DEBUG
environment variable to launch node and enable debug.
#!/bin/bash
if [ -z ${DEBUG+x} ]; then
node server.js
else
node-inspector --web-port 9080 &
node --debug server.js
fi
I guess you could use the same trick to install or not node-inspector. You can even have conditional statement in RUN command if you want to skip the script for installation.
Then when you want to debug a container, launch it like so:
docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
-v /home/docker/sources/.../:/usr/src/app custom-node
Now you just need to hit the docker daemon ip for debugging since we exposed the debug port specified in the script(9080) on the docker run
command. My Dockerfile already exposes my main port so I used -P
for that.
If your container runs on a local VM and you are setup behind a proxy, make sure it either support local addresses or that you disable it before debugging.
EDIT: now works with sidekick container
Here's is the content of my node-debug container Dockerfile
FROM node:4.2.1
EXPOSE 9080
RUN npm install -g node-inspector
CMD ["node-inspector", "--web-port", "9080"]
Docker provides us 2 features to make it as if node-inspector was running locally with the node process.
Even though node-inspector seems to imply you can connect to remote machine by telling you to connect to 127.0.0.1:8080/?ws=127.0.0.1&port=5858
, I couldn't find any code that was parsing the ws
parameter so I used docker net config option to pop the node-debug container in the same network stack as my debugged process: --net=container:mysvc
. This way, node-inspector can open the websocket connection to localhost:5858
.
By using the same mount point as your debugged process, you can fake file locality to the node-inspector process.
Now to make it a little more convenient, I would suggest to use data container for your app sources.
If you want the possibility to start node in debug or not, continue to use the start.sh script(remove the node inspector command though). I wonder if we could use a signal with docker though, that would remove the dependency on start.sh entirely.
if [ -z ${DEBUG+x} ]; then
node server.js
else
node --debug server.js
fi
So create the data container:
docker create -v /home/docker/sources/.../:/usr/src/app \
--name my_service-src custom-node /bin/true
Launch node app and expose node-inspector debug port:
docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
--volumes-from my_service-src custom-node
Launch node-debug container:
docker run -d --net=container:my_service --volumes-from my_service-src \
--name node-debug node-debug
This way, you can quickly spawn node-debug container on the fly to debug a node process.
Connect to docker ip and enjoy your debugging session !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With