# Atlas OS — System Architecture

## Overview: The One-Box Philosophy

Atlas OS is deliberately a single-server architecture. One Hetzner CPX32 VPS
(8 vCPU · 16 GB RAM · 150 GB NVMe · Nuremberg) runs the complete operational
infrastructure of Atlas Corporation: CRM, finance, communications, AI, document
management, fleet control, and 11 websites.

**Why one box?** For a solo founder, operational simplicity outweighs redundancy.
One server = one bill, one SSH target, one Caddy config, one Authentik instance,
and zero inter-datacenter latency. The Tailscale overlay provides device-level
redundancy for access even if Caddy is down.

---

## Network Topology

```
                    ┌──────────────────────────────────────────────┐
 Public Internet    │              atlas-01 (Hetzner CPX32)        │
 ─────────────      │  ┌─────────┐    ┌──────────┐                │
 Browser/App ──────►│  │  Caddy  │───►│Authentik │──► Services    │
                    │  │  (TLS)  │    │  (SSO)   │                │
                    │  └─────────┘    └──────────┘                │
                    │                                              │
 Tailscale mesh     │  ┌────────────────────────────────────────┐ │
 ────────────────   │  │  Private tailnet (100.x.x.x)           │ │
 iOS / PC / Laptop─►│  │  Webtop desktop · internal dashboards  │ │
                    │  └────────────────────────────────────────┘ │
                    └──────────────────────────────────────────────┘
```

### Public → SSO path (every service except mail ports)
1. Request hits Caddy (443 → Docker port)
2. Caddy runs `forward_auth` against Authentik outpost
3. Authentik validates session cookie / issues redirect to login
4. On success: Caddy copies `X-Authentik-*` headers and proxies to service

### Tailscale-only services
- Webtop remote desktop (`tailscale serve :PORT`)
- Internal dashboards (portal, status feeds)
- atlas-01 SSH (blocked on public firewall, tailnet-only)

---

## Service Layers

### Tier 0 — Identity & Security
- **Authentik** (`auth.{DOMAIN}`) — OIDC/SSO, MFA, app proxies
- **Vaultwarden** (`vault.{DOMAIN}`) — end-to-end encrypted password vault
- **Caddy** — automatic TLS, reverse proxy, the sole public entry point

### Tier 1 — Core Business
- **Odoo 19** — CRM, invoicing, project management, contacts
- **Nextcloud 31** — file storage, DAV (calendar/contacts sync to iOS)
- **Stalwart** — self-hosted email: SMTP, IMAPS, JMAP, Sieve
- **Forgejo** — self-hosted git (this very repo)

### Tier 2 — Finance & Operations
- **Firefly III** — double-entry bookkeeping, budgets, reconciliation
- **Enable Banking** — PSD2 bank feed (ING, Knab → Firefly)
- **Paperless-ngx** — document management, OCR, auto-tagging
- **n8n** — workflow automation (webhooks, scheduled tasks)
- **Uptime Kuma** — service health monitoring with alerting

### Tier 3 — AI & Intelligence
- **LiteLLM proxy** — unified OpenAI-compat API to all models (local + cloud)
- **Open-WebUI** — ChatGPT-style UI on top of LiteLLM
- **Atlas Brain** (`atlas_brain.py`) — Python signal collector, runs every 15 min
- **Atlas Loop** — background nudge cycle, publishes to NATS
- **Atlas Meridian** — autonomous decision engine / battle responder
- **Langfuse** — LLM observability: every call traced with latency, cost, tokens
- **Local model router** (`:8888`) — OpenAI-compat router for local Ollama models

### Tier 4 — Fleet & Infrastructure
- **MeshCentral** — remote device access, POS terminal fleet management
- **NATS** — real-time pub/sub event bus across all Tailscale devices
- **Atlas heartbeat sink** — aggregates device heartbeats from the NATS mesh
- **Atlas cockpit feeds** — on-disk JSON feeds consumed by the OS desktop
- **Webtop** — full XFCE Linux desktop in the browser (tailnet-only)

### Tier 5 — Managed Sites (11 sites)

All served via Caddy. WordPress sites run in isolated Docker stacks:

| Domain | Stack | Notes |
|--------|-------|-------|
| `atlasworks.YOUR_DOMAIN` | Docker: works-wordpress | Live WooCommerce (Caddy :8111) |
| `YOUR_DOMAIN` | Docker: corp-wordpress | Corporate site |
| `agency.YOUR_DOMAIN` | Docker: agency-wordpress | Agency services |
| `academy.YOUR_DOMAIN` | TransIP nginx (static HTML) | Academy landing |
| `pos.YOUR_DOMAIN` | TransIP | AtlasPOS product site |

---

## Data Flow — Atlas Brain Cycle

```
Every 15 minutes (atlas-brain.service):
  ┌──────────────────────────────────────────┐
  │  Signal collection phase                 │
  │  ├── 7 IMAP mailboxes (read-only)        │
  │  ├── Odoo REST API (leads, contacts)     │
  │  ├── Enable Banking (bank transactions)  │
  │  └── atlas-01 health/fleet feeds         │
  └──────────────────┬───────────────────────┘
                     │
                     ▼
             atlas-state.json
                     │
                     ▼
         LLM synthesis (model router):
           atlas-auto (local) → Groq 70B → Claude Opus
                     │
                     ▼
         atlas-brief-spoken.json  (daily brief)
                     │
                     ▼
         Atlas OS cockpit panels (Today · Money · Inbox · Pipeline)
```

---

## The AI Mesh

```
atlas-01 (NATS JetStream server)
    │
    ├── subjects:
    │     atlas.events.*      system events (disk, CPU, service state)
    │     atlas.heartbeat.*   device health pings
    │     atlas.jobs.*        delegated compute jobs (Ollama on NEBULA)
    │     atlas.brief.*       daily brief push to all devices
    │
    └── subscribers:
          Caddy PC (this machine)  ← atlas-events-collector
          NEBULA (HP EliteBook)    ← atlas-delegate-worker (5 Ollama models)
          MET-Desktop              ← Odoo failover + fleet monitor
```

---

## Caddy SSO Pattern

Every SSO-gated service uses this Caddyfile block (see `deploy/caddy/Caddyfile.template`):

```caddy
app.example.com {
  # Authentik outpost endpoints (must come first)
  reverse_proxy /outpost.goauthentik.io/* authentik-server:9000

  # SSO gate — redirects to login if no valid session
  forward_auth authentik-server:9000 {
    uri /outpost.goauthentik.io/auth/caddy
    copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email
                 X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt
  }

  # Only reached after successful authentication
  reverse_proxy localhost:APP_PORT
}
```

---

## Docker Compose Topology

| Stack | File | Services |
|-------|------|----------|
| Core | `deploy/compose/atlas-core.yml` | Authentik, Nextcloud, Stalwart, Forgejo, Vaultwarden |
| AI | `deploy/compose/atlas-ai.yml` | LiteLLM, Open-WebUI, Langfuse |
| Business | `atlas-odoo.yml` | Odoo 19 + PostgreSQL |
| Finance | `atlas-finance.yml` | Firefly III + Paperless-ngx + Enable Banking |
| Fleet | `atlas-fleet.yml` | MeshCentral + NATS + Uptime Kuma |
| Sites | Per-site compose | WordPress stacks |
| Desktop | `deploy/webtop-docker-compose.yml` | Webtop (tailnet-only) |

All stacks share the `atlas-net` Docker network. Caddy is the **sole** process with
public port bindings (80/443). All internal services bind only to `127.0.0.1:PORT`.
