Install Node In Docker Container
Jan 26, 2017 So, we would need to execute a command on our node container, using the run command provided by docker-compose. Docker-compose run -rm -no-deps node bash -ci 'npm install'. Note the -no-deps argument, which prevents to start db service in this case. This command would work fine. Yet, if we check nodemodules file permissions, we would get an. In this guide you will learn how to set up your own VeChain Thor node that can connect to main or test net. For this, we will be using Docker and assume you are running a Windows OS. Step 1: Install Docker Wikipedia defines Docker as An open-source project that automates the deployment of software applications inside containers by. EXPOSE: It ensures that a process running in a Docker container is listening on port 3000. It helps forward the ports from the host to the container. CMD: It executes the node app.js command inside our Docker container after the container has started. Step 2: Creating a.dockerignore file. Let’s now try and build a custom container and test it with the code. Testing It Within A Container. Let’s go back to Terminal, stop the server, and remove the node modules because they will be different for Mac OS and Linux. # ctrl + c - to stop the server rm -rf nodemodules; Now let’s create a new Docker container based on an Alpine image.
- Install Nodejs In Docker Container
- Install Nodejs On Ubuntu Docker Container
- Install Node In Docker Container Architecture
Debugging an application involves detecting and removing existing errors also known as bugs in a code which can cause it to work unexpectedly or even crash. Debugging allows the developers to find and resolve bugs or defects in the application to prevent incorrect and unwanted operations.
In this tutorial, we will build a Node.js application with a bug in it, run it in a Docker container and use Visual Studio Code debugging tools for Node.js to debug it. The tutorial can be used by developers as a reference when building their applications.
Prerequisites
To follow along with this tutorial, you are required to have the following.
- Prior knowledge of Docker containers and Node.js.
- Docker installed.
- Node.js installed.
- Microsoft Visual Studio Code installed.
- A web browser. I will be using Google Chrome.
Step 1: Creating the root directory
We will create a simple to-do list application that allows the users to add and delete tasks. We will also introduce a minor bug when coding the application and use Visual Studio Code to address the issue and fix it.

Open a new terminal window, browse to a root directory, and run the command below:
Step 2: Initializing the Node.js project
Initialize the project by executing the below command:
The above command will generate a file named package.json in the TodoApp
folder. The package.json
file contains the information related to the Node.js project. It also gives information to npm about the project’s dependencies.
The file will look like this:
Creating the to-do application
Next, we will build our to-do application using Express.js: a fast, popular and lightweight Node.js web framework.
Express makes the development of web applications easier.
Step 1: Installing project’s dependencies
We will install express
and a few other prerequisites needed by the application by running the command below:
Step 2: Coding the app.js file
Then we will create a file named app.js
in the TodoApp
directory with the code below:
Step 3: Creating the todo.ejs file
Next we will create a file ./views/todo.ejs
and paste the following code in it:
Step 4: Starting the web server
Start the web server by executing the command below:
A success message that the server is running and listening to the specified port will be displayed on the console window.
Creating a Docker image
Now we have successfully created a Node.js application.
Next, we will create a Docker image for it.
A Docker container is built from a Docker image that contains the necessary information needed to deploy and run the application with Docker.
To run a Docker container, we can either create our own Docker image or download an already built Docker image. In our case, we will create our own Docker image. A Docker image is comprised of multiple layers, which are a read-only file system.
Docker works in a way that it creates a layer for every instruction contained in a Dockerfile. Each new layer resides on top of the previous layers.
For the application’s code that may change often, it’s recommended to place it towards the end of the file.
Step 1: Creating a Dockerfile
Create a file named Dockerfile in the project’s root directory with the lines of code below:
Let’s take a closer look at the file we have just created:
- FROM: Sets the base image. Everything that will be added later will be based on this image. We are going to use Node.js version 14 in this tutorial.
- WORKDIR: The working directory for the commands
COPY
,RUN
andCMD
is set here. - RUN: It executes the
npm install
command in a Docker container. - COPY: It copies the files to the Docker image from the build context.
- EXPOSE: It ensures that a process running in a Docker container is listening on port 3000. It helps forward the ports from the host to the container.
- CMD: It executes the
node app.js
command inside our Docker container after the container has started.
Step 2: Creating a .dockerignore file
As we do not want to send large files to the build context and speed up the system, we use the .dockerignore
file.
It is a text file similar to .gitignore
which contains the name of the directories and files that should not be added to the build. The file .dockerignore
will contain the following content:
Step 3: Building a Docker image
Next, we will execute the docker build
command to build our Docker image:
The -t
flag specifies the name of the image. The path to the context points to the set of files we want to reference from our Docker file.
As discussed earlier, the docker build
command adds a new layer for every command in the Dockerfile.
Docker deletes the intermediate containers once the command executes successfully.
Step 4: Running the Docker container
With our Docker image in place, we can now run it by executing the docker run
command and pass it the arguments below:
-p
is the port on the host. In our case, we will use port 3001 that will be forwarded to the container port 3000 and separated by:
.-e
will create an environment variable. In our case, we use the nameSECRET
and assign it the value tobestkeptsecret
.-d
ensures the container will execute in the background.- The name of the image in this case:
to-do-app
.
The whole command will look like below:
Step 5: Verifying if the container is running
We can verify that our Docker container is running using:
The output will be similar to the one shown below:
Step 6: Inspecting the Docker logs
To inspect the logs, execute the docker logs
command followed by the id
of the container:
The output will appear as below:
Step 7: Testing the app on the web browser
Now that our application is up and running. We can browse to the link http://localhost:3001, and we try to add a new todo. As we can be seen below, the application displays an error on the line: todolist.forEach(function(todo, index)
of the todo.ejs
file.
In the steps below, we will look at how to debug the error above using Visual Studio Code.
Step 8: Stopping the Docker container
First, we have to stop the container from running by executing the below command:
Debugging using Visual Studio Code
Visual Studio Code comes loaded with debugging tools for the Node.js applications running inside a Docker container.
Below are the steps we can follow to use them:
Step 1: Updating the Dockerfile
Edit the Dockerfile
by replacing the line below:
With:
Our updated Dockerfile
will now look as shown as below:
Step 2: Editing the package.json file
Edit the package.json
file by adding the line of code below:
The line of code above initializes the Node.js process to listen to a debugging client running on port 9229.

The updated package.json
file will now look like this:
Step 3: Building the Docker image
Note that every time the Dockerfile
gets updated, we must build the Docker image again:
Also, note that Docker will now run the npm run start-debug
command as we updated earlier.
Step 4: Running the Docker container
To debug using Visual Studio Code, we must forward port 9229.
This is done by running the command below:
The above command will produce the following output:
Step 5: Inspecting the Docker logs
We can check the logs by running the docker logs
command and specifying the id
of the container as shown below:
Note that the debugger is now listening to port 9229. Next, we will configure Visual Studio Code to debug our application.
Steps when debugging the application using Visual Studio Code
Launch Visual Studio Code and open the project directory as below:
Step 1: Configuring Visual Studio Code
The debug configurations in Visual Studio Code are stored in a file named launch.json
. To access it, press Ctrl+Shift+P
and then search for Debug: Open launch.json
and open it.
Edit the launch.json
file to look like the code snippet below:
Since we do not want to go through the code in the node_modules
directory and builtin Node.js core modules, we have included the skipFiles
attribute.
Step 2: Placing a breakpoint to debug the code
Now that we have everything set up, we can start debugging the application. If you can recall from earlier, we had an error in the view/todo.ejs
file, in which the line of code below goes over the todolist
array.
In the app.js
file, the todo.ejs
file gets rendered at this line res.render('todo.ejs', { todolist: req.session.todolist })
. We will put a breakpoint at that line and check the value of the todolist
variable as shown below:
Step 3: Inserting an expression to check the value of the variable
Press Shift+Ctrl+D
to change to the debug view.
Then click on the Debug and Run
button as shown below:
To check the value of the req.session.todolist
variable, we will insert an expression to watch. It is done by selecting the +
sign under watch on the sidebar of the window and then entering the name of the variable (req.session.todolist
) as shown below:
Step 4: Testing the app on a web browser
Next, switch to the web browser and refresh the page http://localhost:3001/todo as shown below:
The Waiting for localhost
message will appear at the bottom left of the page, meaning that the breakpoint we created has paused execution, and we can check the value of the req.session.todolist
variable.
Now move back to Visual Studio Code to get the details as shown:
So the req.session.todolist
variable is undefined
. Is it possible to fix the bug?
Step 5: Fixing the bug
The ejb
template goes through the todolist
array and ought to be placed in the current session. However, we did not initialize the array, so it is undefined.
To fix the bug we will add the lines of code below to the .use
function:
The code snippet should be added just above the next
function.
Our .use
function will look as below:
Step 6: Stopping the Docker container
Next we will retrieve the id
of our running container by executing the docker ps
command as below:
Stop the container by running the docker kill
command followed by its id
as below:
Step 7: Re-building the Docker image
To apply the changes we made earlier, we must re-run the docker build
command as shown below:
Step 8: Re-running the Docker container
Next, run the container using the command below:
Step 9: Reload the web browser to confirm if a bug is fixed
Reload the https://localhost:3001/todo page on the browser and check the results as shown below:
Wrapping up
We have successfully written a to-do list Node.js application, executed it in a Docker container, and utilized our Visual Studio Code debugging tools to identify and fix the issue.
The tutorial can be helpful to the developers who want to build their Node.js application in a Docker container and use the Visual Studio code debugging tools to debug their code.
The code snippets and files used in this tutorial can be found in this GitHub Repo.
Happy coding!
Peer Review Contributions by: Geoffrey Mungai
About the author
Verah OmbuiVerah Ombui is an undergraduate Computer Science student at Jomo Kenyatta University Of Agriculture and Technology. Her interests are web development, cloud computing, and data science. Verah is a technology enthusiast.
In this post I share with you how I set up a simple Dockercontainer for Node.js development. I’ve never found a simple tutorial for beginners that meets my needs!
My requirement is to do all development debugging in a container, so I am assured of consistent behaviour in any environment. I do not want to install Node.js or npm locally on my mac! I cannot be bothered to use a Makefile or Dockerfile to build images - this is only required in the final stage for production!
This is the first in a series of posts on my journey with containers and orchestration. The next post introduces you to Wiring up (networking) Node.js and MongoDB containers.
You’ll need to install Docker Desktop and Microsoft Visual Studio Code 1.10+ - both are available for Windows and mac OS.
To be clear, this is simply a setup for developers - this is not the way to use containers in production (i.e. please go ahead and build images with Dockerfile). In addition, I only advocate downloading 'Official' or 'Docker Certified' images off Docker Hub.
In the host (i.e. on our macOS terminal):
Create a working directory e.g. ~/Work/node
and in that directory, create hello.js
with:
Share the folder in Docker > Preferences... > File Sharing:
- Add the folder
- Hit Apply & Restart
Back in the terminal, download and run a new Node.js container. The run
arguments are:
-it
is shorthand for--interactive --tty
to get the console by running the givenbash
shell--rm
to delete the container when done, since we always use the original image without persisting changes-v
to mount a local volume (the current folder$PWD
) to the given folder in the container-p
to “publish” the port so the host can get to it, in this case 8080
Now the terminal will be running the shell within the container! You’ll know because the prompt will be something like [email protected]:
I prefer to specify bash
or /bin/bash
as the shell, because while the official node image does run bash, many other images specify an ENTRYPOINT
(i.e. a specific executable or comamnd to run when the container starts) and do not run the shell!
In the container terminal, run:
Open a browser to locahost:8080
and you should get the Hello world
message!
To stop the program, back in the container terminal, hit Ctrl-C.
In the container, install nodemon to monitor for changes to hello.js
and automatically restart the node server.

Now, you can make changes to hello.js
and node will restart. Try it - make a change to the “hello world” output and refresh your browser.
Because the container above is not persistent, when you stop the container (with Ctrl-C) and re-start, the installed nodemon would be gone. So, let’s create a new image of Node.js persisting the installed nodemon.
Run the container as above but give it a name, nodedev
:
In the container, install nodemon and exit (which stops the container):
At this stage you should install any other Node.js modules you need in the container, once and for all!
Now, make the change persistent in a new image called nodemondev
, and then run the container again to test (note I don’t run with --name
but instead use --rm
again because I’m not going to persist subsequent changes):
In the container, you can type nodemon
and viola! nodemon is already installed!
In addition, if you want to just immediately run nodemon but yet have the console respond to Ctrl-C to stop node (rather than have to manually stop the container), just run:

VS Code is great for many reasons - one of which is that it can attach to a running Node.js instance and debug the code with step-through and breakpoints.
The important settings when starting Node.js (which in this case I do via nodemon
in a container) are:
Install Nodejs In Docker Container
- turn on debugging with
--inspect=0.0.0.0:9229
, where0.0.0.0
would allow all ingress (remote connections), otherwise debugging is only available from within the container. - and, publish the debugging port 9229 to the host with
-p 127.0.0.1:9229:9229
.
Note that the Node.js Debugging guide states 'Exposing the debug port publicly is unsafe', so we mitigate by only exposing the port to only the host hence the explicit 127.0.0.1
. However, port 8080 is public - but now you know how to change it if so desired.
Now, the magic from VS Code:
- Hit the debugging icon (or from the menu View > Debug)
- Next to the green play ▶ button, hit the dropdown and select Add Configuration....
- In the new editor
launch.json
, select Attach to Process. - The block below will be added and you must add the
remoteroot
path manually (remember the comma in the preceding line). Save and close:
Without remoteRoot
, you’ll get an Unverified breakpoint
message whenever you try to set a breakpoint!
Now hit the green play ▶ button and you’ll be prompted to attach to a Docker container. Simply select yours:
To test, place a breakpoint at res.writeHead(200);
by pressing F9, and refresh the page in your browser. You’ll suddenly be back in VS Code with variables, call stack, etc. displayed. Brilliant!
BTW, if you are too lazy to choose a process above, you could pre-configure everything. The downside is that every new container will need a section like this, where as with the above, as you can select from many containers with different debugging ports (as long as code is always in the /code
folder).
You can read more about the options at Node.js debugging in VS Code.
Still want more? How about running the docker
command line from the green play ▶ button in VS Code directly?
Create another debug configuration in the launch.json
file as below:
Now you never have to leave VS Code, even the Terminal is embedded!
Install Nodejs On Ubuntu Docker Container
It’s really easy to use Docker containers for development, just a little bit of overhead which you can easily script. This provides a more consistent environment without having to install Node.js, etc. on your mac or Windows desktop, more so if your servers are mostly Linux-based.
Install Node In Docker Container Architecture
On to the next post, Wiring up Node.js and MongoDB containers!