ninja-reverse-proxy 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -383
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -1,27 +1,14 @@
|
|
|
1
1
|
# Ninja Reverse Proxy
|
|
2
2
|
|
|
3
|
-
A production-grade, backend-agnostic **Layer 7 Reverse Proxy** built from scratch in
|
|
3
|
+
A production-grade, backend-agnostic **Layer 7 Reverse Proxy** built from scratch in TypeScript and Node.js.
|
|
4
4
|
|
|
5
|
-
Designed in the same philosophy as
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
Developer → GitHub → Jenkins CI/CD → Docker → Any Backend
|
|
9
|
-
```
|
|
5
|
+
Designed in the same philosophy as Nginx, Traefik, and HAProxy — configure it once, point it at any backend, and it handles everything else.
|
|
10
6
|
|
|
11
7
|
---
|
|
12
8
|
|
|
13
|
-
##
|
|
9
|
+
## Works with any HTTP backend
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- Express · Fastify · NestJS
|
|
18
|
-
- Django · FastAPI · Flask
|
|
19
|
-
- Spring Boot · Quarkus
|
|
20
|
-
- Go (net/http, Gin, Echo)
|
|
21
|
-
- ASP.NET Core
|
|
22
|
-
- Kubernetes Services
|
|
23
|
-
- Docker Compose services
|
|
24
|
-
- Any service that speaks HTTP
|
|
11
|
+
Express · Fastify · NestJS · Django · FastAPI · Flask · Spring Boot · Go · ASP.NET Core · Kubernetes Services · Docker Compose services · **Any service that speaks HTTP**
|
|
25
12
|
|
|
26
13
|
The proxy never cares what technology runs behind the URLs. You configure upstreams in `config.yaml` and the proxy routes, balances, caches, rate-limits, and health-checks them automatically.
|
|
27
14
|
|
|
@@ -31,447 +18,165 @@ The proxy never cares what technology runs behind the URLs. You configure upstre
|
|
|
31
18
|
|
|
32
19
|
| Feature | Details |
|
|
33
20
|
|---|---|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
| **Jenkins CI/CD** | Declarative pipeline included |
|
|
49
|
-
| **SonarQube** | `sonar-project.properties` included for static analysis |
|
|
21
|
+
| Cluster Architecture | Master/Worker pattern via Node.js cluster — uses all CPU cores |
|
|
22
|
+
| Round-Robin Load Balancing | Equal request distribution across healthy upstreams |
|
|
23
|
+
| Circuit Breaker | Marks upstreams DOWN after configurable failure threshold |
|
|
24
|
+
| Redis Response Cache | GET response caching with configurable TTL |
|
|
25
|
+
| Per-Route Rate Limiting | Sliding window rate limiter per client IP per route |
|
|
26
|
+
| Service Registry | Backends self-register, deregister, and send heartbeats |
|
|
27
|
+
| Continuous Health Checks | Every 10 seconds — auto-removes and auto-recovers upstreams |
|
|
28
|
+
| HTTPS / TLS Termination | Full SSL at the proxy; all HTTP auto-redirected (301) |
|
|
29
|
+
| Sticky Sessions | Cookie-based session affinity per upstream |
|
|
30
|
+
| Retry Logic | Up to 2 retries on upstream failure, each on a different upstream |
|
|
31
|
+
| Graceful Shutdown | Drains all connections on SIGTERM / SIGINT |
|
|
32
|
+
| Hot Reload | Watches `config.yaml` and `config.d/` — zero-downtime config updates |
|
|
33
|
+
| Admin API | Live stats for load balancer, cache, registry, auto scaler |
|
|
34
|
+
| YAML Configuration | One file, fully validated with Zod — no source code changes needed |
|
|
50
35
|
|
|
51
36
|
---
|
|
52
37
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
┌─────────────────────────────────────────────────┐
|
|
57
|
-
│ Ninja Reverse Proxy │
|
|
58
|
-
│ │
|
|
59
|
-
Client ──HTTPS──► │ Master Process │
|
|
60
|
-
│ ├── Rate Limiter (per-IP, per-route) │
|
|
61
|
-
│ ├── Redis Cache (GET responses) │
|
|
62
|
-
│ ├── Load Balancer (round-robin / ip-hash / …) │
|
|
63
|
-
│ ├── Health Checker (every 10s) │
|
|
64
|
-
│ ├── Service Registry │
|
|
65
|
-
│ └── Auto Scaler (optional) │
|
|
66
|
-
│ │
|
|
67
|
-
│ Worker Processes (one per CPU core) │
|
|
68
|
-
│ └── Forward requests via keepAlive TCP │
|
|
69
|
-
└───────────┬─────────────────────────────────────┘
|
|
70
|
-
│
|
|
71
|
-
┌───────────────┼───────────────┐
|
|
72
|
-
▼ ▼ ▼
|
|
73
|
-
backend-a backend-b backend-c
|
|
74
|
-
(Express) (Django) (Spring Boot)
|
|
75
|
-
```
|
|
38
|
+
## Quick Start
|
|
76
39
|
|
|
77
|
-
###
|
|
40
|
+
### 1. Install globally
|
|
78
41
|
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g ninja-reverse-proxy
|
|
79
44
|
```
|
|
80
|
-
Developer
|
|
81
|
-
│ edits code / config
|
|
82
|
-
▼
|
|
83
|
-
GitHub
|
|
84
|
-
▼
|
|
85
|
-
Jenkins (Jenkinsfile)
|
|
86
|
-
├── Setup (npm ci)
|
|
87
|
-
├── Static Analysis — Lint + npm audit (parallel)
|
|
88
|
-
├── Unit Tests
|
|
89
|
-
├── Build Artifact (tsc)
|
|
90
|
-
└── Deploy to Production (main branch, prod env)
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## Quick Start
|
|
96
45
|
|
|
97
|
-
###
|
|
46
|
+
### 2. Generate TLS certificates
|
|
98
47
|
|
|
99
48
|
```bash
|
|
100
|
-
git clone https://github.com/praveenkumar-co/reverse-proxy.git
|
|
101
|
-
cd reverse-proxy
|
|
102
|
-
|
|
103
|
-
# Generate a self-signed certificate (for development)
|
|
104
49
|
openssl req -x509 -newkey rsa:4096 \
|
|
105
50
|
-keyout key.pem -out cert.pem \
|
|
106
51
|
-days 365 -nodes
|
|
107
52
|
```
|
|
108
53
|
|
|
109
|
-
###
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
cp config.example.yaml config.yaml
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Edit `config.yaml` — replace the example upstreams with your real backend URLs:
|
|
116
|
-
|
|
117
|
-
```yaml
|
|
118
|
-
upstreams:
|
|
119
|
-
- id: my-api
|
|
120
|
-
url: http://my-api:8000
|
|
121
|
-
|
|
122
|
-
- id: my-frontend
|
|
123
|
-
url: http://my-frontend:3000
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 3. Run
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# Proxy + Redis only (you bring your own backends)
|
|
130
|
-
docker-compose up --build
|
|
131
|
-
|
|
132
|
-
# Or run the built-in demo (backend-a + backend-b included)
|
|
133
|
-
cd examples/docker-compose && docker-compose up --build
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### 4. Test
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
curl -k https://localhost:8443/
|
|
140
|
-
curl -k https://localhost:8443/__lb-stats
|
|
141
|
-
curl -k https://localhost:8443/__registry
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## Configuration Reference
|
|
147
|
-
|
|
148
|
-
`config.example.yaml` is the fully commented template. Copy it to `config.yaml` to get started.
|
|
54
|
+
### 3. Create your config file
|
|
149
55
|
|
|
150
56
|
```yaml
|
|
57
|
+
# config.yaml
|
|
151
58
|
server:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
workers: 2 # Set to your CPU core count (run: nproc)
|
|
59
|
+
listen: 8080
|
|
60
|
+
httpsPort: 8443
|
|
61
|
+
workers: 2
|
|
156
62
|
|
|
157
63
|
loadBalancing:
|
|
158
|
-
strategy: round-robin
|
|
159
|
-
failureThreshold: 3
|
|
160
|
-
recoveryTimeMs: 15000
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# true → dynamic server spawning based on load
|
|
165
|
-
minServers: 2
|
|
166
|
-
maxServers: 10
|
|
167
|
-
scaleUpAt: 10 # Spawn a server when connections exceed this
|
|
168
|
-
scaleDownAt: 2 # Kill a server when connections drop below this
|
|
169
|
-
cooldownMs: 60000
|
|
170
|
-
startPort: 9000
|
|
171
|
-
proxyPort: 8080
|
|
172
|
-
|
|
173
|
-
cache:
|
|
174
|
-
enabled: false # true → cache GET responses in Redis
|
|
175
|
-
host: redis
|
|
176
|
-
port: 6379
|
|
177
|
-
ttlSeconds: 60
|
|
64
|
+
strategy: round-robin
|
|
65
|
+
failureThreshold: 3
|
|
66
|
+
recoveryTimeMs: 15000
|
|
67
|
+
retry:
|
|
68
|
+
maxAttempts: 2
|
|
69
|
+
statusCodes: [502, 503, 504]
|
|
178
70
|
|
|
179
71
|
upstreams:
|
|
180
|
-
- id:
|
|
181
|
-
url: http://
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
url: http://backend-b:3002
|
|
72
|
+
- id: my-api
|
|
73
|
+
url: http://localhost:5000
|
|
74
|
+
- id: my-api-2
|
|
75
|
+
url: http://localhost:5001
|
|
185
76
|
|
|
186
77
|
paths:
|
|
187
|
-
- path: /
|
|
188
|
-
upstream:
|
|
189
|
-
- backend-a
|
|
190
|
-
- backend-b
|
|
191
|
-
rateLimit:
|
|
192
|
-
windowMs: 60000 # 1-minute window
|
|
193
|
-
maxRequests: 100000 # per client IP
|
|
194
|
-
|
|
195
|
-
- path: /api # Route /api to a specific backend only
|
|
196
|
-
upstream:
|
|
197
|
-
- backend-a
|
|
78
|
+
- path: /
|
|
79
|
+
upstream: [my-api, my-api-2]
|
|
198
80
|
|
|
199
81
|
headers:
|
|
200
82
|
- key: X-Forwarded-For
|
|
201
83
|
value: client_ip
|
|
202
|
-
- key: X-Real-IP
|
|
203
|
-
value: client_ip
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Docker
|
|
209
84
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
85
|
+
cache:
|
|
86
|
+
enabled: false
|
|
87
|
+
host: redis
|
|
88
|
+
port: 6379
|
|
89
|
+
ttlSeconds: 60
|
|
214
90
|
```
|
|
215
91
|
|
|
216
|
-
###
|
|
92
|
+
### 4. Start the proxy
|
|
217
93
|
|
|
218
94
|
```bash
|
|
219
|
-
|
|
220
|
-
docker-compose up --build
|
|
95
|
+
ninja-proxy --config config.yaml
|
|
221
96
|
```
|
|
222
97
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
### Run the full built-in demo
|
|
98
|
+
### 5. Test it
|
|
226
99
|
|
|
227
100
|
```bash
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
docker-compose up --build
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Connect your real app
|
|
234
|
-
|
|
235
|
-
Add your app as a service in your own `docker-compose.yml` and connect it to the proxy network:
|
|
236
|
-
|
|
237
|
-
```yaml
|
|
238
|
-
services:
|
|
239
|
-
|
|
240
|
-
my-express-app:
|
|
241
|
-
image: my-express-app:latest
|
|
242
|
-
networks:
|
|
243
|
-
- proxy-network
|
|
244
|
-
|
|
245
|
-
networks:
|
|
246
|
-
proxy-network:
|
|
247
|
-
external: true
|
|
248
|
-
name: reverse-proxy_proxy-network
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Then add it to `config.yaml`:
|
|
252
|
-
|
|
253
|
-
```yaml
|
|
254
|
-
upstreams:
|
|
255
|
-
- id: my-express-app
|
|
256
|
-
url: http://my-express-app:3000
|
|
101
|
+
curl -k https://localhost:8443/
|
|
102
|
+
curl -k https://localhost:8443/__lb-stats
|
|
257
103
|
```
|
|
258
104
|
|
|
259
105
|
---
|
|
260
106
|
|
|
261
|
-
##
|
|
262
|
-
|
|
263
|
-
See [`k8s/README.md`](k8s/README.md) for the full deployment guide.
|
|
107
|
+
## Dynamic Service Registry
|
|
264
108
|
|
|
265
|
-
|
|
109
|
+
Backends can self-register at runtime without touching `config.yaml`:
|
|
266
110
|
|
|
267
111
|
```bash
|
|
268
|
-
#
|
|
269
|
-
|
|
112
|
+
# Register a new upstream dynamically
|
|
113
|
+
curl -X POST -H "Content-Type: application/json" \
|
|
114
|
+
-d '{"id":"my-service","url":"http://localhost:3000"}' \
|
|
115
|
+
http://localhost:8080/__registry/register
|
|
270
116
|
|
|
271
|
-
#
|
|
272
|
-
|
|
117
|
+
# Send a heartbeat
|
|
118
|
+
curl -X PUT http://localhost:8080/__registry/heartbeat/my-service
|
|
273
119
|
|
|
274
|
-
#
|
|
275
|
-
curl -
|
|
120
|
+
# Deregister
|
|
121
|
+
curl -X DELETE http://localhost:8080/__registry/deregister/my-service
|
|
276
122
|
```
|
|
277
123
|
|
|
278
|
-
The proxy config is mounted as a Kubernetes ConfigMap — change it without rebuilding the image.
|
|
279
|
-
|
|
280
124
|
---
|
|
281
125
|
|
|
282
|
-
##
|
|
126
|
+
## Multi-Tenant Config (Nginx-style)
|
|
283
127
|
|
|
284
|
-
|
|
128
|
+
Drop extra config files into a `config.d/` folder — the proxy merges them automatically with zero downtime:
|
|
285
129
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
```yaml
|
|
289
|
-
autoScaling:
|
|
290
|
-
enabled: false
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
The proxy uses only the upstream servers listed in `config.yaml`. This is appropriate for production setups where you manage your own backend services.
|
|
294
|
-
|
|
295
|
-
### Dynamic mode
|
|
130
|
+
```bash
|
|
131
|
+
mkdir config.d
|
|
296
132
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
133
|
+
# Each tenant/app gets their own isolated file
|
|
134
|
+
echo "
|
|
135
|
+
server:
|
|
136
|
+
upstreams:
|
|
137
|
+
- id: tenant-a
|
|
138
|
+
url: http://localhost:4000
|
|
139
|
+
paths:
|
|
140
|
+
- path: /tenant-a
|
|
141
|
+
upstream: [tenant-a]
|
|
142
|
+
" > config.d/tenant-a.yaml
|
|
305
143
|
```
|
|
306
144
|
|
|
307
|
-
|
|
145
|
+
The proxy hot-reloads `config.d/` automatically whenever a file is added or changed.
|
|
308
146
|
|
|
309
147
|
---
|
|
310
148
|
|
|
311
149
|
## Admin API
|
|
312
150
|
|
|
313
|
-
All admin endpoints are available on the HTTPS port.
|
|
314
|
-
|
|
315
151
|
| Endpoint | Method | Description |
|
|
316
152
|
|---|---|---|
|
|
317
153
|
| `/__lb-stats` | GET | Load balancer stats + healthy upstreams |
|
|
318
154
|
| `/__cache-stats` | GET | Redis cache hit/miss stats |
|
|
319
155
|
| `/__registry` | GET | All registered services |
|
|
320
|
-
| `/__autoscaler-stats` | GET | Auto scaler status |
|
|
321
156
|
| `/__registry/register` | POST | Register a new upstream |
|
|
322
157
|
| `/__registry/deregister/:id` | DELETE | Deregister an upstream |
|
|
323
158
|
| `/__registry/heartbeat/:id` | PUT | Upstream heartbeat ping |
|
|
324
159
|
|
|
325
|
-
```bash
|
|
326
|
-
curl -k https://localhost:8443/__lb-stats
|
|
327
|
-
curl -k https://localhost:8443/__cache-stats
|
|
328
|
-
curl -k https://localhost:8443/__registry
|
|
329
|
-
curl -k https://localhost:8443/__autoscaler-stats
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## Jenkins CI/CD Pipeline
|
|
335
|
-
|
|
336
|
-
A declarative `Jenkinsfile` is included in the project root.
|
|
337
|
-
|
|
338
|
-
**Pipeline stages:**
|
|
339
|
-
|
|
340
|
-
1. **Setup** — `npm ci` (deterministic install)
|
|
341
|
-
2. **Static Analysis** — Lint + `npm audit` (parallel)
|
|
342
|
-
3. **Unit Tests** — conditional on `RUN_TESTS` parameter
|
|
343
|
-
4. **Build Artifact** — `npm run build` (TypeScript → JavaScript)
|
|
344
|
-
5. **Deploy to Production** — branch `main` + `ENV_TYPE=prod` + manual approval gate
|
|
345
|
-
|
|
346
|
-
**Global options:** 1-hour timeout · last 10 builds retained · no concurrent builds · timestamps on every log line.
|
|
347
|
-
|
|
348
160
|
---
|
|
349
161
|
|
|
350
|
-
##
|
|
351
|
-
|
|
352
|
-
`sonar-project.properties` is included. To run a scan:
|
|
353
|
-
|
|
354
|
-
```bash
|
|
355
|
-
sonar-scanner \
|
|
356
|
-
-Dsonar.host.url=http://localhost:9000 \
|
|
357
|
-
-Dsonar.login=YOUR_SONAR_TOKEN
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
Scans the `src/` directory. Excludes `node_modules/`, `dist/`, certificates, and CI files.
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## Security Scanning (Trivy)
|
|
365
|
-
|
|
366
|
-
```bash
|
|
367
|
-
# Scan dependencies
|
|
368
|
-
trivy fs .
|
|
369
|
-
|
|
370
|
-
# Scan the Docker image
|
|
371
|
-
docker build -t ninja-reverse-proxy:latest .
|
|
372
|
-
trivy image ninja-reverse-proxy:latest
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
## Project Structure
|
|
378
|
-
|
|
379
|
-
```
|
|
380
|
-
ninja-reverse-proxy/
|
|
381
|
-
├── src/ ← Proxy source (TypeScript)
|
|
382
|
-
│ ├── index.ts → CLI entry point
|
|
383
|
-
│ ├── server.ts → Master + Worker proxy engine
|
|
384
|
-
│ ├── loadBalancer.ts → Round-robin with circuit breaker
|
|
385
|
-
│ ├── auto-scaler.ts → Dynamic server scaling
|
|
386
|
-
│ ├── health.ts → Health checker (initial + continuous)
|
|
387
|
-
│ ├── Serviceregistry.ts → Service registry (register/heartbeat/deregister)
|
|
388
|
-
│ ├── cache.ts → Redis cache (get/set/invalidate/stats)
|
|
389
|
-
│ ├── rate-limiter.ts → Sliding window rate limiter
|
|
390
|
-
│ ├── config-schema.ts → Zod config validation schema
|
|
391
|
-
│ ├── config.ts → YAML parser
|
|
392
|
-
│ └── server-schema.ts → Worker IPC message schema
|
|
393
|
-
│
|
|
394
|
-
├── k8s/ ← Kubernetes manifests
|
|
395
|
-
│ ├── configmap.yaml
|
|
396
|
-
│ ├── tls-secret.yaml
|
|
397
|
-
│ ├── proxy-deployment.yaml
|
|
398
|
-
│ ├── proxy-service.yaml
|
|
399
|
-
│ └── README.md
|
|
400
|
-
│
|
|
401
|
-
├── examples/ ← Integration examples (NOT part of the proxy)
|
|
402
|
-
│ ├── docker-compose/ ← Full demo stack (backend-a + backend-b)
|
|
403
|
-
│ │ ├── server-template.js → Minimal demo backend
|
|
404
|
-
│ │ ├── Dockerfile.server → Demo backend image
|
|
405
|
-
│ │ ├── docker-compose.yml → Full demo stack
|
|
406
|
-
│ │ ├── config.yaml → Demo config
|
|
407
|
-
│ │ └── README.md
|
|
408
|
-
│ └── express/ ← Express.js integration example
|
|
409
|
-
│ ├── server.js
|
|
410
|
-
│ └── README.md
|
|
411
|
-
│
|
|
412
|
-
├── Dockerfile ← Proxy image (multi-stage build)
|
|
413
|
-
├── Jenkinsfile ← CI/CD declarative pipeline
|
|
414
|
-
├── sonar-project.properties ← SonarQube config
|
|
415
|
-
├── docker-compose.yml ← Proxy + Redis only
|
|
416
|
-
├── config.example.yaml ← Fully commented configuration template
|
|
417
|
-
├── .dockerignore
|
|
418
|
-
├── .gitignore
|
|
419
|
-
├── package.json
|
|
420
|
-
├── tsconfig.json
|
|
421
|
-
└── README.md
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
---
|
|
425
|
-
|
|
426
|
-
## Tech Stack
|
|
427
|
-
|
|
428
|
-
| Technology | Purpose |
|
|
429
|
-
|---|---|
|
|
430
|
-
| TypeScript | Full type safety |
|
|
431
|
-
| Node.js Cluster | Master/Worker multi-process architecture |
|
|
432
|
-
| Redis | Response caching |
|
|
433
|
-
| Zod | Schema validation for config and worker messages |
|
|
434
|
-
| YAML | Human-readable configuration |
|
|
435
|
-
| Commander | CLI entry point |
|
|
436
|
-
| Docker Compose | Orchestration |
|
|
437
|
-
| Kubernetes | Production cluster deployment |
|
|
438
|
-
| Jenkins | CI/CD pipeline |
|
|
439
|
-
| SonarQube | Static code analysis |
|
|
440
|
-
| Trivy | Container security scanning |
|
|
441
|
-
|
|
442
|
-
---
|
|
443
|
-
|
|
444
|
-
## Request Lifecycle
|
|
445
|
-
|
|
446
|
-
```
|
|
447
|
-
Client → :8080 HTTP → 301 redirect to HTTPS
|
|
448
|
-
Client → :8443 HTTPS
|
|
449
|
-
1. Rate limiter checks client IP — 429 if exceeded
|
|
450
|
-
2. GET requests → Redis cache checked — HIT returns instantly
|
|
451
|
-
3. Write requests (POST/PUT/PATCH/DELETE) → cache invalidated
|
|
452
|
-
4. Request body assembled from chunks
|
|
453
|
-
5. Load balancer picks a healthy upstream
|
|
454
|
-
6. Worker process forwards request over keepAlive TCP
|
|
455
|
-
7. Upstream responds → reply sent back via IPC
|
|
456
|
-
8. Master sends response to client + caches (GET)
|
|
457
|
-
9. On failure → circuit breaker records it, retry up to 2 times
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
---
|
|
461
|
-
|
|
462
|
-
## Performance Tips
|
|
162
|
+
## Configuration Reference
|
|
463
163
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
164
|
+
| Field | Default | Description |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| `server.listen` | `8080` | HTTP port — redirects all traffic to HTTPS |
|
|
167
|
+
| `server.httpsPort` | `8443` | HTTPS port — main entry point |
|
|
168
|
+
| `server.workers` | `2` | Set to your CPU core count |
|
|
169
|
+
| `loadBalancing.strategy` | `round-robin` | `round-robin` \| `least-connections` \| `ip-hash` \| `random` |
|
|
170
|
+
| `loadBalancing.failureThreshold` | `3` | Mark upstream DOWN after N consecutive failures |
|
|
171
|
+
| `loadBalancing.recoveryTimeMs` | `15000` | Retry a DOWN upstream after N ms |
|
|
172
|
+
| `cache.enabled` | `false` | Enable Redis GET response caching |
|
|
173
|
+
| `cache.ttlSeconds` | `60` | Cache TTL in seconds |
|
|
469
174
|
|
|
470
175
|
---
|
|
471
176
|
|
|
472
|
-
##
|
|
177
|
+
## Repository
|
|
473
178
|
|
|
474
|
-
|
|
179
|
+
[github.com/praveenkumar-co/reverse-proxy](https://github.com/praveenkumar-co/reverse-proxy)
|
|
475
180
|
|
|
476
181
|
---
|
|
477
182
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ninja-reverse-proxy",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A production-grade reverse proxy with load balancing, circuit breaker, sticky sessions, and dynamic service registry.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,7 +13,16 @@
|
|
|
13
13
|
"dev": "tsc-watch --onSuccess \"node dist/index.js --config config.yaml\"",
|
|
14
14
|
"test": "tsc -p tsconfig.test.json && node --test dist-test/test"
|
|
15
15
|
},
|
|
16
|
-
"keywords": [
|
|
16
|
+
"keywords": [
|
|
17
|
+
"reverse-proxy",
|
|
18
|
+
"load-balancer",
|
|
19
|
+
"circuit-breaker",
|
|
20
|
+
"nginx",
|
|
21
|
+
"gateway",
|
|
22
|
+
"sticky-session",
|
|
23
|
+
"rate-limiter",
|
|
24
|
+
"proxy"
|
|
25
|
+
],
|
|
17
26
|
"author": "praveenkumar-co",
|
|
18
27
|
"license": "ISC",
|
|
19
28
|
"repository": {
|
|
@@ -29,10 +38,7 @@
|
|
|
29
38
|
},
|
|
30
39
|
"dependencies": {
|
|
31
40
|
"commander": "^14.0.3",
|
|
32
|
-
"express": "^5.2.1",
|
|
33
|
-
"node-utils-kit": "^1.2.4",
|
|
34
41
|
"redis": "^5.11.0",
|
|
35
|
-
"scalable-bloom-kit": "^1.0.6",
|
|
36
42
|
"yaml": "^2.8.2",
|
|
37
43
|
"zod": "^4.3.6"
|
|
38
44
|
}
|