# 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.nl` | Docker: works-wordpress | Live WooCommerce (Caddy :8111) | | `atlascorporation.nl` | Docker: corp-wordpress | Corporate site | | `atlasagency.nl` | Docker: agency-wordpress | Agency services | | `atlasacademy.nl` | TransIP nginx (static HTML) | Academy landing | | `atlaspos.nl` | 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`.