Containerize a Node.js application
Prerequisites
- You have installed the latest version of Docker Desktop.
- You're familiar with basic Docker concepts. If you're new to Docker, start with Get started.
Overview
Containerizing your application means packaging it together with its dependencies, configuration, and runtime into a single portable unit called a container image. Running that image creates a container, an isolated process that behaves the same on any machine, whether it's your laptop, a CI runner, or a production server.
In this section, you'll containerize a simple Express.js API written in TypeScript. You'll write a Dockerfile that describes how to build the image, add a compose.yaml file that defines how Docker runs your container, and then build and start the application with one command.
You'll use Docker Hardened Images as the base. These are minimal, secure Node.js images maintained by Docker.
This guide focuses on a backend Node.js API. If you're building a standalone frontend application, Docker has dedicated guides for React.js, Vue.js, Angular, and Next.js.
Create the application
The sample application is a minimal Express API with a single endpoint that returns a JSON greeting. Create the following files in a new nodejs-docker-example directory. To create all the files at once, switch to the Scaffold script tab in the file browser and copy the shell command.
If you have Node.js installed and want to verify the app works before containerizing it, you can run it locally.
To run in development mode with hot-reload:
$ npm install
$ npm run dev
To run the compiled production build (matching what the Dockerfile does):
$ npm install
$ npm run build
$ npm start
Then open http://localhost:3000 in your browser. You should see {"message":"Hello World"}.
If you don't have Node.js installed, skip ahead. The remaining steps run the application in a container, with no local Node.js required.
Create the Docker assets
Sign in to the DHI registry so Docker can pull the Node.js base images during the build. The available Node.js images are listed in the catalog.
$ docker login dhi.io
Add the following three files to your nodejs-docker-example directory. The Dockerfile describes how to build the image, compose.yaml defines how Docker runs the container, and .dockerignore keeps unwanted files out of the build context.
TipGordon, Docker's AI assistant, can generate Docker assets for your project. Ask Gordon to create a Dockerfile, Compose file, and
.dockerignoretailored to your application.
The Dockerfile uses three stages. The builder stage installs all dependencies and compiles TypeScript. The deps stage does a fresh install of production-only dependencies. The runner stage copies the compiled output and production node_modules into a minimal runtime image that contains only Node.js.
To learn more about each file, see the following:
Run the application
Inside the nodejs-docker-example directory, run the following command in a
terminal.
$ docker compose up --build
Open a browser and view the application at http://localhost:3000. You should see {"message":"Hello World"}.
In the terminal, press ctrl+c to stop the application.
Run the application in the background
You can run the application detached from the terminal by adding the -d
option. Inside the nodejs-docker-example directory, run the following command
in a terminal.
$ docker compose up --build -d
Open a browser and view the application at http://localhost:3000.
In the terminal, run the following command to stop the application.
$ docker compose down
For more information about Compose commands, see the Compose CLI reference.
Summary
In this section, you learned how to containerize and run a Node.js application using Docker.
Related information:
Next steps
In the next section, you'll take a look at how to set up a local development environment using Docker containers.