Introduction
In this tutorial, you will learn how to containerize a Node.js microservice using Docker. Containerization allows you to package your microservice and its dependencies into a single, portable unit that can run consistently across different environments. We'll walk through each step, provide the necessary commands, and explain key technical terms.
Prerequisites
Before you begin, make sure you have the following prerequisites:
Node.js installed on your development machine.
Docker installed on your development machine. You can follow the official Docker installation guide to install Docker for your platform.
Step 1: Develop a Node.js Microservice
First, let's create a simple Node.js microservice. You can use your own microservice code or create a simple example using Express.js.
Create a new directory for your microservice:
mkdir node-microservice cd node-microservice
Initialize a Node.js project and install Express:
npm init -y npm install express
Create a basic Express.js microservice in an
app.js
file:const express = require('express'); const app = express(); const port = process.env.PORT || 3000; app.get('/', (req, res) => { res.send('Hello, Microservice!'); }); app.listen(port, () => { console.log(`Microservice is running on port ${port}`); });
Save the changes and exit your code editor.
Step 2: Write a Dockerfile
A Dockerfile is used to define the environment and instructions for building a Docker image. In this step, we'll create a Dockerfile for your Node.js microservice.
Create a file named
Dockerfile
in the root of your microservice directory:touch Dockerfile
Open the
Dockerfile
in a text editor and add the following content:# Use an official Node.js runtime as the base image FROM node:14 # Set the working directory within the container WORKDIR /app # Copy the package.json and package-lock.json files to the container COPY package*.json ./ # Install project dependencies RUN npm install # Copy the rest of the application code to the container COPY . . # Expose a port for your microservice EXPOSE 3000 # Define the command to start your microservice CMD ["node", "app.js"]
This Dockerfile specifies a Node.js base image, sets up the working directory, copies the project files, installs dependencies, exposes a port, and defines the command to start the microservice.
Step 3: Install Docker
If you haven't already installed Docker, here are the steps to install it:
Linux Installation
Update your package manager:
sudo apt-get update
Install necessary packages:
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
Add Docker's official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Add the Docker repository to your sources list:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Update the package list to include Docker and install it:
sudo apt-get update sudo apt-get install docker-ce -y
Add your user to the
docker
group to run Docker commands without sudo:sudo usermod -aG docker ${USER}
Activate the changes to groups:
su - ${USER}
Verify that Docker is installed and running:
sudo systemctl status docker
Windows Installation
- Download the Docker Desktop for Windows installer and follow the installation instructions.
macOS Installation
- Download the Docker Desktop for Mac installer and follow the installation instructions.
Step 4: Build the Docker Image
Now that you have a Dockerfile, you can build a Docker image for your Node.js microservice.
Open your terminal and navigate to the root of your microservice directory.
Build the Docker image using the
docker build
command. Replace<image-name>
with a name for your image, and optionally add a tag (e.g.,v1.0
) for versioning:docker build -t <image-name>:<tag> .
For example:
docker build -t my-node-microservice:v1.0 .
Docker will execute the instructions in your Dockerfile, creating an image for your microservice.
Step 5: Run Multiple Instances with Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. In this step, we'll use Docker Compose to run multiple instances of your microservice.
Create a
docker-compose.yml
file in your microservice directory:touch docker-compose.yml
Open the
docker-compose.yml
file in a text editor and add the following content:version: '3' services: microservice: image: my-node-microservice:v1.0 ports: - 3000:3000
This
docker-compose.yml
file defines a service named "microservice" based on the Docker image you built earlier. It maps port 3000 on your host to port 3000 in the container.Save the changes and exit your code editor.
Run your microservice using Docker Compose:
docker-compose up
This command starts your microservice within a Docker container.
Step 6: Implement Service Discovery with Docker Networking
Docker provides built-in networking features that allow containers to communicate with each other. By default, containers launched by Docker Compose can resolve
each other's service names as hostnames.
In your Node.js microservice, you can connect to another microservice using its service name as the hostname.
For example, if you have another microservice running and named "other-service" in your docker-compose.yml
, you can make an HTTP request to it like this:
const axios = require('axios');
axios.get('http://other-service:3000')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
By using Docker Compose and Docker's built-in networking, you can easily implement service discovery between microservices.
Conclusion
You've successfully containerized a Node.js microservice using Docker. This allows you to package your microservice and its dependencies into a portable unit that can be deployed consistently across different environments. You've also learned how to run multiple instances of your microservice with Docker Compose and implement service discovery using Docker networking.
Key Terms & Meaning:
Dockerfile: A script used to create a Docker image, defining the environment and instructions for building a container.
Docker Image: A lightweight, stand-alone, executable package that includes everything needed to run a piece of software, including the code, runtime, system tools, and libraries.
Docker Compose: A tool for defining and running multi-container Docker applications.
Service Discovery: The process of automatically detecting and connecting to available services in a network, often used in microservices architectures.
Docker Networking: Docker's networking features that allow containers to communicate with each other using service names as hostnames.