Deploying Node.js Microservices with Docker and Docker Compose
This article demonstrates how to package a NestJS-based microservice architecture into Docker images, build and run them individually, and orchestrate multiple services using Docker Compose, covering Dockerfile multi-stage builds, port mapping, IP binding, and practical deployment steps for Node.js backend services.
The backend business logic of a NestJS project is split into separate microservices that communicate via TCP, with a main HTTP service forwarding requests to them. After development, the services are built with npm run build and the resulting dist folder is deployed.
Instead of copying files manually, each service is containerized using Docker. A typical multi‑stage Dockerfile for the main service looks like this:
FROM node:alpine as development<br/>WORKDIR /usr/app<br/>COPY package.json ./<br/>RUN npm install<br/>COPY . .<br/>RUN npm run build<br/>FROM node:alpine as production<br/>WORKDIR /usr/app<br/>COPY package.json ./<br/>RUN npm install --only=production<br/>COPY . .<br/>COPY --from=development /usr/app/dist ./dist<br/>CMD ["node", "dist/main.js"]Each microservice has a similar Dockerfile. After building the images with docker build -t main-app ., docker build -t ms-calc . and docker build -t ms-log ., they can be started individually with docker run -p 3000:3000 main-app, docker run -p 8888:8888 ms-calc and docker run -p 9999:9999 ms‑log. Port mapping ( -p host:container) and binding the services to 0.0.0.0 are essential so the containers are reachable from the host.
Running several containers manually is cumbersome, especially when the number of services grows. Docker Compose solves this by defining all services, their build contexts, Dockerfiles, ports, and start‑up order in a single docker-compose.yml file:
services:<br/> main-app:<br/> build:<br/> context: ./main-app<br/> dockerfile: ./Dockerfile<br/> depends_on:<br/> - ms-calc<br/> - ms-log<br/> - rabbitmq<br/> ports:<br/> - '3000:3000'<br/> ms-calc:<br/> build:<br/> context: ./micro-service-calc<br/> dockerfile: ./Dockerfile<br/> ports:<br/> - '8888:8888'<br/> ms-log:<br/> build:<br/> context: ./micro-service-log<br/> dockerfile: ./Dockerfile<br/> ports:<br/> - '9999:9999'<br/> rabbitmq:<br/> image: rabbitmq<br/> ports:<br/> - '5672:5672'Running docker-compose up builds all images and starts the containers in the correct order, merging their logs for easier monitoring. The setup can be managed via Docker Desktop, which shows the images and running containers.
Key points include using multi‑stage builds to keep production images small, copying only the dist folder to the final image, binding services to 0.0.0.0 instead of localhost, and using the host’s IP when services need to call each other. This workflow provides a reproducible, scalable way to deploy Node.js backend microservices.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
