One of the nice things about docker is that we can use all kinds of software without cluttering up our local machine. I really like the ability to have the development environment running in a container. Here is an example where we:
- Get a Node.js development environment with all required tools and packages
- Allow remote debugging of the app in the container
- See code changes immediately reflected inside the container
dockerfile below gives us a container with all required tools and packages for a Node.js app. In this example we assume the ‘.’ directory contains the files needed to run the app.
RUN npm install -g nodemon
COPY package.json /code/package.json
RUN npm install && npm ls
RUN mv /code/node_modules /node_modules
COPY . /code
CMD ["npm", "start"]
That’s nice, but how does this provide remote debugging? and how do code changes propagate to a running container?
Two very normal aspects of docker achieve this. Firstly
docker-compose.yml overrules the
CMD ["npm", "start"] statement to start
nodemon with the
--inspect=0.0.0.5858 flag. That starts the app with the debugger listening on all of the machines IP addresses. We expose port 5858 to allow remote debuggers to connect to the app in the container.
Secondly, the compose file contains a volume mapping that overrules the
/code folder in the container and points it to the directory on the local machine where you edit the code. Combined with the
nodemon sees any changes you make to the code and restarts the app in the container with the latest code changes.
Note: If you are running docker on Windows of the code is stored on some network share, then you must use the
--legacy-watch flag instead of
command: nodemon --inspect=0.0.0.0:5858 --watch
launch.json for Visual Studio Code to attach to the container.