@ruvector/edge-net 0.4.1 → 0.4.3
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/deploy/.env.example +97 -0
- package/deploy/DEPLOY.md +481 -0
- package/deploy/Dockerfile +99 -0
- package/deploy/docker-compose.yml +162 -0
- package/deploy/genesis-prod.js +1536 -0
- package/deploy/health-check.js +187 -0
- package/deploy/prometheus.yml +38 -0
- package/firebase-signaling.js +242 -53
- package/package.json +19 -3
- package/real-workers.js +9 -4
- package/scheduler.js +8 -4
- package/secure-access.js +595 -0
- package/tests/distributed-workers-test.js +1609 -0
- package/tests/p2p-migration-test.js +1102 -0
- package/tests/webrtc-peer-test.js +686 -0
- package/webrtc.js +727 -50
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @ruvector/edge-net Genesis Node - Environment Configuration
|
|
2
|
+
#
|
|
3
|
+
# Copy this file to .env and customize for your deployment.
|
|
4
|
+
# These variables override the defaults in genesis-prod.js
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# cp deploy/.env.example deploy/.env
|
|
8
|
+
# # Edit deploy/.env with your values
|
|
9
|
+
# docker-compose -f deploy/docker-compose.yml --env-file deploy/.env up -d
|
|
10
|
+
|
|
11
|
+
# ============================================
|
|
12
|
+
# Network Configuration
|
|
13
|
+
# ============================================
|
|
14
|
+
|
|
15
|
+
# WebSocket port for peer connections
|
|
16
|
+
GENESIS_PORT=8787
|
|
17
|
+
|
|
18
|
+
# Bind address (0.0.0.0 for all interfaces)
|
|
19
|
+
GENESIS_HOST=0.0.0.0
|
|
20
|
+
|
|
21
|
+
# Health check and metrics HTTP port
|
|
22
|
+
HEALTH_PORT=8788
|
|
23
|
+
|
|
24
|
+
# ============================================
|
|
25
|
+
# Storage Configuration
|
|
26
|
+
# ============================================
|
|
27
|
+
|
|
28
|
+
# Data directory for ledger persistence
|
|
29
|
+
# In Docker, this maps to a volume
|
|
30
|
+
GENESIS_DATA=/data/genesis
|
|
31
|
+
|
|
32
|
+
# Fixed node ID (optional)
|
|
33
|
+
# Leave empty for auto-generated ID
|
|
34
|
+
# Set for persistent identity across restarts
|
|
35
|
+
# GENESIS_NODE_ID=your-fixed-node-id-here
|
|
36
|
+
|
|
37
|
+
# ============================================
|
|
38
|
+
# Logging Configuration
|
|
39
|
+
# ============================================
|
|
40
|
+
|
|
41
|
+
# Log level: debug, info, warn, error
|
|
42
|
+
LOG_LEVEL=info
|
|
43
|
+
|
|
44
|
+
# Log format: json (structured), text (human-readable)
|
|
45
|
+
LOG_FORMAT=json
|
|
46
|
+
|
|
47
|
+
# ============================================
|
|
48
|
+
# Rate Limiting
|
|
49
|
+
# ============================================
|
|
50
|
+
|
|
51
|
+
# Maximum connections per IP address
|
|
52
|
+
MAX_CONN_PER_IP=50
|
|
53
|
+
|
|
54
|
+
# Maximum messages per second per connection
|
|
55
|
+
MAX_MSG_PER_SEC=100
|
|
56
|
+
|
|
57
|
+
# ============================================
|
|
58
|
+
# Monitoring
|
|
59
|
+
# ============================================
|
|
60
|
+
|
|
61
|
+
# Enable Prometheus metrics at /metrics endpoint
|
|
62
|
+
METRICS_ENABLED=true
|
|
63
|
+
|
|
64
|
+
# ============================================
|
|
65
|
+
# Firebase Bootstrap Registration (Optional)
|
|
66
|
+
# ============================================
|
|
67
|
+
# Set these to register your genesis node in Firebase
|
|
68
|
+
# for automatic discovery by edge-net clients.
|
|
69
|
+
#
|
|
70
|
+
# Get credentials from Firebase Console:
|
|
71
|
+
# https://console.firebase.google.com/
|
|
72
|
+
#
|
|
73
|
+
# FIREBASE_API_KEY=your-api-key
|
|
74
|
+
# FIREBASE_PROJECT_ID=your-project-id
|
|
75
|
+
# FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
|
|
76
|
+
|
|
77
|
+
# ============================================
|
|
78
|
+
# TLS/SSL (for reverse proxy setup)
|
|
79
|
+
# ============================================
|
|
80
|
+
# These are used when running behind nginx/traefik
|
|
81
|
+
#
|
|
82
|
+
# VIRTUAL_HOST=genesis.yourdomain.com
|
|
83
|
+
# LETSENCRYPT_HOST=genesis.yourdomain.com
|
|
84
|
+
# LETSENCRYPT_EMAIL=admin@yourdomain.com
|
|
85
|
+
|
|
86
|
+
# ============================================
|
|
87
|
+
# Cloud Platform Specific
|
|
88
|
+
# ============================================
|
|
89
|
+
|
|
90
|
+
# Google Cloud Run
|
|
91
|
+
# CLOUD_RUN_INSTANCE_CONNECTION_LIMIT=100
|
|
92
|
+
|
|
93
|
+
# AWS ECS
|
|
94
|
+
# AWS_REGION=us-east-1
|
|
95
|
+
|
|
96
|
+
# Azure Container Instances
|
|
97
|
+
# AZURE_CONTAINER_GROUP=edge-net-genesis
|
package/deploy/DEPLOY.md
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# Edge-Net Genesis Node Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide covers deploying the Edge-Net Genesis bootstrap node to various platforms.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Local Development
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Run directly with Node.js
|
|
11
|
+
npm run genesis:prod
|
|
12
|
+
|
|
13
|
+
# Or with Docker
|
|
14
|
+
npm run genesis:docker
|
|
15
|
+
npm run genesis:docker:logs
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Production Deployment
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Build the Docker image
|
|
22
|
+
npm run genesis:docker:build
|
|
23
|
+
|
|
24
|
+
# Push to your registry
|
|
25
|
+
docker tag ruvector/edge-net-genesis:latest your-registry/edge-net-genesis:latest
|
|
26
|
+
docker push your-registry/edge-net-genesis:latest
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
The Genesis Node provides:
|
|
32
|
+
|
|
33
|
+
1. **WebSocket Signaling** (port 8787) - WebRTC connection establishment
|
|
34
|
+
2. **DHT Routing** - Kademlia-based peer discovery
|
|
35
|
+
3. **Ledger Sync** - CRDT-based state synchronization
|
|
36
|
+
4. **Firebase Registration** - Optional bootstrap node discovery
|
|
37
|
+
5. **Health Endpoints** (port 8788) - Kubernetes-compatible probes
|
|
38
|
+
6. **Prometheus Metrics** - Observable monitoring
|
|
39
|
+
|
|
40
|
+
## Configuration
|
|
41
|
+
|
|
42
|
+
### Environment Variables
|
|
43
|
+
|
|
44
|
+
| Variable | Default | Description |
|
|
45
|
+
|----------|---------|-------------|
|
|
46
|
+
| `GENESIS_PORT` | 8787 | WebSocket signaling port |
|
|
47
|
+
| `GENESIS_HOST` | 0.0.0.0 | Bind address |
|
|
48
|
+
| `HEALTH_PORT` | 8788 | Health check/metrics port |
|
|
49
|
+
| `GENESIS_DATA` | /data/genesis | Persistent data directory |
|
|
50
|
+
| `GENESIS_NODE_ID` | (auto) | Fixed node ID for persistence |
|
|
51
|
+
| `LOG_LEVEL` | info | Log verbosity: debug, info, warn, error |
|
|
52
|
+
| `LOG_FORMAT` | json | Log format: json, text |
|
|
53
|
+
| `METRICS_ENABLED` | true | Enable Prometheus metrics |
|
|
54
|
+
| `MAX_CONN_PER_IP` | 50 | Rate limit: connections per IP |
|
|
55
|
+
| `MAX_MSG_PER_SEC` | 100 | Rate limit: messages per second |
|
|
56
|
+
| `FIREBASE_API_KEY` | - | Firebase API key (optional) |
|
|
57
|
+
| `FIREBASE_PROJECT_ID` | - | Firebase project ID (optional) |
|
|
58
|
+
|
|
59
|
+
### Using .env File
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cp deploy/.env.example deploy/.env
|
|
63
|
+
# Edit deploy/.env with your values
|
|
64
|
+
docker-compose -f deploy/docker-compose.yml --env-file deploy/.env up -d
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Deployment Platforms
|
|
68
|
+
|
|
69
|
+
### Docker Standalone
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Build
|
|
73
|
+
docker build -t ruvector/edge-net-genesis:latest -f deploy/Dockerfile .
|
|
74
|
+
|
|
75
|
+
# Run
|
|
76
|
+
docker run -d \
|
|
77
|
+
--name edge-net-genesis \
|
|
78
|
+
-p 8787:8787 \
|
|
79
|
+
-p 8788:8788 \
|
|
80
|
+
-v genesis-data:/data/genesis \
|
|
81
|
+
-e LOG_LEVEL=info \
|
|
82
|
+
ruvector/edge-net-genesis:latest
|
|
83
|
+
|
|
84
|
+
# View logs
|
|
85
|
+
docker logs -f edge-net-genesis
|
|
86
|
+
|
|
87
|
+
# Check health
|
|
88
|
+
curl http://localhost:8788/health
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Docker Compose
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Start single node
|
|
95
|
+
docker-compose -f deploy/docker-compose.yml up -d
|
|
96
|
+
|
|
97
|
+
# Start cluster (2 nodes)
|
|
98
|
+
docker-compose -f deploy/docker-compose.yml --profile cluster up -d
|
|
99
|
+
|
|
100
|
+
# Start with monitoring (Prometheus + Grafana)
|
|
101
|
+
docker-compose -f deploy/docker-compose.yml --profile monitoring up -d
|
|
102
|
+
|
|
103
|
+
# View logs
|
|
104
|
+
docker-compose -f deploy/docker-compose.yml logs -f
|
|
105
|
+
|
|
106
|
+
# Stop
|
|
107
|
+
docker-compose -f deploy/docker-compose.yml down
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Kubernetes
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
# genesis-deployment.yaml
|
|
114
|
+
apiVersion: apps/v1
|
|
115
|
+
kind: Deployment
|
|
116
|
+
metadata:
|
|
117
|
+
name: edge-net-genesis
|
|
118
|
+
labels:
|
|
119
|
+
app: edge-net-genesis
|
|
120
|
+
spec:
|
|
121
|
+
replicas: 2
|
|
122
|
+
selector:
|
|
123
|
+
matchLabels:
|
|
124
|
+
app: edge-net-genesis
|
|
125
|
+
template:
|
|
126
|
+
metadata:
|
|
127
|
+
labels:
|
|
128
|
+
app: edge-net-genesis
|
|
129
|
+
spec:
|
|
130
|
+
containers:
|
|
131
|
+
- name: genesis
|
|
132
|
+
image: ruvector/edge-net-genesis:latest
|
|
133
|
+
ports:
|
|
134
|
+
- containerPort: 8787
|
|
135
|
+
name: websocket
|
|
136
|
+
- containerPort: 8788
|
|
137
|
+
name: health
|
|
138
|
+
env:
|
|
139
|
+
- name: LOG_FORMAT
|
|
140
|
+
value: "json"
|
|
141
|
+
- name: LOG_LEVEL
|
|
142
|
+
value: "info"
|
|
143
|
+
resources:
|
|
144
|
+
requests:
|
|
145
|
+
memory: "128Mi"
|
|
146
|
+
cpu: "100m"
|
|
147
|
+
limits:
|
|
148
|
+
memory: "512Mi"
|
|
149
|
+
cpu: "500m"
|
|
150
|
+
livenessProbe:
|
|
151
|
+
httpGet:
|
|
152
|
+
path: /health
|
|
153
|
+
port: 8788
|
|
154
|
+
initialDelaySeconds: 10
|
|
155
|
+
periodSeconds: 30
|
|
156
|
+
readinessProbe:
|
|
157
|
+
httpGet:
|
|
158
|
+
path: /ready
|
|
159
|
+
port: 8788
|
|
160
|
+
initialDelaySeconds: 5
|
|
161
|
+
periodSeconds: 10
|
|
162
|
+
volumeMounts:
|
|
163
|
+
- name: genesis-data
|
|
164
|
+
mountPath: /data/genesis
|
|
165
|
+
volumes:
|
|
166
|
+
- name: genesis-data
|
|
167
|
+
persistentVolumeClaim:
|
|
168
|
+
claimName: genesis-pvc
|
|
169
|
+
---
|
|
170
|
+
apiVersion: v1
|
|
171
|
+
kind: Service
|
|
172
|
+
metadata:
|
|
173
|
+
name: edge-net-genesis
|
|
174
|
+
spec:
|
|
175
|
+
selector:
|
|
176
|
+
app: edge-net-genesis
|
|
177
|
+
ports:
|
|
178
|
+
- name: websocket
|
|
179
|
+
port: 8787
|
|
180
|
+
targetPort: 8787
|
|
181
|
+
- name: health
|
|
182
|
+
port: 8788
|
|
183
|
+
targetPort: 8788
|
|
184
|
+
type: LoadBalancer
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Google Cloud Run
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Build and push
|
|
191
|
+
gcloud builds submit --tag gcr.io/PROJECT_ID/edge-net-genesis
|
|
192
|
+
|
|
193
|
+
# Deploy
|
|
194
|
+
gcloud run deploy edge-net-genesis \
|
|
195
|
+
--image gcr.io/PROJECT_ID/edge-net-genesis \
|
|
196
|
+
--platform managed \
|
|
197
|
+
--region us-central1 \
|
|
198
|
+
--port 8787 \
|
|
199
|
+
--memory 512Mi \
|
|
200
|
+
--min-instances 1 \
|
|
201
|
+
--max-instances 10 \
|
|
202
|
+
--allow-unauthenticated
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### AWS ECS (Fargate)
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"family": "edge-net-genesis",
|
|
210
|
+
"networkMode": "awsvpc",
|
|
211
|
+
"requiresCompatibilities": ["FARGATE"],
|
|
212
|
+
"cpu": "256",
|
|
213
|
+
"memory": "512",
|
|
214
|
+
"containerDefinitions": [{
|
|
215
|
+
"name": "genesis",
|
|
216
|
+
"image": "your-ecr-repo/edge-net-genesis:latest",
|
|
217
|
+
"portMappings": [
|
|
218
|
+
{"containerPort": 8787, "protocol": "tcp"},
|
|
219
|
+
{"containerPort": 8788, "protocol": "tcp"}
|
|
220
|
+
],
|
|
221
|
+
"environment": [
|
|
222
|
+
{"name": "LOG_FORMAT", "value": "json"},
|
|
223
|
+
{"name": "LOG_LEVEL", "value": "info"}
|
|
224
|
+
],
|
|
225
|
+
"healthCheck": {
|
|
226
|
+
"command": ["CMD-SHELL", "curl -f http://localhost:8788/health || exit 1"],
|
|
227
|
+
"interval": 30,
|
|
228
|
+
"timeout": 10,
|
|
229
|
+
"retries": 3
|
|
230
|
+
},
|
|
231
|
+
"logConfiguration": {
|
|
232
|
+
"logDriver": "awslogs",
|
|
233
|
+
"options": {
|
|
234
|
+
"awslogs-group": "/ecs/edge-net-genesis",
|
|
235
|
+
"awslogs-region": "us-east-1",
|
|
236
|
+
"awslogs-stream-prefix": "genesis"
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}]
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Fly.io
|
|
244
|
+
|
|
245
|
+
```toml
|
|
246
|
+
# fly.toml
|
|
247
|
+
app = "edge-net-genesis"
|
|
248
|
+
|
|
249
|
+
[build]
|
|
250
|
+
dockerfile = "deploy/Dockerfile"
|
|
251
|
+
|
|
252
|
+
[env]
|
|
253
|
+
LOG_FORMAT = "json"
|
|
254
|
+
LOG_LEVEL = "info"
|
|
255
|
+
|
|
256
|
+
[[services]]
|
|
257
|
+
internal_port = 8787
|
|
258
|
+
protocol = "tcp"
|
|
259
|
+
|
|
260
|
+
[[services.ports]]
|
|
261
|
+
handlers = ["tls", "http"]
|
|
262
|
+
port = 443
|
|
263
|
+
|
|
264
|
+
[[services.ports]]
|
|
265
|
+
handlers = ["http"]
|
|
266
|
+
port = 80
|
|
267
|
+
|
|
268
|
+
[[services]]
|
|
269
|
+
internal_port = 8788
|
|
270
|
+
protocol = "tcp"
|
|
271
|
+
|
|
272
|
+
[[services.tcp_checks]]
|
|
273
|
+
grace_period = "5s"
|
|
274
|
+
interval = "30s"
|
|
275
|
+
restart_limit = 3
|
|
276
|
+
timeout = "10s"
|
|
277
|
+
|
|
278
|
+
[mounts]
|
|
279
|
+
source = "genesis_data"
|
|
280
|
+
destination = "/data/genesis"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
fly launch
|
|
285
|
+
fly deploy
|
|
286
|
+
fly scale count 2
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Railway
|
|
290
|
+
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"build": {
|
|
294
|
+
"dockerfilePath": "deploy/Dockerfile"
|
|
295
|
+
},
|
|
296
|
+
"deploy": {
|
|
297
|
+
"startCommand": "node deploy/genesis-prod.js",
|
|
298
|
+
"healthcheckPath": "/health",
|
|
299
|
+
"healthcheckTimeout": 10
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### DigitalOcean App Platform
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
# .do/app.yaml
|
|
308
|
+
name: edge-net-genesis
|
|
309
|
+
services:
|
|
310
|
+
- name: genesis
|
|
311
|
+
dockerfile_path: deploy/Dockerfile
|
|
312
|
+
http_port: 8788
|
|
313
|
+
instance_count: 2
|
|
314
|
+
instance_size_slug: basic-xxs
|
|
315
|
+
envs:
|
|
316
|
+
- key: LOG_FORMAT
|
|
317
|
+
value: "json"
|
|
318
|
+
health_check:
|
|
319
|
+
http_path: /health
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Monitoring
|
|
323
|
+
|
|
324
|
+
### Health Endpoints
|
|
325
|
+
|
|
326
|
+
| Endpoint | Description |
|
|
327
|
+
|----------|-------------|
|
|
328
|
+
| `GET /health` | Basic liveness check |
|
|
329
|
+
| `GET /ready` | Readiness check (WebSocket accepting connections) |
|
|
330
|
+
| `GET /status` | Detailed status JSON |
|
|
331
|
+
| `GET /metrics` | Prometheus metrics |
|
|
332
|
+
|
|
333
|
+
### Example Health Check
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
# Basic health
|
|
337
|
+
curl http://localhost:8788/health
|
|
338
|
+
# {"status":"healthy","timestamp":1704067200000}
|
|
339
|
+
|
|
340
|
+
# Readiness
|
|
341
|
+
curl http://localhost:8788/ready
|
|
342
|
+
# {"ready":true,"timestamp":1704067200000}
|
|
343
|
+
|
|
344
|
+
# Full status
|
|
345
|
+
curl http://localhost:8788/status
|
|
346
|
+
# {
|
|
347
|
+
# "nodeId": "abc123...",
|
|
348
|
+
# "isRunning": true,
|
|
349
|
+
# "uptime": 3600000,
|
|
350
|
+
# "connections": 42,
|
|
351
|
+
# "peers": {"total": 150, "rooms": 3},
|
|
352
|
+
# ...
|
|
353
|
+
# }
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Prometheus Metrics
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
# HELP genesis_connections_total Total WebSocket connections
|
|
360
|
+
# TYPE genesis_connections_total counter
|
|
361
|
+
genesis_connections_total 1523
|
|
362
|
+
|
|
363
|
+
# HELP genesis_peers_registered Current registered peers
|
|
364
|
+
# TYPE genesis_peers_registered gauge
|
|
365
|
+
genesis_peers_registered 42
|
|
366
|
+
|
|
367
|
+
# HELP genesis_signals_relayed WebRTC signals relayed
|
|
368
|
+
# TYPE genesis_signals_relayed counter
|
|
369
|
+
genesis_signals_relayed 8432
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Grafana Dashboard
|
|
373
|
+
|
|
374
|
+
Import the Prometheus data source and create dashboards for:
|
|
375
|
+
- Connection rate and active connections
|
|
376
|
+
- Peer registration and churn
|
|
377
|
+
- Signal relay latency
|
|
378
|
+
- DHT routing table size
|
|
379
|
+
- Error rates
|
|
380
|
+
|
|
381
|
+
## Security Considerations
|
|
382
|
+
|
|
383
|
+
1. **Rate Limiting** - Built-in protection against connection/message floods
|
|
384
|
+
2. **Non-root User** - Container runs as unprivileged user
|
|
385
|
+
3. **Network Isolation** - Use private networks where possible
|
|
386
|
+
4. **TLS Termination** - Use a reverse proxy (nginx, traefik) for TLS
|
|
387
|
+
5. **Firebase Rules** - If using Firebase, configure security rules
|
|
388
|
+
|
|
389
|
+
### TLS with Nginx
|
|
390
|
+
|
|
391
|
+
```nginx
|
|
392
|
+
upstream genesis {
|
|
393
|
+
server localhost:8787;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
server {
|
|
397
|
+
listen 443 ssl;
|
|
398
|
+
server_name genesis.yourdomain.com;
|
|
399
|
+
|
|
400
|
+
ssl_certificate /etc/letsencrypt/live/genesis.yourdomain.com/fullchain.pem;
|
|
401
|
+
ssl_certificate_key /etc/letsencrypt/live/genesis.yourdomain.com/privkey.pem;
|
|
402
|
+
|
|
403
|
+
location / {
|
|
404
|
+
proxy_pass http://genesis;
|
|
405
|
+
proxy_http_version 1.1;
|
|
406
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
407
|
+
proxy_set_header Connection "upgrade";
|
|
408
|
+
proxy_set_header Host $host;
|
|
409
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
410
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
411
|
+
proxy_read_timeout 86400;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Scaling
|
|
417
|
+
|
|
418
|
+
### Horizontal Scaling
|
|
419
|
+
|
|
420
|
+
Genesis nodes can run in parallel. Peers will discover each other through:
|
|
421
|
+
1. Firebase bootstrap registration (if enabled)
|
|
422
|
+
2. DHT peer exchange
|
|
423
|
+
3. Direct peer-to-peer connections
|
|
424
|
+
|
|
425
|
+
### Load Balancing
|
|
426
|
+
|
|
427
|
+
For WebSocket, use sticky sessions or connection-aware load balancing:
|
|
428
|
+
|
|
429
|
+
```nginx
|
|
430
|
+
upstream genesis_cluster {
|
|
431
|
+
ip_hash; # Sticky sessions by IP
|
|
432
|
+
server genesis-1:8787;
|
|
433
|
+
server genesis-2:8787;
|
|
434
|
+
server genesis-3:8787;
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Troubleshooting
|
|
439
|
+
|
|
440
|
+
### Common Issues
|
|
441
|
+
|
|
442
|
+
1. **Connection refused**
|
|
443
|
+
- Check firewall rules for ports 8787 and 8788
|
|
444
|
+
- Verify container is running: `docker ps`
|
|
445
|
+
|
|
446
|
+
2. **WebSocket upgrade failed**
|
|
447
|
+
- Ensure proxy supports WebSocket upgrade
|
|
448
|
+
- Check `Connection: upgrade` header is passed
|
|
449
|
+
|
|
450
|
+
3. **High memory usage**
|
|
451
|
+
- Reduce `MAX_CONN_PER_IP` limit
|
|
452
|
+
- Enable peer pruning (default: 5 min timeout)
|
|
453
|
+
|
|
454
|
+
4. **Peers not discovering each other**
|
|
455
|
+
- Verify Firebase credentials if using bootstrap registration
|
|
456
|
+
- Check network connectivity between nodes
|
|
457
|
+
|
|
458
|
+
### Debug Mode
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Run with debug logging
|
|
462
|
+
LOG_LEVEL=debug npm run genesis:prod
|
|
463
|
+
|
|
464
|
+
# Or in Docker
|
|
465
|
+
docker run -e LOG_LEVEL=debug ruvector/edge-net-genesis:latest
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Health Check Script
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# Use the included health check script
|
|
472
|
+
node deploy/health-check.js --host localhost --port 8788
|
|
473
|
+
|
|
474
|
+
# JSON output for automation
|
|
475
|
+
node deploy/health-check.js --json
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Support
|
|
479
|
+
|
|
480
|
+
- GitHub Issues: https://github.com/ruvnet/ruvector/issues
|
|
481
|
+
- Documentation: https://github.com/ruvnet/ruvector/tree/main/examples/edge-net
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @ruvector/edge-net Genesis Node - Production Dockerfile
|
|
2
|
+
#
|
|
3
|
+
# Multi-stage build for minimal production image
|
|
4
|
+
# Supports: Docker, Kubernetes, Cloud Run, AWS ECS, Azure Container Instances
|
|
5
|
+
#
|
|
6
|
+
# Build:
|
|
7
|
+
# docker build -t ruvector/edge-net-genesis:latest -f deploy/Dockerfile .
|
|
8
|
+
#
|
|
9
|
+
# Run:
|
|
10
|
+
# docker run -p 8787:8787 -p 8788:8788 ruvector/edge-net-genesis:latest
|
|
11
|
+
|
|
12
|
+
# ============================================
|
|
13
|
+
# Stage 1: Dependencies
|
|
14
|
+
# ============================================
|
|
15
|
+
FROM node:20-alpine AS deps
|
|
16
|
+
|
|
17
|
+
WORKDIR /app
|
|
18
|
+
|
|
19
|
+
# Install build dependencies for native modules
|
|
20
|
+
RUN apk add --no-cache python3 make g++ linux-headers
|
|
21
|
+
|
|
22
|
+
# Copy package files
|
|
23
|
+
COPY package.json package-lock.json* ./
|
|
24
|
+
|
|
25
|
+
# Install production dependencies only
|
|
26
|
+
RUN npm ci --only=production --ignore-scripts 2>/dev/null || npm install --only=production --ignore-scripts
|
|
27
|
+
|
|
28
|
+
# ============================================
|
|
29
|
+
# Stage 2: Production Runtime
|
|
30
|
+
# ============================================
|
|
31
|
+
FROM node:20-alpine AS runner
|
|
32
|
+
|
|
33
|
+
# Security: Run as non-root user
|
|
34
|
+
RUN addgroup -g 1001 -S nodejs && \
|
|
35
|
+
adduser -S edgenet -u 1001 -G nodejs
|
|
36
|
+
|
|
37
|
+
WORKDIR /app
|
|
38
|
+
|
|
39
|
+
# Install runtime dependencies
|
|
40
|
+
RUN apk add --no-cache \
|
|
41
|
+
tini \
|
|
42
|
+
dumb-init \
|
|
43
|
+
curl
|
|
44
|
+
|
|
45
|
+
# Copy node_modules from deps stage
|
|
46
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
47
|
+
|
|
48
|
+
# Copy application files
|
|
49
|
+
COPY package.json ./
|
|
50
|
+
COPY *.js ./
|
|
51
|
+
COPY *.d.ts ./
|
|
52
|
+
COPY *.wasm ./
|
|
53
|
+
COPY node/ ./node/
|
|
54
|
+
COPY deploy/genesis-prod.js ./deploy/
|
|
55
|
+
|
|
56
|
+
# Create data directory with correct permissions
|
|
57
|
+
RUN mkdir -p /data/genesis && \
|
|
58
|
+
chown -R edgenet:nodejs /data/genesis && \
|
|
59
|
+
chmod 755 /data/genesis
|
|
60
|
+
|
|
61
|
+
# Set environment variables
|
|
62
|
+
ENV NODE_ENV=production
|
|
63
|
+
ENV GENESIS_PORT=8787
|
|
64
|
+
ENV GENESIS_HOST=0.0.0.0
|
|
65
|
+
ENV HEALTH_PORT=8788
|
|
66
|
+
ENV GENESIS_DATA=/data/genesis
|
|
67
|
+
ENV LOG_FORMAT=json
|
|
68
|
+
ENV LOG_LEVEL=info
|
|
69
|
+
ENV METRICS_ENABLED=true
|
|
70
|
+
|
|
71
|
+
# Expose ports
|
|
72
|
+
# 8787: WebSocket signaling
|
|
73
|
+
# 8788: Health check / metrics
|
|
74
|
+
EXPOSE 8787
|
|
75
|
+
EXPOSE 8788
|
|
76
|
+
|
|
77
|
+
# Health check
|
|
78
|
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
79
|
+
CMD curl -f http://localhost:8788/health || exit 1
|
|
80
|
+
|
|
81
|
+
# Switch to non-root user
|
|
82
|
+
USER edgenet
|
|
83
|
+
|
|
84
|
+
# Use tini as init system for proper signal handling
|
|
85
|
+
ENTRYPOINT ["/sbin/tini", "--"]
|
|
86
|
+
|
|
87
|
+
# Start the genesis node
|
|
88
|
+
CMD ["node", "deploy/genesis-prod.js"]
|
|
89
|
+
|
|
90
|
+
# ============================================
|
|
91
|
+
# Labels for container registry
|
|
92
|
+
# ============================================
|
|
93
|
+
LABEL org.opencontainers.image.title="Edge-Net Genesis Node"
|
|
94
|
+
LABEL org.opencontainers.image.description="Bootstrap node for the RuVector Edge-Net P2P network"
|
|
95
|
+
LABEL org.opencontainers.image.vendor="RuVector"
|
|
96
|
+
LABEL org.opencontainers.image.url="https://github.com/ruvnet/ruvector"
|
|
97
|
+
LABEL org.opencontainers.image.source="https://github.com/ruvnet/ruvector/tree/main/examples/edge-net"
|
|
98
|
+
LABEL org.opencontainers.image.version="1.0.0"
|
|
99
|
+
LABEL org.opencontainers.image.licenses="MIT"
|