# KiteStacks Architecture — How It All Works **Last updated:** 2026-06-18 --- ## The Simple Version KiteStacks is two computers working together to run a bunch of websites. - **monk** — your home machine. Runs almost everything. - **kscloud1** — a rented computer in Germany (Hetzner). Backs everything up. People visit the websites through **Cloudflare**, which acts like a secret post-office. Cloudflare knows where monk and kscloud1 are, but the rest of the internet doesn't. That means your home address never gets exposed. ``` You (on any device) → Cloudflare (the post office) → monk or kscloud1 ``` If monk goes offline, Cloudflare automatically sends traffic to kscloud1 instead. Both are always ready to handle requests — this is called **active-active**. --- ## What Each Service Does ### Login (Identity) | Service | What it does | |---------|-------------| | **Authentik** | The doorman — checks who you are before letting you into any site | | Authentik worker | Runs background jobs for Authentik | | Authentik PostgreSQL | The address book — stores all usernames and passwords (on kscloud1) | | Authentik Redis | Fast memory — remembers who is logged in so you don't need to log in again | ### Infrastructure | Service | What it does | |---------|-------------| | **cloudflared** | Runs on both machines — creates the secret tunnel to Cloudflare | | **Portainer** | A control panel to manage all the little program-boxes (containers) | | **Forgejo** | Like GitHub but yours — stores all the code and scripts | | **Uptime Kuma** | A watchdog — alerts when any service goes down | ### Monitoring | Service | What it does | |---------|-------------| | **Prometheus** | Collects numbers (CPU, memory, disk) from both machines every 15 seconds | | **Grafana** | Turns those numbers into charts you can watch | | **Node Exporter** | Runs on each machine and reports its health to Prometheus | ### Apps | Service | What it does | |---------|-------------| | **BookStack** | A private wiki — all notes and guides live here | | **Karakeep** | Saves bookmarks and website archives | | **Kavita** | Reads ebooks and manga | | **OSTicket** | Help-desk system — tracks tasks and tickets | | **Open WebUI** | Chat with AI (GPT-4, Claude, or local models) | | **LiteLLM** | Routes AI requests to the right model | | **KiteStacks Portal** | The homepage at www.kitestacks.com | --- ## How Login Works (SSO) Every website on KiteStacks uses **Authentik** for login. You log in once, and every website trusts that. This is called **Single Sign-On (SSO)**. Here's what happens when you visit a site: ``` 1. You go to wiki.kitestacks.com (BookStack) 2. BookStack checks: "Are you logged in?" — No. 3. BookStack sends you to auth.kitestacks.com (Authentik) 4. Authentik asks for your username and password 5. You log in — Authentik issues a proof-token 6. Authentik sends you back to BookStack with the proof 7. BookStack reads the proof and creates your session 8. You're in! ``` This system uses a standard called **OIDC** (OpenID Connect). Every website speaks OIDC, so they all work the same way with Authentik as the login source. --- ## How the Network Works ### Public traffic (the websites) All public traffic enters through **Cloudflare Tunnel**. - Both monk and kscloud1 run a small program called `cloudflared` - `cloudflared` connects outward to Cloudflare — no ports need to be open on your router - Cloudflare sends visitor traffic through whichever connector is healthy - If monk is off, kscloud1 handles everything within seconds ### Private traffic (machine-to-machine) monk and kscloud1 talk to each other through **Tailscale** — a private encrypted network. Tailscale is used for: - monk reaching the database (PostgreSQL) on kscloud1 for Authentik logins - SSH from monk to kscloud1 for management - Prometheus on monk scraping metrics from kscloud1 Nothing on Tailscale is visible to the public internet. --- ## Where Files Live ### On monk ``` ~/kitestacks-live/docker/ ├── authentik/ ← login system ├── bookstack/ ← wiki + its database ├── cloudflared/ ← cloudflare tunnel connector ├── forgejo/ ← git server ├── grafana/ ← monitoring charts ├── karakeep/ ← bookmarks ├── kavita/ ← ebook reader ├── kitestacks-portal/ ← homepage ├── osticket/ ← help desk ├── portainer/ ← container dashboard └── prometheus/ ← metrics collector ``` ### On kscloud1 ``` /opt/kitestacks/docker/ ├── authentik/ ← PostgreSQL + Redis (shared with monk's Authentik) ├── bookstack/ ← backup wiki └── cloudflared/ ← backup tunnel connector ``` --- ## What Happens When Things Break | What breaks | What users see | Comes back automatically? | |-------------|----------------|--------------------------| | monk offline | monk services down; portal + wiki still work on kscloud1 | Yes — Cloudflare switches to kscloud1 | | kscloud1 offline | Authentik logins may fail (database unreachable) | No — restart kscloud1 or switch to local DB | | Cloudflare tunnel down | All public websites unreachable | No — check CF dashboard, restart cloudflared | | BookStack database crashes | BookStack shows an error | Run: `docker restart bookstack-db && docker restart bookstack` | | Portainer lockout | Can't manage containers from the web | Run the password reset helper (see RUNBOOK.md) | --- ## Key Design Decisions **Why Cloudflare Tunnel instead of opening router ports?** Opening ports exposes your home IP address. Anyone can then scan it, try to break in, or use it to locate you. Cloudflare Tunnel creates a private outbound connection — your IP stays hidden. It's also free and supports automatic failover. **Why active-active instead of active-passive?** Active-passive requires detecting failure and switching over, which takes time. Active-active is simpler — both machines are always handling traffic, so Cloudflare just stops sending to the broken one automatically. **Why Authentik for login instead of passwords per app?** If every app has its own password, you manage dozens of credentials and each app stores its own user database. Authentik is one place — one login to change, one place to block a user. Every app just asks Authentik "is this person who they say they are?" **Why Forgejo instead of just GitHub?** GitHub can disappear, change pricing, or expose your private repos. Forgejo is self-hosted — runs on monk, uses almost no RAM, and keeps everything in-house. **Why BookStack instead of Notion?** Notion is a third-party service that can change pricing or lose your data. BookStack is self-hosted — the data is on your machine, and you own it completely.