Files
..
2026-01-29 19:05:51 +02:00
2026-01-29 19:05:51 +02:00
2026-01-29 19:05:51 +02:00
2026-01-29 19:05:51 +02:00
2026-01-29 19:05:51 +02:00

Documentatie Stack Node.js + Docker + Docker Compose + Nginx


1. Structura proiect

project/
│
├── Dockerfile             # imaginea Node.js
├── docker-compose.yml     # orchestration containere + Nginx
├── nginx.conf             # configuratie Nginx
├── server.js              # cod Node.js
├── package.json
└── index.html             # pagina servita de Node

Stack-ul include:

  • Node.js aplicatie stateless
  • 3 containere Node, fiecare cu INSTANCE_NAME
  • Nginx reverse proxy si load balancer
  • Docker Compose orchestrare containere + retea

2. Node.js

2.1 server.js

const express = require('express');
const path = require('path');

const instanceName = process.env.INSTANCE_NAME || 'unknown';

const app = express();
const port = 3000;

app.get('/', (req, res) => {
    console.log(`[${instanceName}] Request received`);
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(port, () => {
    console.log(`[${instanceName}] Node app listening on port ${port}`);
});

Explicatii:

  • process.env.INSTANCE_NAME pentru identificarea containerului
  • Stateless design aplicatia nu stie cate instante exista
  • Log-urile arata care container a servit request-ul
  • Servește index.html

2.2 package.json

{
  "name": "node-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

3. Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json .
RUN npm install

COPY index.html .
COPY server.js .

EXPOSE 3000

CMD ["node", "server.js"]

Explicatii:

  • Imagine oficiala Node minimală
  • COPY package*.json pentru caching optim
  • EXPOSE 3000 port intern container
  • CMD comanda de start

4. Docker Compose

version: "3.9"

services:
  app-1:
    image: node-app:v1
    ports:
      - "3001:3000"
    networks:
      - app-network
    environment:
      - INSTANCE_NAME=app-1

  app-2:
    image: node-app:v1
    ports:
      - "3002:3000"
    networks:
      - app-network
    environment:
      - INSTANCE_NAME=app-2

  app-3:
    image: node-app:v1
    ports:
      - "3003:3000"
    networks:
      - app-network
    environment:
      - INSTANCE_NAME=app-3

  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app-1
      - app-2
      - app-3
    ports:
      - "80:80"
    networks:
      - app-network

networks:
  app-network:

Explicatii:

  • 3 servicii Node identice, fiecare pe port intern 3000
  • Nginx ascultă pe port 80 și face proxy la Node
  • depends_on pentru startup order
  • retea comuna

5. Nginx Configuration (nginx.conf)

events {}

http {
    upstream backend {
        server app-1:3000;
        server app-2:3000;
        server app-3:3000;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

Explicatii:

  • upstream backend = grup backend-uri Node pentru load balancing
  • proxy_pass http://backend; trimite request-ul la unul din backends
  • Header-ele ajuta Node sa stie IP-ul real
  • Nginx foloseste portul intern 3000

6. Workflow

  1. Build Node.js:
docker build -t node-app:v1 .
  1. Pornire Compose:
docker-compose up -d
  1. Verificare log-uri:
docker-compose logs -f
  1. Test load balancing:
  • http://localhost
  • Refresh repetat → request-urile distribuite între app-1, app-2, app-3