Local Setup (Kind)¶
Run the full IDP platform on your laptop — no AWS account required.
Prerequisites¶
1 2 3 4 5 6 7 8 | |
macOS ARM64 note: The cluster is pinned to K8s 1.33.1 (
kindest/node:v1.33.1) — tested stable on macOS ARM64 with Docker Desktop.Python note (only if you run the observability tests): the exporters use
X | Nonetype syntax, which needs Python 3.10+. macOS ships 3.9 aspython3, and runningpytest observability/testswith it fails inside an import —observability/tests/conftest.pycatches that and says so. Use a newer interpreter, e.g.python3.13 -m pytest observability/tests. Nothing else in the local setup needs it: CI runs 3.12/3.13 and the exporter CronJobs usepython:3.12-slim/python:3.13-slim.
Machine requirements — and what to do if you don't have them¶
The full platform is ~90 pods. What it actually consumes once settled, measured
with kubectl top on a Rancher Desktop VM of 8 CPU / 13 GB (2026-08-22):
| Layer | Installed by | CPU | Memory |
|---|---|---|---|
Kubernetes itself (kube-system, ingress, storage) |
always | ~630m | ~1.5 GB |
| Observability (Prometheus, Grafana, OpenCost) | bootstrap-local.sh |
~280m | ~1.2 GB |
| ↳ Loki + Promtail + Tempo | installed but scaled to 0 — see below | 0 | 0 |
| GitOps + policy (ArgoCD, Kyverno, Gatekeeper, Argo Rollouts) | bootstrap-local.sh |
~170m | ~1.1 GB |
Your services + the 8 MCP servers (services-dev) |
bootstrap-local.sh |
~105m | ~0.35 GB |
| VM overhead (kubelet, containerd, guest OS) | — | — | ~2.3 GB |
| Langfuse (6 pods) | bootstrap-ai.sh (on by default) |
~400m | ~2.2 GB |
| KAgent runtime + 1 agent | bootstrap-ai.sh |
~40m | ~0.5 GB |
| ↳ each additional agent | --agents |
~5m | ~200 MB |
| MLflow | bootstrap-ai.sh |
~50m | ~0.4 GB |
| Argo Workflows | bootstrap-ai.sh |
~30m | ~0.15 GB |
Two numbers dominate and are worth knowing by name: inside Langfuse,
langfuse-clickhouse is ~736 MB and langfuse-web ~908 MB. langfuse-web will
not run under a 1 GB limit at all — Node sizes its heap from the container limit
and OOMs at ~503 MB, so 2 GB is the floor.
Both Kind nodes share one VM. free -m inside either node reports the whole
VM, not a per-node slice, so "the worker has 13 GB" is not a second 13 GB.
Adding it up¶
| Selection | Memory | Fits in a 13 GB VM? |
|---|---|---|
Core only (bootstrap-local.sh) |
~6.9 GB | yes, comfortably |
| + Langfuse | ~9.1 GB | yes |
| + Langfuse + KAgent with 1 agent | ~9.6 GB | yes, ~3.3 GB spare |
| Everything: + 8 more agents, MLflow, Argo Workflows | ~11.8 GB | no — ~1.2 GB spare, below the level where it degrades |
The thresholds that actually matter¶
These are the points at which a real cluster stopped working, not safety margins:
| Signal | Observed |
|---|---|
| < ~200 MB available memory | etcd returns DeadlineExceeded, the API server starts answering every request with Handler timeout, and kubectl fails with Unable to connect to the server: EOF. Backstage shows ERR_EMPTY_RESPONSE because nginx-ingress runs inside the starving cluster. |
| > ~75% of VM CPU sustained (600% of 800% on 8 cores) | Pods stick in Terminating for tens of minutes, controllers crashloop on their liveness probes, and dependent installs fail — a stuck kagent-postgresql is what makes the KAgent controller crashloop and Backstage 502 on /api/modelconfigs. |
| > ~90% of VM CPU | The run does not complete. |
Stop adding components when available memory drops below ~1.5 GB.
1 2 3 | |
free will look alarming (a few hundred MB) while several GB are still
reclaimable cache. available is the number to watch.
Note the asymmetry: CPU binds during installation — image pulls and several
concurrent helm --waits — while memory binds at rest. An install can die on
a cluster that would have run the same pods perfectly well once settled. Install
incrementally on a tight machine and let each step finish.
VM sizing¶
Set this in Docker Desktop → Settings → Resources, or Rancher Desktop → Virtual Machine. The VM gets roughly 80% of physical RAM, so the third column is what your machine actually needs:
| Setup | VM CPU | VM memory | Physical RAM | Notes |
|---|---|---|---|---|
| Everything | 8 | 16 GB | 24 GB | All agents, Langfuse, MLflow, Argo Workflows. ~11.8 GB of workload plus room to build images. |
| Full stack, no Langfuse | 8 | 13 GB | 16 GB | bootstrap-ai.sh --skip-langfuse. Drops the single most expensive layer. |
| Core + one AI component | 8 | 13 GB | 16 GB | The realistic ceiling on a 16 GB machine: core plus one of Langfuse, KAgent + 2 agents, or MLflow. |
| Without AI/ML | 4 | 8 GB | 12 GB | bootstrap-local.sh only; don't run bootstrap-ai.sh. |
| Core only | 2 | 6 GB | 8 GB | Add --skip-obs --skip-policies (see below). |
A 16 GB Mac cannot run the full platform. It yields a ~13 GB VM against ~11.8 GB of workload, and the ~1.2 GB left is under the degradation threshold above. That is not a tuning problem — install a subset:
1 2 | |
--agents prunes: re-running with a shorter list removes the agents you left
out, so always pass the full set you want. --agents list prints what is
available.
Since the VM is carved out of your host, the recommended tier wants a 16 GB host at an absolute minimum, 24–32 GB to be comfortable — a 16 GB laptop giving 12 GB to the VM leaves very little for the rest of macOS.
Reading
kubectl get nodescorrectly: it reports the CPU/memory of the VM against each Kind node, so a 2-node cluster on a 6-CPU/12 GB VM looks like 12 CPUs and 24 GB. It isn't — both nodes are containers sharing the one VM. The real ceiling is whatever you gave Docker/Rancher Desktop.
Symptoms of an under-resourced cluster¶
These all look like different bugs but share one cause — CPU starvation making pods miss their liveness probes, so kubelet restarts them in a loop:
503 Service Temporarily Unavailablefrom nginx ongrafana.idp.localand friends, clearing on its own after ~30s- Pods with a high
RESTARTScount butReason: Error/ exit code 137 (killed on liveness, not OOMKilled) etcdelection timeouts, orlima-guestagentdying, taking the whole cluster with it- Bootstrap steps timing out on
--waitthat succeed when re-run
Confirm before you tune anything — if nr_throttled is a large fraction of
nr_periods, the container is CPU-throttled and needs a higher limit or a
bigger VM, not a more lenient probe:
1 2 | |
Running on less¶
Trim from the bottom of the value/cost list. Each flag is independent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
If you're below the "core only" tier, don't run the platform locally — use a
cloud dev box, or deploy to AWS with ./scripts/bootstrap.sh.
Choosing which KAgent agents run¶
bootstrap-ai.sh installs six agents by default — idp, qa, release,
cost, platform, contract. Three more ship in the repo but are not
installed unless asked for: incident, security, onboarding.
Each agent is one Deployment running the kagent/app Python image, so the
count maps directly to CPU pressure. Narrow it with --agents:
| Value | Result |
|---|---|
| (omitted) | The six defaults — unchanged behaviour |
--agents idp |
One agent |
--agents idp,qa |
Any comma-separated subset |
--agents all |
All nine |
--agents none |
KAgent runtime and UI install, zero agent pods |
--agents list |
Print the available agents and exit |
Two things worth knowing:
- There is one toolserver, and it is automatic. Every agent references a
single
RemoteMCPServernamedai-gateway, applied for you. It creates no pods of its own; the AI Gateway it points at is one ~9Mi pod that multiplexes all eight MCP servers. Agents stay genuinely independent — each still gets only the tools in its own allowlist, so enabling one can never break another. - Deselected agents are pruned. Re-running with a shorter list deletes the agents you dropped rather than leaving the previous run's pods consuming CPU. An unknown agent name fails immediately, before anything is installed.
Loki and Tempo ship disabled¶
The log and trace backends — Loki, Promtail, and Tempo — are installed as Helm releases but run zero pods locally. Prometheus, Grafana, and OpenCost are unaffected; only log aggregation and distributed tracing are off, so the Grafana Loki and Tempo datasources return nothing.
This is a deliberate capacity decision. A single-node Kind cluster on a 8CPU/16GB
machine already sits at roughly 380% CPU overcommit on limits with the rest
of the platform up. Adding these three starves the control plane rather than
merely slowing it: components answer /healthz too slowly and get probe-killed,
and kube-controller-manager / kube-scheduler lose leadership when their
leases miss the 5s renewal deadline. The symptom is a cluster that looks like
eight unrelated things are broken at once.
To turn them back on — give the node more CPU and memory first:
| Component | Where | Change |
|---|---|---|
| Tempo | local/observability/tempo/tempo-values.yaml |
replicas: 0 → 1 |
| Promtail | local/observability/loki/promtail-values.yaml |
delete the nodeSelector: {idp/disabled} block |
| Loki | scripts/bootstrap-local.sh (step 5c) |
remove the kubectl scale statefulset loki --replicas=0 line |
Loki is the odd one out: its chart's singleBinaryReplicas helper hardcodes 1
unless object storage is in use, so singleBinary.replicas cannot express 0
and the scale-down has to happen after install.
The URL banner only advertises the Loki and Tempo endpoints when their StatefulSets are actually scaled above zero, so it will start listing them once you re-enable them.
Bootstrap (~10–15 min)¶
First time? Run
setup.shand nothing else. From the repo root:It personalises the placeholders, then calls
1./scripts/setup.sh # choose "local" when promptedbootstrap-local.shfor you and offers to start Backstage. Don't also runbootstrap-local.shyourself — that just repeats the whole 15–20 minute install.
Run the command below only for day-2 work on an existing setup — recreating
the cluster after --destroy, or re-running a step that failed:
1 | |
What it does (in order):
| Step | What |
|---|---|
| 1 | Starts a local container registry on localhost:5003 |
| 2 | Creates a Kind cluster (kind-idp-mvp) with the registry wired in |
| 3 | Creates platform namespaces and RBAC |
| 4 | Installs nginx ingress controller (host ports 80/443) |
| 4b | Installs metrics-server (required for CPU/memory in Backstage) |
| 4c | Wires Backstage K8s Service + nginx Ingress |
| 5 | Installs Prometheus + Grafana + AlertManager (kube-prometheus-stack) |
| 5b | Installs OpenCost |
| 6 | Builds and deploys hello-service via the golden-path Helm chart |
| 7 | Writes /etc/hosts entries for *.idp.local and flushes DNS cache |
| 8 | Installs ArgoCD |
| 8b | (Optional) Installs Argo Workflows for ML pipeline orchestration (use --install-argo-workflows flag) |
| 9 | Installs OPA/Gatekeeper and applies all five policy constraints |
| 10 | Installs Prometheus Pushgateway + DORA exporter CronJob + catalog exporter CronJob |
| 11 | Deploys Tech Insights Exporter CronJob (scorecard metrics → Pushgateway every 15 min) |
| 12 | Wires AlertManager Slack webhook (if SLACK_WEBHOOK_URL is set) |
| 13 | Applies ArgoCD idp-services ApplicationSet — auto-discovers services/* and deploys hello-service, idp-mcp-server, and qa-mcp-server to services-dev. contract-mcp-server is excluded from the ApplicationSet and is only deployed by bootstrap-ai.sh. Removes the bootstrap-deployed hello-service from the services namespace. |
Bootstrap flags¶
1 2 3 4 5 6 | |
Flags can be combined: --skip-obs --skip-gitops cuts bootstrap time roughly in half. For which flags to reach for on a resource-constrained machine, and how much each one saves, see Running on less.
Access services¶
/etc/hosts entries are written automatically by bootstrap-local.sh. If you need to add them manually:
1 | |
| Service | URL | Credentials |
|---|---|---|
| Backstage | http://backstage.idp.local (or http://localhost:3000) | — (guest mode) |
| AI Assistant | http://backstage.idp.local/ai-assistant | — (integrated in Backstage; hidden until bootstrap-ai.sh runs — see why) |
| hello-service | http://hello-service.idp.local | — (managed by ArgoCD in services-dev as hello-service-local-service-template) |
| Grafana | http://grafana.idp.local | admin / admin |
| ArgoCD | http://argocd.idp.local | admin / (see below) |
| Prometheus | http://prometheus.idp.local | — |
| AlertManager | http://alertmanager.idp.local | — |
| Argo Rollouts | http://argo-rollouts.idp.local | — (canary/progressive-delivery dashboard) |
| Tempo (traces) | Scaled to 0 by default — see Loki and Tempo ship disabled. Once enabled: http://grafana.idp.local/explore → select the Tempo datasource | — (Tempo has no UI of its own) |
| ↳ Tempo OTLP ingest | Once enabled: POST http://tempo.idp.local/v1/traces — an API endpoint, not a page. Opening it in a browser returns 405 method not allowed, supported: [POST], and / returns 404 page not found; both mean Tempo is up. Health: /ready |
— |
| Loki (logs) | Scaled to 0 by default — see Loki and Tempo ship disabled. Once enabled: http://grafana.idp.local/explore → select the Loki datasource | — |
| OpenCost | http://opencost.idp.local | — |
| Pushgateway | http://pushgateway.idp.local | — |
| KAgent UI | http://kagent.idp.local | — (agent management) |
| MLflow | http://mlflow.idp.local | — (experiment tracking & model registry) |
| Argo Workflows | http://argo-workflows.idp.local | — (if --install-argo-workflows flag used) |
| Local registry | localhost:5003 | — (no auth) |
ArgoCD initial admin password:
1 2 | |
Alternatively, use kubectl port-forward for any service:
1 | |
Start Backstage¶
bootstrap-local.sh sets up the cluster and platform but does not start Backstage. Run this after the cluster is up:
1 | |
This single command:
1. Builds the Backstage Docker image
2. Starts the Docker Compose stack
3. Waits for the container to join the kind network
4. Wires the nginx ingress endpoint to the live container IP
5. Seeds sample QA metrics into Pushgateway
6. Triggers an immediate catalog export
7. Prints the full access-URL summary
Backstage is then available at http://backstage.idp.local (or http://localhost:3000 as a direct fallback).
Note: Backstage uses
dangerouslyDisableDefaultAuthPolicy: trueinapp-config.local.yamlso the catalog loads and is accessible before sign-in completes (prevents 401 flash on first page load in Backstage v1.29+).
Known platform patches¶
The Backstage image bundles two repo-local patches that are applied automatically — you do not need to do anything, but knowing they exist saves debugging time:
| Patch | Location | Why it exists |
|---|---|---|
@material-table/core v3 → uuid v10 default-export shim |
backstage/app/.yarn/patches/@material-table-core-npm-3.2.5-*.patch |
uuid v10 dropped its default export; without the patch, the catalog, api-docs, and techdocs pages crash with Cannot read properties of undefined (reading 'v4'). Verify with grep "uuid.*v4" backstage/app/node_modules/@material-table/core/dist/utils/data-manager.js — expect (_uuid["default"] \|\| _uuid).v4(). |
vm2-shim (replacing abandoned vm2) |
backstage/app/vm2-shim/ |
vm2 was pulled in transitively via typescript-json-schema → @backstage/config-loader and has no upstream security fix. The shim is a thin wrapper over Node's built-in vm module and is copied into the image before yarn workspaces focus runs. |
Both patches are tracked in git and re-applied automatically by yarn install and by the multi-stage backstage/Dockerfile. If you ever see catalog tables fail to render or scaffolder actions crash on startup, re-run yarn install inside backstage/app/ and rebuild the image.
Environment files (first time only)¶
1 2 3 4 5 6 | |
AI/ML Platform (Optional):
- ANTHROPIC_API_KEY — Required to enable Claude API for KAgent agents (used by bootstrap-ai.sh)
- OPENAI_API_KEY — Required to enable OpenAI GPT-4o support via the modelconfig-openai CRD (used by bootstrap-ai.sh)
If these are not set, the AI/ML platform still deploys but agents/models using those providers will fail gracefully.
K8s credentials (
K8S_CLUSTER_URL,K8S_SERVICE_ACCOUNT_TOKEN,K8S_CLUSTER_CA_DATA) are written tolocal/backstage/.envautomatically bybootstrap-local.shviaget-k8s-credentials.sh. No manual step needed if you bootstrapped with that script.
Troubleshooting observability after bootstrap¶
DORA metrics not appearing in Grafana / Pushgateway empty
The dora-exporter CronJob runs every 15 minutes. If metrics are absent immediately after bootstrap, trigger a manual run:
1 2 | |
If the job fails with python: can't open file '/scripts/dora-exporter.py', the ConfigMap was not populated. Re-run the bootstrap step:
1 2 3 | |
Kubernetes tab shows "unknown" for CPU / Memory
Ensure skipMetricsLookup: false is set in backstage/app-config.yaml and that the metrics-server is running:
1 2 | |
catalog-exporter CrashLoopBackOff
The CronJob targets backstage.default.svc.cluster.local:3000. It will fail whenever Backstage is not running. Start Backstage first:
1 | |
Day-2 Backstage restart¶
If you restart Docker Compose manually, re-run --start-backstage to rewire the nginx endpoint:
1 | |
Or, if you only need to refresh the IP without reseeding metrics:
1 | |
Manual backend bundle rebuild¶
Only needed if you changed code under backstage/app/packages/backend/src/:
1 2 3 | |
Deploy a service via Backstage¶
Scaffold a new service¶
- Open http://backstage.idp.local → Create
- Choose Node.js Service or Python FastAPI Service
- Fill in name, description, owner, GitHub repo
- Click Create — Backstage publishes the repo to GitHub and registers it in the catalog
Deploy to local Kind¶
The platform includes a custom idp:deploy-local action and a dedicated template.
Prerequisites:
- Kind cluster and Backstage running (./scripts/bootstrap-local.sh then ./scripts/bootstrap-local.sh --start-backstage)
- Image pushed to local registry (see below)
Push the image:
1 2 3 | |
Deploy via Backstage:
1. Open http://backstage.idp.local → Create
2. Choose Deploy Service to local Kind cluster
3. Pick the service from the catalog, set image tag (latest)
4. Click Create
The action runs helm upgrade --install and logs pod status. It connects to Kind via a rewritten kubeconfig (127.0.0.1 → host.docker.internal) mounted into the Backstage container.
Deploy via CLI (alternative):
1 2 3 4 5 | |
Scaffold and test a new service locally (CLI path)¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Local vs AWS — what's different¶
| Concern | Local | AWS |
|---|---|---|
| Ingress class | nginx |
alb (but ingress.enabled: false by default — scaffolded services get no ALB unless opted in) |
| Image pull | localhost:5003/<name> |
<account>.dkr.ecr.<region>.amazonaws.com/idp-mvp/<name> |
| Auth | none | OIDC (GitHub Actions), IRSA (pods) |
| CD trigger | idp:deploy-local Backstage action |
GitHub Actions push to main |
| Observability | Prometheus in-cluster | CloudWatch + Grafana |
| Helm values file | helm-values-local.yaml |
helm-values-aws.yaml |
| Persistent storage | hostPath / emptyDir | EBS (gp2/gp3) |
The Helm chart (helm/service-template) is identical for both. Only the values file differs.
AI/ML Stack (Optional)¶
After bootstrap-local.sh (and optionally --start-backstage) completes, boot the AI/ML platform:
1 2 | |
What it installs:
- KAgent platform — Kubernetes-native AI agents with idp-assistant, qa-assistant, contract-assistant agents
- MCP servers — Model Context Protocol servers: idp-mcp-server (6 IDP tools), qa-mcp-server (QA tools), contract-mcp-server (contract testing tools)
- MLflow — Experiment tracking and model registry at http://mlflow.idp.local
- OpenAI ModelConfig — GPT-4o support if OPENAI_API_KEY is set; Claude Anthropic support if ANTHROPIC_API_KEY is set
- AI Observability — Grafana dashboard with MCP tool metrics, latency, cost attribution per server
AI-Native Platform Features (Phase 7a Complete)¶
Priority 1: AI Platform Foundations ✅¶
- OpenAI ModelConfig CRD — Deploy agents using GPT-4o in addition to Claude
- AI Observability Dashboard — Monitor MCP tool calls, latency, error rates in Grafana
- RAG Document Indexing — AI search across TechDocs and runbooks via
/ai-searchpage
Priority 2: AI Service Lifecycle ✅¶
- Model Serving API Template — Deploy Ollama (local) or vLLM (AWS) inference servers via Backstage
- AI Platform Scorecard — Tech Insights checks for model cards, eval suites, observability (Bronze/Silver/Gold)
- Prompt Lifecycle Management — System prompts in ConfigMaps for zero-downtime updates
Priority 3: ML Workflows & Cost Attribution ✅¶
- Argo Workflows — Multi-step ML pipeline orchestration (optional; use
--install-argo-workflowsflag in bootstrap-local.sh) - Cost Attribution — Team labels on agents,
ai_api_calls_totalmetrics for cost tracking per model
Scaffold AI services¶
After bootstrap-ai.sh completes, use the templates from Backstage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Monitor AI Platform¶
1 2 3 4 5 6 7 8 9 10 11 | |
This installs KAgent (AI agent runtime), the IDP MCP Server, and MLflow.
The AI Assistant at /ai-assistant is a native React chat UI (not an iframe) that talks directly to the KAgent A2A API via the Backstage proxy.
| Service | URL | Notes |
|---|---|---|
| KAgent UI | http://kagent.idp.local | Direct agent chat UI |
| AI Assistant | http://backstage.idp.local/ai-assistant | Backstage-embedded native React chat UI |
| AI Search | http://backstage.idp.local/ai-search | Semantic search (requires VOYAGE_API_KEY) |
| IDP Assistant (A2A) | http://idp-assistant.idp.local | A2A agent endpoint |
| MLflow UI | http://mlflow.idp.local | Experiment tracking |
| IDP MCP Server health | http://idp-mcp-server.idp.local/healthz | MCP server status |
Skip flags (combine freely):
1 2 3 | |
Tear down AI/ML only (core platform stays up):
1 2 3 4 5 | |
Warning:
bootstrap-ai.sh --destroyscopes deletions to the active environment (--awsflag). Running without--awswhileKUBECONFIGpoints at EKS will target AWS resources unintentionally.Certificate error on
kagent.idp.localafterbootstrap-ai.sh? The KAgent ingresses are HTTP-only as of commitfe4fce2. If you ran an earlier version of this repo on the same machine, your browser may have cached HSTS for*.idp.localfrom the old HTTPS-with-mkcert ingress and will keep upgrading the request to HTTPS, against which nginx-ingress responds with a fake default cert. Fix: openchrome://net-internals/#hsts, Delete domain security policies forkagent.idp.localandidp-assistant.idp.local, disable Settings → Privacy → Always use secure connections (or exclude*.idp.local), and hard-reload. On a fresh clone you'll never hit this.
Using the AI Assistant in Backstage¶
Open http://backstage.idp.local/ai-assistant (or click AI Assistant in the sidebar). The assistant can:
- Search the service catalog: "find all Python services owned by qa-platform-team"
- Check metrics: "show request rate for hello-service"
- List running deployments: "what's deployed in the services namespace?"
- Scaffold a new service: "scaffold a Python FastAPI service called demo, description demo API, owner group:default/platform-team"
For scaffolding, provide name, description, and owner in one message — the
agent will call the scaffolder immediately without asking for confirmation.
Enabling AI Search (semantic / RAG)¶
The /ai-search page provides semantic search over the catalog using Voyage AI
embeddings stored in pgvector. To enable it, add your Voyage AI key to
local/backstage/.env before starting Backstage:
1 | |
The Postgres image used by Docker Compose (pgvector/pgvector:pg17) and
local/backstage/init-pgvector.sql handle the vector extension and table
automatically on first Postgres startup — no manual SQL step needed.
Without VOYAGE_API_KEY, the page loads but search returns HTTP 503. All other
features are unaffected.
See docs/ai-assistant.md for the full architecture and troubleshooting guide.
Known limitations (local)¶
| Page | Status | Reason |
|---|---|---|
/kubernetes standalone |
Disabled | Requires entity context — use the Kubernetes tab on a catalog entity instead |
/catalog-graph |
Disabled | Disabled pending fix |
/ai-search |
Requires VOYAGE_API_KEY |
Returns 503 without the key; all other features unaffected |
| Cost Overview | Shows "OpenCost returned 500" if OpenCost is not running | Check kubectl get pods -n opencost |
Troubleshooting¶
For a full catalogue of setup and day-2 issues with diagnosis commands and fixes, see docs/TROUBLESHOOTING.md.
Teardown¶
1 | |
The destroy sequence runs in this order:
- AI/ML teardown — if
kagent,ml-platform, orservices-devnamespaces exist, callsbootstrap-ai.sh --destroy(local scope only;aws/manifests are never touched). - Scaffolded service cleanup — auto-discovers every service in
services/that is not a platform built-in (hello-service,idp-mcp-server,qa-mcp-server,contract-mcp-server). For each one:- Deletes the ArgoCD Application (cascade-deletes all managed K8s resources)
- Uninstalls the Helm release from
services-dev/services - Removes the
services/<name>/directory from the repo and commits + pushes it ([skip ci])
- Cluster deletion — Kind:
kind delete cluster; Rancher Desktop: deletes all platform namespaces. - Docker cleanup — stops the Backstage compose stack, prunes images and volumes.
/etc/hostscleanup — removes all IDP hostname entries.