219 lines
3.6 KiB
Markdown
219 lines
3.6 KiB
Markdown
### 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
|
||
|
||
---
|