mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-03-31 05:59:26 +02:00
8.3 KiB
8.3 KiB
Project N.O.M.A.D. — Homelab Edition: Architecture
System Overview
Project N.O.M.A.D. Homelab Edition is a container-native knowledge platform designed for NAS and homelab environments. The architecture prioritizes reliability, minimal resource usage, and compatibility with storage-backed systems.
Container Stack
┌─────────────────────────────────────────────────────────────────┐
│ Docker Host / NAS │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ nomad-internal network │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │ │
│ │ │ nomad-nginx │ │ nomad-app │ │nomad-worker │ │ │
│ │ │ (Nginx) ├───►│ (AdonisJS) │ │ (Queue Jobs)│ │ │
│ │ │ :80/:443 │ │ :8080 │ │ │ │ │
│ │ └──────────────┘ └──────┬───────┘ └──────┬──────┘ │ │
│ │ │ │ │ │
│ │ ┌──────▼───────┐ ┌──────▼──────┐ │ │
│ │ │nomad-database│ │ nomad-cache │ │ │
│ │ │ (MySQL 8.0) │ │ (Redis 7) │ │ │
│ │ │ :3306 │ │ :6379 │ │ │
│ │ └──────────────┘ └─────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ Volumes: │
│ ├── nomad-db-data (Docker volume - local SSD) │
│ ├── NOMAD_DATA_DIR/storage (bind mount - NAS share) │
│ ├── NOMAD_DATA_DIR/redis (bind mount) │
│ └── NOMAD_DATA_DIR/logs/nginx (bind mount) │
└─────────────────────────────────────────────────────────────────┘
Service Roles
nomad-app (Application Server)
- Technology: Node.js 22 + AdonisJS 6
- Role: Serves the web UI (React/Inertia), handles API requests, manages content
- Port: 8080
- Dependencies: nomad-database, nomad-cache
nomad-worker (Background Worker)
- Technology: Same image as nomad-app
- Role: Processes background jobs — content downloads, AI model downloads, embeddings, benchmarks
- Queues: downloads, model-downloads, benchmarks, embeddings
- Dependencies: nomad-database, nomad-cache
nomad-database (Database)
- Technology: MySQL 8.0
- Role: Persistent storage for services, content metadata, chat sessions, benchmarks, settings
- Storage: Docker named volume (optimized for I/O)
nomad-cache (Cache / Queue Broker)
- Technology: Redis 7 Alpine
- Role: BullMQ job queues, session cache, real-time event transport
- Config: AOF persistence, 256MB max memory with LRU eviction
nomad-nginx (Reverse Proxy)
- Technology: Nginx Alpine
- Role: TLS termination, request routing, static asset caching, WebSocket proxy
- Ports: 80 (HTTP), 443 (HTTPS)
Data Flow
Content Download Pipeline
User Request
│
▼
nomad-app (API) ──► nomad-cache (Redis Queue)
│
▼
nomad-worker
│
Downloads content
│
▼
/app/storage/
(NAS bind mount)
AI Chat Pipeline
User Message
│
▼
nomad-app ──► Ollama (AI Model)
│ │
│ ▼
│ Response + RAG context
│ │
▼ ▼
nomad-database (Chat History)
Real-Time Updates
nomad-worker ──► nomad-cache (Redis Pub/Sub)
│
▼
nomad-app (Transmit SSE)
│
▼
Browser (EventSource)
Storage Architecture
Design Principles
- Database on local volume — Docker named volume for high-IOPS MySQL operations
- Content on NAS share — Bind mount to NAS storage for large files (ZIM, maps, PDFs)
- Logs rotated automatically — Nginx logs on bind mount, easily accessible
Storage Tiers
| Tier | Type | Use Case | I/O Profile |
|---|---|---|---|
| Hot | Docker named volume | MySQL database | High IOPS, small writes |
| Warm | Bind mount (SSD/cache) | Redis, temp files | Medium IOPS |
| Cold | Bind mount (NAS array) | Content library, backups | Sequential reads, large files |
NAS Compatibility
| Platform | Storage Path | Notes |
|---|---|---|
| Unraid | /mnt/user/appdata/project-nomad |
Uses cache drive for DB |
| TrueNAS SCALE | /mnt/pool/apps/project-nomad |
ZFS dataset recommended |
| Linux | /opt/project-nomad |
Standard filesystem |
| Synology | /volume1/docker/project-nomad |
Btrfs volume |
Network Architecture
Internal Network
All services communicate over the nomad-internal bridge network. Only the following ports are exposed to the host:
| Port | Service | Purpose |
|---|---|---|
| 80 | nomad-nginx | HTTP (configurable) |
| 443 | nomad-nginx | HTTPS (configurable) |
| 8080 | nomad-app | Direct app access (optional) |
Reverse Proxy Compatibility
The stack works behind external reverse proxies:
Internet/LAN
│
▼
┌───────────────────┐
│ External Proxy │ Nginx Proxy Manager / Traefik / Caddy
│ (TLS termination) │
└─────────┬─────────┘
│
▼
┌─────────────────────┐
│ nomad-nginx (:80) │ OR directly to nomad-app (:8080)
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ nomad-app (:8080) │
└─────────────────────┘
When using an external reverse proxy, you can disable nomad-nginx:
# In docker-compose.yml override
services:
nomad-nginx:
profiles: ["proxy"] # Only starts with --profile proxy
Resource Requirements
Minimum (8 GB RAM system)
| Service | RAM | CPU |
|---|---|---|
| nomad-app | 256 MB | 0.25 cores |
| nomad-worker | 256 MB | 0.1 cores |
| nomad-database | 256 MB | 0.25 cores |
| nomad-cache | 64 MB | 0.05 cores |
| nomad-nginx | 16 MB | 0.01 cores |
| Total | ~850 MB | ~0.66 cores |
Recommended (32 GB RAM system)
| Service | RAM | CPU |
|---|---|---|
| nomad-app | 1 GB | 1 core |
| nomad-worker | 2 GB | 1 core |
| nomad-database | 1 GB | 0.5 cores |
| nomad-cache | 256 MB | 0.1 cores |
| nomad-nginx | 32 MB | 0.05 cores |
| Total | ~3.3 GB | ~2.65 cores |
Security Model
- No authentication by default (network-level access control recommended)
- All inter-service communication on private Docker network
- Database and Redis not exposed to host by default
- Docker socket mounted read-only where possible
- Agent communication via shared secret (Bearer token)