Guide to Node.js Dockerode with Docker and Docker Compose
Posted January 9, 2024
Docker ships, and runs applications in containers. If you are a Node.js developer, Dockerode runs your Docker containers as Remote APIs using JavaScript. Dockerode is a library, just like other Node.js libraries like Express.
Dockerode specifically works with Docker and Node.js to control your Docker containers. This way, Dockerode will manage Docker containers, images, and other Docker-related tasks (networks, volumes, Docker Compose) using only Node.js runtime. Dive into this guide and learn how to use Node.js with Dockerode to elevate how you run and manage Docker tasks.
Along this Node.js Dockerode with Docker and Docker Compose guide, you will learn:
- How Dockerode and Node.js make it easier to manage Docker containers with JavaScript.
- How to use Dockerode Node.js to build Docker images, create containers, and list and remove them.
- Using Dockerode to create Docker volumes and networks.
- The right way to execute Dockerode with Node.js to create Docker Compose configurations and run multiple containers.
Step 1: What you Need to use Dockerode
To follow along with Dockerode, you’ll need:
- Docker and Docker Compose are installed.
- Dockerode is Node.js package. To use it, Node.js must be installed on your computer.
Step 2: Setting up a Node.js Dockerode App
Let’s first create a Node.js project. You will head over to your working directory and initialize Node.js.
npm init -y
Now install Dockerode using NPM:
npm install dockerode
At this point, your Docker Engine should be running. Then create an app.js
Node.js file, import the Dockerode module, and create a new Node.js instance of Docker:
const Docker = require("dockerode");
const docker = new Docker();
Step 3: How to Build Docker Images with Dockerode
Let’s say you have a Node.js app. So, you have a simple index.js
file as follows:
// app.js
const express = require("express");
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello, Dockerode!");
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
In this case, you have already installed Express to run this app:
npm install express
To build an image, you will use a Dockerfile and then use the image to start a container. Create your Dockerfile as follows:
# Node.js base image
FROM node:20-alpine
# working directory
WORKDIR /app
# Copy package.json to the working directory
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy code to the container at /app
COPY . /app
# Expose port 3000
EXPOSE 3000
# run your app
CMD ["node", "index.js"]
From this point, you can provide Dockerode with the context of your Dockerfile while using buildImage
to return a Promise of NodeJS stream and create your custom Node.js API image.
In your Dockerode file setup (app.js
), proceed and create your image name and add the image tag as such:
// Define the image name and tag
const imageName = "nodejs-api";
const imageTag = "latest";
const fullImageName = `${imageName}:${imageTag}`;
Then use buildImage
method from Dockerode to extract the context on your Dockerfile. This example will assume your Dockerfile is at the same path as app.js
. This way, Node.js will use Dockerode to read Dockerfile and other important related files such as index.js
and package.json
.
Your Dockerode buildImage
method should look as follows:
// Build an image from the Dockerfile
docker.buildImage(
{ context: __dirname, src: ["Dockerfile", "index.js", "package.json"] },
{ t: fullImageName },
(err, stream) => {
if (err) {
console.error(err);
return;
}
docker.modem.followProgress(stream, onFinished, onProgress);
function onFinished(err, output) {
if (err) {
console.error(err);
} else {
console.log("Image built successfully:", output);
}
}
function onProgress(event) {
console.log(event);
}
}
);
To build your image, you now need to run this file just like any other Node.js app:
node app.js
This should successfully build and tag your image. Go to Docker and confirm these results:
Step 4: Creating Docker Containers using Dockerode and Node.js
The same process used to create images goes to the next step to build containers. With Dockerode, this step works the same as you would using the docker run
command or docker-compose
.
Dockerode will use the createContainer
method to reference all parameters required to successfully launch a Docker container. Using the already built image, add the following additional steps:
- First, you need port mapping to expose the container. Create a variable to do so:
// port mapping
const portMapping = {
"3000/tcp": [{ HostPort: "3000" }],
};
- Update the
buildImage
method. In this case, you want to create the container immediately afteronFinished
(Image built successfully) as follows:
docker.buildImage(
{ context: __dirname, src: ["Dockerfile", "index.js", "package.json"] },
{ t: fullImageName },
(err, stream) => {
if (err) {
console.error(err);
return;
}
docker.modem.followProgress(stream, onFinished, onProgress);
function onFinished(err, output) {
if (err) {
console.error(err);
} else {
console.log("Image built successfully:", output);
// Run a container from the built image
docker.createContainer(
{
Image: fullImageName,
// Container name
name: "node-app-container",
HostConfig: {
PortBindings: portMapping,
},
},
(err, container) => {
if (err) {
console.error(err);
return;
}
container.start((err, data) => {
if (err) {
console.error(err);
} else {
console.log("Container started successfully:", data);
}
});
}
);
}
}
function onProgress(event) {
console.log(event);
}
}
);
Rerun your Node.js command:
node app.js
This should create and run a container named port 3000 as follows:
Open http://localhost:3000/
on the web, and you should have a successfully created Dockerode container:
Step 4: Managing Docker Tasks with Dockerode Features
Docker allows you to manage other Docker app-related elements, such as list images, get running containers, and create networks and volumes. All these tasks are possible with Dockerode.
Below is a simple code to list local images and networks on Docker Engine:
docker.listImages((err, images) => {
if (err) {
console.error("Error listing images:", err);
return;
}
console.log("Images:", images);
});
docker.listNetworks((err, networks) => {
if (err) {
console.error("Error listing networks:", err);
return;
}
console.log("Networks:", networks);
});
Step 6: Using Dockerode and Node.js with Docker Compose
Is it possible to use Dockerode to run Docker Compose Commands? docker-compose
commands build and start services defined in the Docker Compose file (docker-compose.yml
).
Docker Compose runs multi-container Docker applications. To do that programmatically using Node.js and Dockerode, you first install dockerode-compose package:
npm i dockerode-compose
This will give you access to compose commands to build and run your Docker Compose services.
Check dockerode-compose docs and learn how to use Docker Compose with Dockerode.
Conclusion
This guide helped you learn how Dockerode and Node.js make it easier to manage Docker containers with JavaScript. I hope you found the tutorial helpful!
More Related Articles:
-
Easy Apache PHP Guide with Docker Compose, MySQL and PhpMyAdmin
Nov 20, 2023
-
Deploy PHP FPM, Apache httpd, and MySQL with Docker Compose
Nov 1, 2023
-
Running PHP, Apache, and PostgreSQL with Docker Compose
Oct 1, 2023
-
Guide to TypeORM with NestJS, Postgres, MySQL, Multer, Docker and Docker Compose
Sep 28, 2023