# ByteLyst Single-VM Deployment

> Deploy the **entire ByteLyst ecosystem** (31 services, 11 products) on a single Azure VM.
> Two orchestration approaches — pick one or learn both side by side.

Related:

- [`../ENDPOINT_INVENTORY.md`](../ENDPOINT_INVENTORY.md) — canonical endpoint inventory across local, Azure VM, and domain-based ingress

---

## Approaches

### [`docker/`](docker/) — Docker Compose (Production-ready)

Proven, battle-tested deployment using `docker-compose.ecosystem.yml`.
Installs everything from scratch on a raw Ubuntu VM in ~20 minutes.
Includes Gitea CI (act_runner) for continuous integration.

```bash
sudo ./docker/setup.sh              # Full install
sudo ./docker/setup.sh --resume     # Resume after disconnect
/opt/bytelyst/check-health.sh       # Verify all 30 services
```

**Use this if:** You want reliable deployment now.

### [`k8s/`](k8s/) — Kubernetes via k3s (Learning / Future-ready)

Same 31 services orchestrated by Kubernetes on a single VM using k3s.
Builds on the same Docker images — no Dockerfile changes needed.

**Use this if:** You want to learn K8s with real services, practice `kubectl`,
and prepare for multi-node scaling later.

---

## Architecture (shared by both approaches)

```
Raw Ubuntu 24.04 VM (Standard_D8s_v5: 8 vCPU, 32 GB RAM)
├── Ollama (systemd, :11434) ─── local LLM inference
├── Gitea (Docker/:3300) ──────── npm package registry + CI
├── act_runner (systemd) ──────── Gitea CI runner (host mode)
└── 31 Services
    ├── Infrastructure (6): cosmos-emulator, azurite, mailpit, loki, grafana, traefik
    ├── Platform (3): platform-service, extraction-service, mcp-server
    ├── Dashboards (2): admin-web, tracker-web
    ├── Backends (10): peakpulse, chronomind, jarvisjr, nomgap, mindlyst,
    │                   lysnrai, notelett, flowmonk, actiontrail, localmemgpt
    ├── Web Apps (9): lysnrai-dashboard, chronomind-web, jarvisjr-web, flowmonk-web,
    │                  notelett-web, mindlyst-web, nomgap-web, actiontrail-web, localmemgpt-web
    └── Standalone (1): llmlab-dashboard (LLM Lab Mission Control)
```

## Comparison

|                     | Docker Compose     | K8s (k3s)                          |
| ------------------- | ------------------ | ---------------------------------- |
| **Setup time**      | ~20 min            | ~30 min                            |
| **RAM overhead**    | ~100 MB            | ~600 MB                            |
| **Config files**    | 1 compose + 1 .env | ~30 manifests (or Helm)            |
| **Scaling**         | Manual             | `kubectl scale` / HPA              |
| **Rolling updates** | Restart-based      | Zero-downtime                      |
| **Resource limits** | Basic              | Fine-grained per pod               |
| **Multi-VM ready**  | Docker Swarm       | Native `kubectl join`              |
| **Learning value**  | Low                | High (transferable to AKS/EKS/GKE) |

## Recommendation

**For a single Azure VM → use Docker Compose.** Here's why:

1. **One VM = no cluster benefits.** K8s shines at multi-node scheduling, auto-healing across hosts, and rolling deploys with replica sets. With 1 node, all pods compete for the same resources anyway.
2. **RAM matters.** k3s adds ~500-600 MB overhead. On a 32 GB VM running 31 services + Cosmos emulator + Ollama, that headroom is useful.
3. **Operational simplicity.** `docker compose logs -f platform-service` vs `kubectl logs deploy/platform-service -n bytelyst-platform -f` — Compose wins for a solo developer.
4. **Faster iteration.** `docker compose up --build flowmonk-backend` rebuilds + restarts in seconds. K8s requires image tag bumps, manifest edits, and `kubectl apply`.
5. **CI already runs on host.** act_runner uses host mode, not Docker-in-Docker. Compose services are reachable at `localhost:<port>` — K8s NodePort adds a layer.

**When to switch to K8s:**

- Scaling beyond 1 VM (add nodes with `k3s agent`)
- Need zero-downtime rolling updates for beta users
- Want fine-grained resource limits per service
- Preparing for AKS/EKS production migration

The `k8s/` folder is ready for when you need it. Both approaches share the same Docker images and Gitea registry.
