Tutorial: Dockerize a Node.js Express application
You can use Docker to pack your application into an image along with a specific runtime environment and any other necessary dependencies. You can then run a container from that image to see how the application will run in this environment. This is called dockerizing an application.
This tutorial describes how to create a Dockerfile to build a Docker image with Node.js 22 and a Node.js Express application. It also shows how to share this image with others and run a Docker container from it.
Example 1: Dockerize a simple Node.js application
Let us start with a simple Node.js Express application. Let this applcation consist of a hello_express.js file that returns Hello World! and outputs Example app listening on port 3000! in the console.
Create an empty project with Node.js
Click New Project on the Welcome screen or select from the main menu.
In the dialog that opens, select Node.js in the left-hand pane.
Specify the location of the application and its name, for example,
hello_world_docker.Specify the local Node.js runtime to use. Accept the suggested installation or select another one from the list, or even click Download if you do not have Node.js on your machine yet. Learn more from Create a new Node.js application.

Click Create.
Populate the application
Let us create a separate folder for our application, this will help us later map local folders to folders in the container.
To do that, open the Project tool window Alt+1, right-click the project folder, select from the context menu, and then select . In the popup dialog that appears, specify the name of the folder, for example, app.

Now it is time to create a JavaScript file to place the code of our application in.

In the popup dialog that appears, specify the name of the file, for example, hello_express.js.

Open the newly created hello_express.js file in the editor and type the following code:
const express = require('express'); const app = express(); app.get('/', function(req, res) { res.send('Hello World!') }); app.listen(3000,function() { console.log('Example app listening on port 3000!') });As you might have expected, the
expressreference is not resolved and highlighted as an error. However, WebStorm suggests a quick-fix as you hover over the reference:
When you click the Install 'express' link,
expressis added to the package.json file and installed.
Run the application locally
Let us run our application locally to make sure it works as expected.
Open the hello_express.js file, right-click anywhere in the editor tab, and select from the context menu.

The Run tool window opens showing
Example app listening on port 3000!.If you open the browser at
http://localhost:3000, you will see that the page shows Hello World!, as expected.
Create a Dockerfile
From the context menu of the project folder, select from the context menu, and then select .

Open the newly created Dockerfile and type the following code:
FROM node:22-alpine WORKDIR /tmp COPY package*.json . RUN npm ci --omit=dev COPY ./app/ ./app/ CMD ["node","./app/hello_express.js"]This Dockerfile contains instructions for building an image based on the
node:22image from Docker Hub.When you run a container from this image, Docker sets copies the contents of the /app/ directory to the /tmp/app/ directory in the container (in our case, the /app/ directory contains the hello_express.js file). The package.json file is copied to /tmp/.
Then Docker sets the current working directory to /tmp and runs
node ./app/hello_express.js. As a result, the container log should showExample app listening on port 3000!.
Build and run an image from the Dockerfile
Open the Dockerfile in the editor, click
gutter icon, select Run, and then select Run on 'Docker'.

WebStorm creates a Dockerfile run configuration, which builds an image from the Dockerfile and then runs a container based on that image.

To see the whole process, open the Build Log tab in the Services tool window.

You can share the image with others, for example, to demonstrate exactly how your application is expected to run, without the need to install Node.js (only Docker is required).
We now have an Express app running inside a container, listening on port 3000. But we can’t connect to it from the outside. We need to expose the container’s port and then bind it to a port on the host.
Expose the container's port
Open your Dockerfile and add the following line to it:
EXPOSE 3000Now your Dockerfile will look as follows:
FROM node:22-alpine WORKDIR /tmp COPY package*.json . RUN npm ci --omit=dev COPY ./app/ ./app/ EXPOSE 3000 CMD ["node","./app/hello_express.js"]
Bind the container's port to a port on the host
You can do port binding in two ways:
In a run/debug configuration that WebStorm generates when you run a Dockerfile . In this case, you have to restart the container with
In a running container.
Bind ports in a run/debug configuration
When you run a Dockerfile as described above, WebStorm creates a temporary run/debug configuration of the type Dockerfile with the default name Dockerfile. This configuration is based on the settings from the Dockerfile used and contains no information about port bindings.
In the Run Widget on the main toolbar, select the autogenerated Dockerfile run configuration, then click
, and then select .

In the Run/Debug Configurations dialog that opens, select the Dockerfile run configuration in the left-hand pane and then click
on the toolbar.

In the right-hand pane, click Modify options and select Bind ports.

In the Bind ports field, click
and then click
in the Port Bindings dialog that opens.
In the Container port field, specify the port at which the application is running in the container, in this example it is
3000.In the Host port field, specify the port through which the application will be accessible from outside the container, for example,
3001.
When you click OK, the dialog closes and you return to the Run/Debug Configurations dialog where the port binding is specified in the Bind ports field:

Bind ports in a running container
Run your application as described above.
In the Dashboard tab, click Add in the Ports area and then specify the container port, in our example, it is
3000.
Click Modify options, set a tick next to Host port, and specify the host port in the field that is added. On our example, let it be
3001.
No matter how you specified the port binding, you can now open the application at http ://localhost:30001:

Example 2: Dockerize a Node.js Express application with elaborate folder structure
In this example we will use an Express application with a more complicated folder structure.
Create a Node.js Express application
Click New Project on the Welcome screen or select from the main menu.
In the dialog that opens, select Express in the left-hand pane.
Specify the location of the application and its name, for example,
node_express_docker.Specify the local Node.js runtime to use. Accept the suggested installation or select another one from the list, or even click Download if you do not have Node.js on your machine yet. Learn more from Create a new Node.js application.

Accept the default settings for the View Engine and the Stylesheet Engine.
Click Create.
WebStorm generates a simple Express application and installs the dependencies listed in package.json.
Run an application locally
To make sure our autogenerated application works, let us first run it locally. You may notice that WebStorm has also generated a bin/www run/debug configuration of the type Node.js.
Select the bin/www run/debug configuration from the Run widget on the toolbar and click
next to it.

The Run tool window opens showing the application output.

Open the browser at
http://localhost:3000. The page shows a welcome message:
Let's slightly update the code so we don't have to open the browser but can get some response from the application in the console. To do that, open bin/www and add the following line, for example, inside the
onListening()function:console.log("Hello world");If we now rerun the application, the Run tool window looks as follows:

Create a Dockerfile
In the Project tool window, right-click the project name, point to, New and click File.
In the New File dialog, type Dockerfile and press Enter.
Paste the following code to the new Dockerfile:
FROM node:22-alpine WORKDIR /tmp COPY package*.json . RUN npm ci --omit=dev COPY ./bin/ ./bin/ COPY ./public/ ./public/ COPY ./routes/ ./routes/ COPY ./views/ ./views/ COPY ./app.js . CMD ["npm","start"]As you can see, here we copy local folders separately step by step.
Let us expose the container port by adding
EXPOSE 3000to our Dockerfile:FROM node:22-alpine WORKDIR /tmp COPY package*.json . RUN npm ci --omit=dev COPY ./bin/ ./bin/ COPY ./public/ ./public/ COPY ./routes/ ./routes/ COPY ./views/ ./views/ COPY ./app.js . EXPOSE 3000 CMD ["npm","start"]
Deploy and run the application
To deploy and run the application, click
gutter icon, select Run, and then select Run on 'Docker'. The application is now running in a container:

Bind ports
To make the application accessible from outside a Docker container, we need to bind the container port, which in our example is 3000, to a port on the host.
You can do that right in a running container or in a Dockerfile run/debug configuration, as described above.
In the Dashboard tab, click Add in the Ports area and then specify the container port, in our example, it is
3000.
Click Modify options, set a tick next to Host port, and specify the host port in the field that is added. On our example, let it be
3001.
No matter how you specified the port binding, you can now open the application at http://localhost :30001:
