Introduction
Microservices architectures allow you to break down monolithic applications into independent services, each responsible for a specific business domain. This approach improves scalability, resilience, and deployment speed. In 2026, teams routinely use tools like Kubernetes for orchestration and message brokers for asynchronous communication. This tutorial guides you step by step through building a complete system consisting of two Node.js services communicating via RabbitMQ, containerized with Docker, and deployed on Kubernetes. Each step includes production-ready code.
Prerequisites
- Node.js 20+
- Docker Desktop
- Kubernetes (Minikube or cloud cluster)
- Solid knowledge of TypeScript and distributed architecture
- RabbitMQ installed locally for testing
User Service
import express from 'express';
import amqp from 'amqplib';
const app = express();
app.use(express.json());
let channel: any;
async function connectRabbit() {
const connection = await amqp.connect('amqp://localhost');
channel = await connection.createChannel();
await channel.assertQueue('user_created');
}
app.post('/users', async (req, res) => {
const user = { id: Date.now(), ...req.body };
await channel.sendToQueue('user_created', Buffer.from(JSON.stringify(user)));
res.status(201).json(user);
});
connectRabbit().then(() => {
app.listen(3001, () => console.log('User service on 3001'));
});This Express service exposes a POST endpoint and publishes an event to RabbitMQ after user creation. The connection is established once at startup to avoid resource leaks.
Order Service
import express from 'express';
import amqp from 'amqplib';
const app = express();
app.use(express.json());
let channel: any;
async function connectRabbit() {
const connection = await amqp.connect('amqp://localhost');
channel = await connection.createChannel();
await channel.assertQueue('user_created');
channel.consume('user_created', (msg) => {
if (msg) {
const user = JSON.parse(msg.content.toString());
console.log('Nouvel utilisateur reçu:', user);
channel.ack(msg);
}
});
}
app.post('/orders', (req, res) => {
res.status(201).json({ orderId: Date.now(), userId: req.body.userId });
});
connectRabbit().then(() => {
app.listen(3002, () => console.log('Order service on 3002'));
});The Order service consumes user_created events. Using channel.ack ensures the message is only removed from the queue after successful processing.
User Service Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3001
CMD ["node", "dist/index.js"]Minimal Alpine image to reduce the attack surface. npm ci ensures reproducible production builds.
Docker Compose
version: '3.8'
services:
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
user-service:
build: ./user-service
ports:
- "3001:3001"
depends_on:
- rabbitmq
order-service:
build: ./order-service
ports:
- "3002:3002"
depends_on:
- rabbitmqCompose orchestrates the three containers with explicit dependencies. RabbitMQ also exposes its management interface for debugging.
Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:latest
ports:
- containerPort: 3001Three replicas ensure high availability. The label selector allows a Kubernetes Service to route traffic automatically.
Best Practices
- Use message queues for asynchronous communication to decouple services
- Implement the Circuit Breaker pattern to handle partial failures
- Version your APIs and events
- Centralize logs and metrics with ELK or Prometheus
- Automate contract testing between services
Common Mistakes to Avoid
- Sharing a database between services (creates tight coupling)
- Ignoring duplicate message handling (idempotency is required)
- Forgetting Kubernetes health checks
- Not limiting payload size in message queues
Going Further
Deepen your knowledge of observability and service mesh with Istio in our Learni training courses.