WebStorm 2025.3 Help

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

  1. Click New Project on the Welcome screen or select File | New | Project from the main menu.

  2. In the dialog that opens, select Node.js in the left-hand pane.

  3. Specify the location of the application and its name, for example, hello_world_docker.

  4. 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.

    Create an empty project with Node.js
  5. Click Create.

Populate the application

  1. 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 New from the context menu, and then select Directory. In the popup dialog that appears, specify the name of the folder, for example, app.

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

    From the context menu of the app folder, select New from the context menu, and then select JavaScript File.

    Create a JavaScript file, context menu

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

    Create a JavaScript file
  3. 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!') });
  4. As you might have expected, the express reference is not resolved and highlighted as an error. However, WebStorm suggests a quick-fix as you hover over the reference:

    Express is not installed - a quick-fix is suggested

    When you click the Install 'express' link, express is added to the package.json file and installed.

    package.json - Express 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 Run 'hello_express.js' from the context menu.

    Run an application locally

    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.

    The application is running locally

Create a Dockerfile

  1. From the context menu of the project folder, select New from the context menu, and then select Dockerfile.

    Create a Dockerfile - context menu
  2. 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:22 image 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 show Example app listening on port 3000!.

Build and run an image from the Dockerfile

  1. Open the Dockerfile in the editor, click The Run on Docker icon gutter icon, select Run, and then select Run on 'Docker'.

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

    Services tool window, Log tab

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

    View full log
  3. 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 3000

    Now 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.

  1. In the Run Widget on the main toolbar, select the autogenerated Dockerfile run configuration, then click the More Actions icon, and then select Edit.

    Open Dockerfile run configuration from the Run Widget
  2. In the Run/Debug Configurations dialog that opens, select the Dockerfile run configuration in the left-hand pane and then click the Save Configuration icon on the toolbar.

    Save temporary Dockerfile configuration
  3. In the right-hand pane, click Modify options and select Bind ports.

    Dockerfile configuration—bind ports
  4. In the Bind ports field, click the Browse button and then click the Add button 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.

    Specify the container port and the host port

    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:

    Ports bound

Bind ports in a running container

  1. Run your application as described above.

  2. In the Dashboard tab, click Add in the Ports area and then specify the container port, in our example, it is 3000.

    Bind ports - specify the container port

    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.

    Bind ports in a running container

No matter how you specified the port binding, you can now open the application at http ://localhost:30001:

Ports bound, the application is opened in the browser at 3001

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

  1. Click New Project on the Welcome screen or select File | New | Project from the main menu.

  2. In the dialog that opens, select Express in the left-hand pane.

  3. Specify the location of the application and its name, for example, node_express_docker.

  4. 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.

    Create a Node.js Express application
  5. Accept the default settings for the View Engine and the Stylesheet Engine.

  6. 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.

  1. Select the bin/www run/debug configuration from the Run widget on the toolbar and click the Run 'bin/www' icon next to it.

    Run an Express application locally

    The Run tool window opens showing the application output.

    the Run tool window with the application output
  2. Open the browser at http://localhost:3000. The page shows a welcome message:

    Express application is opened in the browser
  3. 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:

    Hello world  in the Run tool window

Create a Dockerfile

  1. In the Project tool window, right-click the project name, point to, New and click File.

  2. In the New File dialog, type Dockerfile and press Enter.

  3. 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.

  4. Let us expose the container port by adding EXPOSE 3000 to 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 The Run on Docker icon gutter icon, select Run, and then select Run on 'Docker'. The application is now running in a container:

    The application is deployed and running in a docker 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.

    Bind ports - specify the container port

    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.

    Bind ports in a running container

No matter how you specified the port binding, you can now open the application at http://localhost :30001:

Ports bound, the application is opened in the browser at 3001
20 October 2025