My first basic loadBalancer
This commit is contained in:
218
files/README.md
Normal file
218
files/README.md
Normal file
@@ -0,0 +1,218 @@
|
||||
### 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
|
||||
|
||||
```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
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "node-app",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. Dockerfile
|
||||
|
||||
```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
|
||||
|
||||
```yaml
|
||||
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)
|
||||
|
||||
```nginx
|
||||
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:
|
||||
|
||||
```bash
|
||||
docker build -t node-app:v1 .
|
||||
```
|
||||
|
||||
2. Pornire Compose:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
3. Verificare log-uri:
|
||||
|
||||
```bash
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
4. Test load balancing:
|
||||
|
||||
* [http://localhost](http://localhost)
|
||||
* Refresh repetat → request-urile distribuite între app-1, app-2, app-3
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user