[{"data":1,"prerenderedAt":363},["ShallowReactive",2],{"apps":3},[4,34,47,63,80,94,109,125,142,158,170,183,196,211,227,243,256,269,282,296,309,325,338,351],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":8,"slug":10,"group":11,"stage":12,"stageLabel":13,"order":14,"icon":15,"accent":16,"tagline":17,"whatItDoes":18,"howItRuns":19,"connectsTo":20,"whyChosen":27,"_type":28,"_id":29,"_source":30,"_file":31,"_stem":32,"_extension":33},"/apps/gitlab","apps",false,"","GitLab","gitlab","pipeline",1,"Code",10,"simple-icons:gitlab","cyan","Self-hosted Git, merge requests and CI/CD in one place","GitLab hosts the Git repositories and merge requests for this cluster and defines the CI pipelines that build and test every push.","Runs as a GitLab Operator custom resource in the gitlab-system namespace, served through a Traefik IngressRoute on gitlab.kei-space.com. Sign-in is offered through Keycloak via OpenID Connect, and the webservice, Sidekiq and Gitaly components each run as a single replica, backed by its own database on the shared PostgreSQL cluster.",[21,22,23,24,25,26],"postgres","keycloak","gitlab-runner","argocd","sourcebot","uptrace","One tool for source control, code review and CI avoids stitching together separate review and pipeline products, and merge-request pipelines give fast feedback before anything reaches main.","markdown","content:apps:gitlab.md","content","apps/gitlab.md","apps/gitlab","md",{"_path":35,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":36,"description":8,"slug":25,"group":11,"stage":12,"stageLabel":13,"order":37,"icon":38,"accent":16,"tagline":39,"whatItDoes":40,"howItRuns":41,"connectsTo":42,"whyChosen":43,"_type":28,"_id":44,"_source":30,"_file":45,"_stem":46,"_extension":33},"/apps/sourcebot","Sourcebot",15,"mdi:code-braces-box","Fast code search and navigation across every repository","Sourcebot indexes source code across repositories and gives full-text and symbol search with a web UI, so finding where something is defined does not require cloning every project.","Deployed in the sourcebot namespace with a config that connects to the GitLab instance at gitlab.kei-space.com and indexes every repository in the gitops group, using its own PostgreSQL database for application data, served on sourcebot.kei-space.com.",[10,21],"A dedicated code-search index is faster than grepping local clones and keeps working even for repositories not currently checked out.","content:apps:sourcebot.md","apps/sourcebot.md","apps/sourcebot",{"_path":48,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":49,"description":8,"slug":23,"group":11,"stage":50,"stageLabel":51,"order":52,"icon":53,"accent":16,"tagline":54,"whatItDoes":55,"howItRuns":56,"connectsTo":57,"whyChosen":59,"_type":28,"_id":60,"_source":30,"_file":61,"_stem":62,"_extension":33},"/apps/gitlab-runner","GitLab Runner",2,"Build",20,"mdi:cog-play","Executes CI jobs defined in GitLab pipelines","GitLab Runner picks up CI jobs from GitLab and executes them in isolated job pods, running the build, test and image-build steps a pipeline defines.","Runs in the gitlab-runner namespace using the Kubernetes executor, registered against gitlab.kei-space.com, with concurrency capped at one job at a time to fit the cluster's available memory. The runner allows privileged pods so image builds can use a docker:dind service, and job pods are pinned to the worker with the most free memory.",[10,58],"nexus","Running the runner inside the cluster it serves means no separate CI host to patch, and the Kubernetes executor gives every job a clean, resource-limited pod.","content:apps:gitlab-runner.md","apps/gitlab-runner.md","apps/gitlab-runner",{"_path":64,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":65,"description":8,"slug":66,"group":11,"stage":67,"stageLabel":68,"order":69,"icon":70,"accent":71,"tagline":72,"whatItDoes":73,"howItRuns":74,"connectsTo":75,"whyChosen":76,"_type":28,"_id":77,"_source":30,"_file":78,"_stem":79,"_extension":33},"/apps/dependency-track","Dependency-Track","dependency-track",3,"Scan",30,"simple-icons:owasp","purple","Tracks known vulnerabilities in the dependencies listed in uploaded SBOMs","Dependency-Track ingests software bills of materials and continuously matches the libraries they list against known vulnerability data, flagging components that need an upgrade.","Deployed in the dependency-track namespace with separate API server and frontend components, served behind Traefik on dtrack.kei-space.com, with its REST API on a separate host, dtrack-api.kei-space.com. Sign-in goes through Keycloak over OpenID Connect, and projects and findings live in its own PostgreSQL database, with the API server's working data on a 10Gi Longhorn volume.",[21,22],"Stored SBOMs are re-matched as new CVEs are published, so a dependency that was clean when added gets flagged later without a rebuild.","content:apps:dependency-track.md","apps/dependency-track.md","apps/dependency-track",{"_path":81,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":82,"description":8,"slug":83,"group":11,"stage":67,"stageLabel":68,"order":84,"icon":85,"accent":71,"tagline":86,"whatItDoes":87,"howItRuns":88,"connectsTo":89,"whyChosen":90,"_type":28,"_id":91,"_source":30,"_file":92,"_stem":93,"_extension":33},"/apps/nvd-mirror","NVD Mirror","nvd-mirror",35,"mdi:shield-search","Nightly local mirror of the NIST vulnerability database","NVD Mirror keeps a local copy of the National Vulnerability Database feed, so a vulnerability scanner can match dependencies against CVE data without calling the NVD API directly.","Runs in the nvd-mirror namespace with a CronJob that rebuilds the mirror on a nightly schedule, storing the feed on a 25Gi Longhorn volume and serving it behind Traefik on nvd-mirror.kei-space.com.",[],"One nightly download serves any scanner that points at it, instead of each tool pulling the full feed and hitting NVD rate limits.","content:apps:nvd-mirror.md","apps/nvd-mirror.md","apps/nvd-mirror",{"_path":95,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":96,"description":8,"slug":58,"group":11,"stage":97,"stageLabel":98,"order":99,"icon":100,"accent":71,"tagline":101,"whatItDoes":102,"howItRuns":103,"connectsTo":104,"whyChosen":105,"_type":28,"_id":106,"_source":30,"_file":107,"_stem":108,"_extension":33},"/apps/nexus","Nexus Repository",4,"Store",40,"simple-icons:sonatype","Hosts container images and build artifacts the pipeline produces","Nexus Repository stores the artifacts a pipeline builds, acting as a self-hosted container registry and package repository that later deploy steps pull from.","Runs in the nexus namespace as a ClusterIP service reached through a single Traefik host, nexus.kei-space.com, which path-routes UI, REST API, Docker and Helm OCI traffic without separate ports per protocol. Image and artifact data lives on a two-replica Longhorn volume dedicated to this app, and it also proxies Maven and npm downloads for CI.",[23],"One registry for both OCI images and Helm charts keeps the pipeline's \"where do artifacts land\" answer in a single place instead of a registry plus a separate chart repo.","content:apps:nexus.md","apps/nexus.md","apps/nexus",{"_path":110,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":111,"description":8,"slug":24,"group":11,"stage":112,"stageLabel":113,"order":114,"icon":115,"accent":116,"tagline":117,"whatItDoes":118,"howItRuns":119,"connectsTo":120,"whyChosen":121,"_type":28,"_id":122,"_source":30,"_file":123,"_stem":124,"_extension":33},"/apps/argocd","Argo CD",5,"Deploy",50,"simple-icons:argo","green","GitOps controller that keeps the cluster in sync with Git","Argo CD watches a Git repository of Kubernetes manifests and applies every change to the cluster, so the repo is always the source of truth.","Runs in the argocd namespace behind a Traefik IngressRoute on argocd.kei-space.com, with sign-in delegated to Keycloak over OpenID Connect. It polls the GitLab-hosted GitOps repository for every application it manages, and its reconciliation interval is tuned to 600 seconds so that polling more than 30 apps does not overload the single GitLab instance.",[10,22],"Rolling back is a git revert, and drift between the repo and the cluster shows up in the UI instead of being discovered during an incident.","content:apps:argocd.md","apps/argocd.md","apps/argocd",{"_path":126,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":127,"description":8,"slug":128,"group":129,"order":130,"icon":131,"accent":132,"tagline":133,"whatItDoes":134,"howItRuns":135,"connectsTo":136,"whyChosen":138,"_type":28,"_id":139,"_source":30,"_file":140,"_stem":141,"_extension":33},"/apps/talos","Talos Linux","talos","platform",60,"simple-icons:talos","amber","Immutable, API-managed Linux that the whole cluster boots from","Talos Linux is a minimal Linux distribution built only to run Kubernetes, configured entirely through a declarative machine config and an API instead of SSH.","Every node in the cluster runs Talos, with the NVMe disks on the two SSD-equipped workers mounted for Longhorn through each node's machine config.",[137],"longhorn","No SSH and no package manager to drift out of sync means node configuration stays reproducible, which matters more on single-board hardware with no out-of-band console.","content:apps:talos.md","apps/talos.md","apps/talos",{"_path":143,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":144,"description":8,"slug":145,"group":129,"order":146,"icon":147,"accent":132,"tagline":148,"whatItDoes":149,"howItRuns":150,"connectsTo":151,"whyChosen":154,"_type":28,"_id":155,"_source":30,"_file":156,"_stem":157,"_extension":33},"/apps/traefik","Traefik","traefik",61,"simple-icons:traefikproxy","Ingress controller that routes every kei-space.com hostname","Traefik is the ingress controller that terminates TLS and routes incoming traffic to the right in-cluster service based on hostname.","Runs as a single replica with a websecure entrypoint on port 443, and every web-facing app gets its own IngressRoute matching a kei-space.com hostname, with TLS certificates supplied by cert-manager.",[152,153],"cert-manager","metallb","Kubernetes-native IngressRoute objects let each app's own manifests declare its routing instead of maintaining one central ingress config by hand.","content:apps:traefik.md","apps/traefik.md","apps/traefik",{"_path":159,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":152,"description":8,"slug":152,"group":129,"order":160,"icon":161,"accent":132,"tagline":162,"whatItDoes":163,"howItRuns":164,"connectsTo":165,"whyChosen":166,"_type":28,"_id":167,"_source":30,"_file":168,"_stem":169,"_extension":33},"/apps/cert-manager",62,"simple-icons:letsencrypt","Issues and renews TLS certificates for every app automatically","cert-manager requests, renews and stores TLS certificates as Kubernetes resources, so no certificate is ever manually downloaded or copied onto a server.","Runs a ClusterIssuer backed by Let's Encrypt's production ACME endpoint, proving domain ownership with a DNS-01 challenge against the kei-space.com Route 53 zone, and each app declares its own Certificate, whose secret its IngressRoute serves.",[145],"DNS-01 validation issues wildcard-capable certificates without exposing an HTTP-01 challenge path on every single ingress host.","content:apps:cert-manager.md","apps/cert-manager.md","apps/cert-manager",{"_path":171,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":172,"description":8,"slug":153,"group":129,"order":173,"icon":174,"accent":132,"tagline":175,"whatItDoes":176,"howItRuns":177,"connectsTo":178,"whyChosen":179,"_type":28,"_id":180,"_source":30,"_file":181,"_stem":182,"_extension":33},"/apps/metallb","MetalLB",63,"mdi:scale-balance","Gives bare-metal LoadBalancer services a real, routable IP","MetalLB implements the Kubernetes LoadBalancer service type on bare metal, which normally only works on a cloud provider's own network.","Runs in the metallb-system namespace and hands out addresses from a dedicated IP pool using layer-2 mode, announced only from worker nodes so a control-plane reboot cannot take ingress down.",[145],"A small self-hosted cluster still needs one real entry-point IP, and MetalLB is the standard way to get that without cloud infrastructure.","content:apps:metallb.md","apps/metallb.md","apps/metallb",{"_path":184,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":185,"description":8,"slug":137,"group":129,"order":186,"icon":187,"accent":132,"tagline":188,"whatItDoes":189,"howItRuns":190,"connectsTo":191,"whyChosen":192,"_type":28,"_id":193,"_source":30,"_file":194,"_stem":195,"_extension":33},"/apps/longhorn","Longhorn",64,"simple-icons:longhorn","Replicated block storage on the workers' NVMe disks","Longhorn turns local disks on each node into replicated block storage, giving pods a PersistentVolume that can fail over to another node instead of disappearing with it.","Runs in the longhorn-system namespace using the NVMe disks on two of the three worker nodes, and backs PersistentVolumeClaims across the cluster, from a two-replica 50Gi volume for Nexus down to a single-replica 2Gi volume for Grafana.",[128],"Replicated storage means a single worker node dying does not take a database or registry's data with it, which matters more without a SAN or cloud-managed disks.","content:apps:longhorn.md","apps/longhorn.md","apps/longhorn",{"_path":197,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":198,"description":8,"slug":22,"group":129,"order":199,"icon":200,"accent":132,"tagline":201,"whatItDoes":202,"howItRuns":203,"connectsTo":204,"whyChosen":207,"_type":28,"_id":208,"_source":30,"_file":209,"_stem":210,"_extension":33},"/apps/keycloak","Keycloak",65,"simple-icons:keycloak","Single sign-on identity provider for seven apps on the cluster","Keycloak is an identity provider that issues OpenID Connect logins, so every app can delegate authentication to one place instead of keeping its own user database.","Runs as a single replica in the postgres-operator namespace, backed by its own database on the shared PostgreSQL cluster. Its realm is the OIDC issuer for seven apps' logins, including GitLab, Argo CD, Dependency-Track, Open WebUI and Uptrace.",[21,10,24,205,26,66,206],"kubernetes-dashboard","open-webui","Centralizing login in one identity provider means one place to disable a user or rotate credentials, instead of doing it per app.","content:apps:keycloak.md","apps/keycloak.md","apps/keycloak",{"_path":212,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":213,"description":8,"slug":21,"group":129,"order":214,"icon":215,"accent":132,"tagline":216,"whatItDoes":217,"howItRuns":218,"connectsTo":219,"whyChosen":223,"_type":28,"_id":224,"_source":30,"_file":225,"_stem":226,"_extension":33},"/apps/postgres","PostgreSQL",66,"simple-icons:postgresql","Shared, operator-managed Postgres cluster behind nine of these apps","A single PostgreSQL cluster gives each database-backed app its own database, instead of each app shipping and backing up its own server.","Managed by the Crunchy Postgres Operator in the postgres-operator namespace, with a dedicated database and user provisioned per consuming app, plus scheduled pgBackRest backups. pgAdmin runs alongside it in the same namespace for administration, signing in through Keycloak over OpenID Connect.",[10,22,26,66,220,221,222,206,25],"gatus","litellm","n8n","One operator-managed cluster with per-app databases is less to operate than one bundled database per app, and it gives every app the same backup story for free.","content:apps:postgres.md","apps/postgres.md","apps/postgres",{"_path":228,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":229,"description":8,"slug":230,"group":231,"order":232,"icon":233,"accent":116,"tagline":234,"whatItDoes":235,"howItRuns":236,"connectsTo":237,"whyChosen":239,"_type":28,"_id":240,"_source":30,"_file":241,"_stem":242,"_extension":33},"/apps/grafana","Grafana","grafana","observe",70,"simple-icons:grafana","Dashboards for the metrics Prometheus collects","Grafana turns time-series metrics into dashboards, so cluster and application health can be read at a glance instead of queried one metric at a time.","Runs in the monitoring namespace with Prometheus configured as its default data source, and its dashboard JSON is provisioned from a ConfigMap rather than clicked together by hand. Dashboard state itself lives on a small Longhorn-backed volume.",[238],"prometheus","Dashboards provisioned from Git can be rebuilt on a fresh cluster and are reviewed like any other manifest change.","content:apps:grafana.md","apps/grafana.md","apps/grafana",{"_path":244,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":245,"description":8,"slug":238,"group":231,"order":246,"icon":247,"accent":116,"tagline":248,"whatItDoes":249,"howItRuns":250,"connectsTo":251,"whyChosen":252,"_type":28,"_id":253,"_source":30,"_file":254,"_stem":255,"_extension":33},"/apps/prometheus","Prometheus",71,"simple-icons:prometheus","Scrapes and stores the cluster metrics behind the Grafana dashboards","Prometheus pulls metrics from the cluster and its workloads on a schedule and stores them as time series that dashboards can query.","Runs in the monitoring namespace on a 10Gi Longhorn volume, scraping the Kubernetes API servers, nodes, cAdvisor, node-exporter and kube-state-metrics endpoints as well as pod and service endpoints across the cluster, and is reachable through Traefik on prometheus.kei-space.com.",[230],"A pull-based metrics store that scrapes workloads directly needs no per-app push client to configure, just a scrape target.","content:apps:prometheus.md","apps/prometheus.md","apps/prometheus",{"_path":257,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":258,"description":8,"slug":26,"group":231,"order":259,"icon":260,"accent":116,"tagline":261,"whatItDoes":262,"howItRuns":263,"connectsTo":264,"whyChosen":265,"_type":28,"_id":266,"_source":30,"_file":267,"_stem":268,"_extension":33},"/apps/uptrace","Uptrace",72,"simple-icons:opentelemetry","Traces and metrics backend fed by the cluster's OpenTelemetry collector","Uptrace ingests OpenTelemetry traces and metrics and lets you follow a single request across services, which is harder to reconstruct from logs alone.","Runs in the uptrace namespace, storing trace and span data in an in-cluster ClickHouse instance and its own project metadata in PostgreSQL. An OpenTelemetry collector feeds it metrics from Traefik, Argo CD, Longhorn and Postgres, and GitLab's Gitaly component and Keycloak export traces to it over OTLP.",[21,10,145,24,137,22],"Tracing points at exactly which hop in a request was slow, which a dashboard of aggregate metrics cannot show on its own.","content:apps:uptrace.md","apps/uptrace.md","apps/uptrace",{"_path":270,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":271,"description":8,"slug":220,"group":231,"order":272,"icon":273,"accent":116,"tagline":274,"whatItDoes":275,"howItRuns":276,"connectsTo":277,"whyChosen":278,"_type":28,"_id":279,"_source":30,"_file":280,"_stem":281,"_extension":33},"/apps/gatus","Gatus",73,"mdi:heart-pulse","Automated status page that polls each app's health endpoint","Gatus repeatedly checks a list of endpoints and renders a status page, so an outage shows up as a red check instead of a support ticket.","Runs in the gatus namespace behind Traefik on gatus.kei-space.com, running about 38 endpoint checks, most of them every 60 seconds, and storing results in its own PostgreSQL database.",[21,238],"Probing each app through its real hostname catches an app that Kubernetes reports as healthy but that is not actually answering requests.","content:apps:gatus.md","apps/gatus.md","apps/gatus",{"_path":283,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":284,"description":8,"slug":285,"group":231,"order":286,"icon":287,"accent":116,"tagline":288,"whatItDoes":289,"howItRuns":290,"connectsTo":291,"whyChosen":292,"_type":28,"_id":293,"_source":30,"_file":294,"_stem":295,"_extension":33},"/apps/uptime-kuma","Uptime Kuma","uptime-kuma",74,"simple-icons:uptimekuma","Self-hosted uptime monitor with its own notification history","Uptime Kuma monitors endpoint uptime and response time with a built-in dashboard and notification history, independent of any other monitoring stack.","Runs as a single-replica StatefulSet in the uptime-kuma namespace, keeping its monitor configuration and history on its own 1Gi Longhorn volume rather than an external database.",[],"A second, independent uptime checker means a bug or outage in the primary monitoring stack does not also blind the status history.","content:apps:uptime-kuma.md","apps/uptime-kuma.md","apps/uptime-kuma",{"_path":297,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":298,"description":8,"slug":205,"group":231,"order":299,"icon":300,"accent":116,"tagline":301,"whatItDoes":302,"howItRuns":303,"connectsTo":304,"whyChosen":305,"_type":28,"_id":306,"_source":30,"_file":307,"_stem":308,"_extension":33},"/apps/kubernetes-dashboard","Kubernetes Dashboard",75,"simple-icons:kubernetes","Web UI for browsing and inspecting live cluster resources","Kubernetes Dashboard gives a web UI over the resources already visible through kubectl, for browsing pods, logs and resource usage without a terminal.","Runs in the kubernetes-dashboard namespace behind Traefik on dashboard.kei-space.com, where a forwardAuth check against a separate oauth2-proxy deployment enforces Keycloak login before any request reaches the dashboard.",[22],"Putting the login check in front of the dashboard with oauth2-proxy means the dashboard never needs its own auth story.","content:apps:kubernetes-dashboard.md","apps/kubernetes-dashboard.md","apps/kubernetes-dashboard",{"_path":310,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":311,"description":8,"slug":312,"group":313,"order":314,"icon":315,"accent":316,"tagline":317,"whatItDoes":318,"howItRuns":319,"connectsTo":320,"whyChosen":321,"_type":28,"_id":322,"_source":30,"_file":323,"_stem":324,"_extension":33},"/apps/ollama","Ollama","ollama","ai",80,"simple-icons:ollama","pink","Runs open-weight LLMs locally instead of calling a hosted API","Ollama downloads and serves open-weight language models, giving an OpenAI-compatible API for running inference without sending prompts to an external provider.","Runs in the ollama namespace with model weights stored on a 20Gi Longhorn volume, exposing its API on the standard Ollama port for in-cluster clients.",[],"Local inference keeps prompts on owned hardware with no per-token cost; on CPU-only Pi nodes that means a small model such as a 1.7B Qwen running at single-digit tokens per second.","content:apps:ollama.md","apps/ollama.md","apps/ollama",{"_path":326,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":327,"description":8,"slug":206,"group":313,"order":328,"icon":329,"accent":316,"tagline":330,"whatItDoes":331,"howItRuns":332,"connectsTo":333,"whyChosen":334,"_type":28,"_id":335,"_source":30,"_file":336,"_stem":337,"_extension":33},"/apps/open-webui","Open WebUI",81,"mdi:chat-processing","Chat front-end for whichever LLM backend LiteLLM is routing to","Open WebUI is a ChatGPT-style web interface for talking to language models, keeping chat history and settings instead of a bare API call.","Runs in the open-webui namespace behind Traefik on ai.kei-space.com, with chat history in its own PostgreSQL database and sign-in offered through Keycloak over OpenID Connect. It talks to LiteLLM's in-cluster service as its OpenAI-compatible backend, authenticating with a key from the same secret LiteLLM itself reads.",[221,21,22],"Pointing the chat UI at LiteLLM instead of a single provider means the model backend can change without reconfiguring the UI.","content:apps:open-webui.md","apps/open-webui.md","apps/open-webui",{"_path":339,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":340,"description":8,"slug":221,"group":313,"order":341,"icon":342,"accent":316,"tagline":343,"whatItDoes":344,"howItRuns":345,"connectsTo":346,"whyChosen":347,"_type":28,"_id":348,"_source":30,"_file":349,"_stem":350,"_extension":33},"/apps/litellm","LiteLLM",82,"mdi:router-network","One OpenAI-compatible endpoint that fans out to multiple models","LiteLLM is a proxy that exposes one OpenAI-compatible API and routes each request to a configured model, so callers don't need to know which provider is behind a given model name.","Runs in the open-webui namespace, routing named models to the Anthropic API with the key read from a Kubernetes secret, and storing its model configuration and spend logs in its own PostgreSQL database.",[21,206,222],"A single routing layer means swapping or adding a model is a config change in one place instead of touching every client that calls it.","content:apps:litellm.md","apps/litellm.md","apps/litellm",{"_path":352,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":222,"description":8,"slug":222,"group":313,"order":353,"icon":354,"accent":316,"tagline":355,"whatItDoes":356,"howItRuns":357,"connectsTo":358,"whyChosen":359,"_type":28,"_id":360,"_source":30,"_file":361,"_stem":362,"_extension":33},"/apps/n8n",83,"simple-icons:n8n","Visual workflow automation for wiring SaaS APIs together","n8n is a workflow automation tool for wiring APIs together with a visual node editor instead of writing a one-off integration script.","Runs in the n8n namespace behind Traefik on n8n.kei-space.com, with workflow and credential data stored in its own PostgreSQL database. One of its workflows also calls LiteLLM's in-cluster endpoint to generate embeddings.",[21,221],"A visual workflow tool makes multi-step automations easy to read and modify later, compared to a pile of small glue scripts.","content:apps:n8n.md","apps/n8n.md","apps/n8n",1791096595875]