Both docs now use everyday analogies (Cloudflare = post office, Authentik = doorman) instead of technical jargon, making them accessible to anyone learning the project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
173 lines
6.7 KiB
Markdown
173 lines
6.7 KiB
Markdown
# 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.
|