Skip to content

docs(platforms): supported-host matrix and air-gapped install runbook#927

Merged
stubbi merged 2 commits into
mainfrom
docs/selfhost-platform-matrix
Jul 16, 2026
Merged

docs(platforms): supported-host matrix and air-gapped install runbook#927
stubbi merged 2 commits into
mainfrom
docs/selfhost-platform-matrix

Conversation

@stubbi

@stubbi stubbi commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Thinking Path

  • Mitos self-hosts on Kubernetes with a control plane (controller, gateway, facade, console) and KVM workers (forkd plus husk pods that boot Firecracker microVMs); self-host is a first-class, Apache-2.0 peer of the hosted product.
  • The host requirements live in host-prerequisites.md and are enforced by mitos doctor, but there was no single page mapping requirements to host TYPES, so an operator learned a node was unsuitable only by running doctor on it and reading a rejection.
  • Separately, the offline story was advertised (the E2B migration doc names air-gapped as a headline) with no runbook behind it, a journey-rule dead end for a regulated or disconnected self-hoster.
  • These need fixing now because the self-hosted first-run must have no dead ends (Experience is DNA) and self-host is a peer surface, not an afterthought.
  • This pull request adds a host-support matrix and an air-gapped install runbook, both grounded in the real chart values and doctor checks, and cross-links them so neither is a dead end.
  • The benefit is that an operator can decide up front which machines to buy or pool and can install fully offline without reverse-engineering the chart.

Linked Issues or Issue Description

Closes #777. Closes #788.

What Changed

  • docs/platforms/supported-hosts.md: a matrix of host types against KVM-worker supportability, each requirement tied to its mitos doctor check, splitting control-plane from KVM-worker requirements. Explicit that bare metal is supported, nested-virt cloud instances are supported if doctor passes, and plain cloud VMs / rescue kernels are not workers.
  • docs/platforms/air-gapped.md: an offline runbook that stages the container images (the real ghcr.io/mitos-run list), the OCI Helm chart, and the per-node guest kernel plus Firecracker binary, then installs against them via image.registry and global.imageTag. Notes the runtime dials no third-party SaaS and that hosted-only surfaces are capability-gated off.
  • prerequisites.md: a See also linking both new pages.

Verification

  • Content is grounded in verified facts: the chart image keys (image.registry, global.imageTag, per-component repository) from deploy/charts/mitos/values.yaml; the mitos doctor checks from internal/agentcli/doctor.go; the host requirements from host-prerequisites.md; the Firecracker patched-binary path from hack/install-firecracker-patched.sh.
  • No em or en dashes; all internal links point to sibling docs/platforms pages.
  • Docs-only change: no code paths touched.

Risks

Low risk. Documentation only. The pages describe existing, shipped behavior (the chart levers and doctor checks already exist); they add no claims that are not reproducible from the chart and the doctor command.

Model Used

Claude Opus 4.8 (claude-opus-4-8), 1M context, extended thinking.

Summary by CodeRabbit

  • Documentation
    • Added an offline installation runbook covering image and Helm chart mirroring, node preparation, installation, and readiness checks.
    • Documented offline deployment limitations, including unavailable hosted-only capabilities.
    • Added a host-support matrix covering control-plane and KVM worker requirements.
    • Documented supported and unsupported host environments, kernel requirements, and acceptance checks.
    • Added cross-references between platform prerequisites, supported hosts, and air-gapped installation guidance.

Jannes Stubbemann added 2 commits July 16, 2026 12:02
Two self-host gaps left the journey with dead ends. There was no single
page saying which machines can be KVM workers versus control-plane only, so
the requirement was discoverable only by hitting mitos doctor on a rejected
node. And the offline story was sold (for example in the E2B migration doc)
with no runbook behind it.

Add docs/platforms/supported-hosts.md: a host-support matrix that ties each
requirement to the mitos doctor check that gates it, splits control-plane
from KVM-worker requirements, and is explicit about bare metal (supported),
nested-virt cloud instances (supported if doctor passes), plain cloud VMs
and rescue kernels (not supported as workers).

Add docs/platforms/air-gapped.md: an offline runbook that stages the three
things an install needs inside the boundary (the container images under
ghcr.io/mitos-run, the OCI Helm chart, and the per-node guest kernel plus
Firecracker binary), installs against them via image.registry and
global.imageTag, and notes that the runtime dials no third-party SaaS.

Cross-link both from prerequisites.md so neither is a dead end.

Closes #777
Closes #788

Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds platform documentation for supported host requirements, mitos doctor checks, and a staged air-gapped installation workflow, with prerequisite links connecting the new guidance.

Changes

Platform documentation

Layer / File(s) Summary
Supported host requirements
docs/platforms/supported-hosts.md, docs/platforms/prerequisites.md
Documents control-plane and KVM-worker requirements, host support classifications, conditional userfaultfd behavior, and links to related platform guides.
Air-gapped installation workflow
docs/platforms/air-gapped.md
Describes mirroring images and the Helm chart, staging microVM assets, installing from an internal registry, running mitos doctor, and offline capability boundaries.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • mitos-run/mitos#798: Updates installation guidance for Helm chart installation through an OCI registry, related to the offline chart-mirroring workflow.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main required sections, but it omits the template's Checklist section. Add the Checklist section and complete the required checkboxes, including tests, model used, signed-off-by, and any relevant security items.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main docs change: host support guidance and an air-gapped install runbook.
Linked Issues check ✅ Passed The new docs appear to satisfy #777 and #788 by adding the host matrix, doctor-gated requirements, and the offline install runbook.
Out of Scope Changes check ✅ Passed The changes stay within documentation scope and the linked platform docs, with no unrelated additions apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/selfhost-platform-matrix

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/platforms/air-gapped.md`:
- Around line 86-91: Update the mitos doctor documentation to accurately
describe its offline behavior: when kubeconfig is available, checks may contact
the Kubernetes cluster API; without it, cluster checks report errors while node
checks still run. Clarify that pre-install execution can exit non-zero because
cluster checks are unavailable, and remove the claim that every check reads only
the local host.
- Around line 74-78: Update the Helm installation flow in the air-gapped
platform instructions to create and label the mitos namespace with
pod-security.kubernetes.io/enforce=privileged before running helm install.
Remove reliance on --create-namespace so the installation uses the pre-labeled
namespace while preserving the existing chart, version, registry, and image tag
options.
- Around line 3-9: Revise the introductory scope in the air-gapped runbook to
guarantee only absence of third-party SaaS connectivity for the specified
release/version boundary. Remove or qualify claims that the product is fully
offline or not degraded, and explicitly distinguish this guarantee from required
internal registry, Kubernetes, and in-cluster network traffic.

In `@docs/platforms/supported-hosts.md`:
- Around line 49-50: Update the definition of “Supported” in the platform
documentation to state that any conformant Kubernetes node can host the control
plane, while preserving the distinction that supported hosts can be KVM workers
and unsupported hosts cannot.
- Around line 9-12: Update the supported KVM worker rule in the documentation to
define support as having no required check with FAIL status rather than
requiring every signal to pass. Clarify that WARN results, including unavailable
userfaultfd or failed data-directory probing, indicate degraded or unverifiable
capability and do not make the machine unsupported, while retaining the non-zero
FAIL and remediation behavior.
- Around line 33-42: Update the supported-hosts requirements matrix to
accurately distinguish rows backed by named mitos doctor checks from
prerequisite-only requirements: use kernel-module-nf_tables for nf_tables, and
either separate the real-filesystem prerequisite row or revise the matrix
introduction so it no longer implies every row has a doctor check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 91d7a82a-c347-47df-b5de-af10d8cafab4

📥 Commits

Reviewing files that changed from the base of the PR and between f5aa492 and 327d3e9.

📒 Files selected for processing (3)
  • docs/platforms/air-gapped.md
  • docs/platforms/prerequisites.md
  • docs/platforms/supported-hosts.md

Comment on lines +3 to +9
mitos self-hosts fully offline. Nothing in the runtime dials a third-party SaaS:
billing, self-serve signup, and abuse checks are hosted-only surfaces that are
capability-gated off by default, so an air-gapped install is a clean, complete
product, not a degraded one. What an offline install needs is exactly three
things staged inside the boundary: the container images, the Helm chart, and the
per-node microVM assets (guest kernel and Firecracker). This runbook stages each
one and installs against them.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target doc and nearby references
git ls-files docs/platforms/air-gapped.md
wc -l docs/platforms/air-gapped.md
cat -n docs/platforms/air-gapped.md | sed -n '1,140p'

printf '\n--- related references ---\n'
rg -n "fully offline|air-gapped|third-party SaaS|billing|self-serve signup|abuse checks|Helm chart|Firecracker|guest kernel|runtime dials" docs . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: mitos-run/mitos

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- docs/platforms/air-gapped.md ---\n'
cat -n docs/platforms/air-gapped.md | sed -n '1,120p'

printf '\n--- precise references ---\n'
rg -n -m 40 "fully offline|third-party SaaS|hosted-only surfaces|capability-gated off by default|clean, complete product|degraded one|exactly three things|internal Kubernetes|cluster-network" docs internal

Repository: mitos-run/mitos

Length of output: 244


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf -- '--- docs/platforms/air-gapped.md ---\n'
cat -n docs/platforms/air-gapped.md | sed -n '1,140p'

printf -- '\n--- precise references ---\n'
rg -n -m 40 "fully offline|third-party SaaS|hosted-only surfaces|capability-gated off by default|clean, complete product|degraded one|exactly three things|internal Kubernetes|cluster-network" docs internal

Repository: mitos-run/mitos

Length of output: 6850


Scope the offline guarantee to external connectivity. “Fully offline” and “not a degraded product” are broader than the contract here; keep this tied to the release/version boundary and separate “no third-party SaaS calls” from the internal registry and in-cluster Kubernetes/network traffic this install still depends on.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/air-gapped.md` around lines 3 - 9, Revise the introductory
scope in the air-gapped runbook to guarantee only absence of third-party SaaS
connectivity for the specified release/version boundary. Remove or qualify
claims that the product is fully offline or not degraded, and explicitly
distinguish this guarantee from required internal registry, Kubernetes, and
in-cluster network traffic.

Comment on lines +74 to +78
helm install mitos oci://registry.internal/mitos/charts/mitos \
--version X.Y.Z -n mitos --create-namespace \
--set image.registry=registry.internal/mitos \
--set global.imageTag=vX.Y.Z
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Label the namespace before installing.

prerequisites.md states that the install namespace must be labeled pod-security.kubernetes.io/enforce=privileged and that Helm cannot create this label. Using --create-namespace here creates an unlabeled namespace, so PSA-enabled clusters can reject the workloads.

Proposed command flow
-helm install mitos oci://registry.internal/mitos/charts/mitos \
-  --version X.Y.Z -n mitos --create-namespace \
+kubectl create namespace mitos
+kubectl label namespace mitos \
+  pod-security.kubernetes.io/enforce=privileged --overwrite
+helm install mitos oci://registry.internal/mitos/charts/mitos \
+  --version X.Y.Z -n mitos \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
helm install mitos oci://registry.internal/mitos/charts/mitos \
--version X.Y.Z -n mitos --create-namespace \
--set image.registry=registry.internal/mitos \
--set global.imageTag=vX.Y.Z
```
kubectl create namespace mitos
kubectl label namespace mitos \
pod-security.kubernetes.io/enforce=privileged --overwrite
helm install mitos oci://registry.internal/mitos/charts/mitos \
--version X.Y.Z -n mitos \
--set image.registry=registry.internal/mitos \
--set global.imageTag=vX.Y.Z
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/air-gapped.md` around lines 74 - 78, Update the Helm
installation flow in the air-gapped platform instructions to create and label
the mitos namespace with pod-security.kubernetes.io/enforce=privileged before
running helm install. Remove reliance on --create-namespace so the installation
uses the pre-labeled namespace while preserving the existing chart, version,
registry, and image tag options.

Comment on lines +86 to +91
`mitos doctor` is offline-safe: every check reads the local host, none dial out.
Run it on each KVM worker before and after install:

```bash
mitos doctor
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Clarify mitos doctor’s offline behavior.

cmd/mitos/main.go attaches a Kubernetes client when kubeconfig is available, so doctor can contact the cluster API. Without kubeconfig, cluster checks report errors while node checks still run. Do not say every check reads only the local host; explain that pre-install execution may exit non-zero because cluster checks are unavailable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/air-gapped.md` around lines 86 - 91, Update the mitos doctor
documentation to accurately describe its offline behavior: when kubeconfig is
available, checks may contact the Kubernetes cluster API; without it, cluster
checks report errors while node checks still run. Clarify that pre-install
execution can exit non-zero because cluster checks are unavailable, and remove
the claim that every check reads only the local host.

Comment on lines +9 to +12
The rule is simple and mechanical: a machine is a supported **KVM worker** if it
passes `mitos doctor`. That command is the per-requirement hard gate; it exits
non-zero and prints an actionable remediation for every requirement it finds
unmet, so you never have to guess why a node was rejected.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Separate FAIL gates from WARN-only checks.

internal/agentcli/doctor.go returns WARN when userfaultfd is unavailable and when data-directory probing fails, so not every unmet signal is a hard, non-zero gate. Document support as “no required check is FAIL”; describe WARN as degraded or unverifiable capability.

Also applies to: 44-45

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/supported-hosts.md` around lines 9 - 12, Update the supported
KVM worker rule in the documentation to define support as having no required
check with FAIL status rather than requiring every signal to pass. Clarify that
WARN results, including unavailable userfaultfd or failed data-directory
probing, indicate degraded or unverifiable capability and do not make the
machine unsupported, while retaining the non-zero FAIL and remediation behavior.

Comment on lines +33 to +42
| Requirement | `mitos doctor` check | Needed for |
| --- | --- | --- |
| `/dev/kvm` present and usable | `kvm-device` | booting every microVM |
| `kvm_intel` / `kvm_amd` loaded | `kernel-module-*` | KVM acceleration |
| `vhost_vsock` module | `kernel-module-vhost_vsock` | guest agent exec/files/env over vsock |
| `tun` module | `kernel-module-tun` | per-sandbox tap networking |
| `nf_tables` support | (see prerequisites) | husk egress isolation and kube-proxy |
| containerd on a real filesystem | (see prerequisites) | the overlay snapshotter cannot stack on overlay/tmpfs |
| adequate free space on `--data-dir` | `data-dir-space` | template rootfs images, snapshots, jailer chroots |
| `CONFIG_USERFAULTFD=y` (perf path) | `userfaultfd` | hugepage-backed restore and snapshot-resume prefetch |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- supported-hosts.md (relevant slice) ---'
nl -ba docs/platforms/supported-hosts.md | sed -n '20,70p'

echo
echo '--- doctor-check references ---'
rg -n "kvm-device|kernel-module-|vhost_vsock|tun|nf_tables|data-dir-space|userfaultfd|prerequisites|containerd on a real filesystem" docs src . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || true

Repository: mitos-run/mitos

Length of output: 237


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- supported-hosts.md (relevant slice) ---'
sed -n '20,70p' docs/platforms/supported-hosts.md | cat -n

echo
echo '--- search for check names and prerequisite wording ---'
rg -n "kvm-device|kernel-module-|vhost_vsock|kernel-module-vhost_vsock|kernel-module-tun|nf_tables|data-dir-space|userfaultfd|real filesystem|overlay snapshotter|prerequisite" docs . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || true

Repository: mitos-run/mitos

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- docs/cli.md around doctor checks ---'
sed -n '200,235p' docs/cli.md | cat -n

echo
echo '--- docs/platforms/prerequisites.md relevant rows ---'
sed -n '12,45p' docs/platforms/prerequisites.md | cat -n

echo
echo '--- docs/platforms/host-prerequisites.md relevant rows ---'
sed -n '12,40p' docs/platforms/host-prerequisites.md | cat -n

Repository: mitos-run/mitos

Length of output: 6988


Align the matrix with mitos doctor

  • nf_tables has an actual doctor check (kernel-module-nf_tables); the real-filesystem requirement is prerequisite-only and doesn’t map to a doctor check name.
  • Either split prerequisite-only rows out, or change the intro so it doesn’t claim every row names a mitos doctor check.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/supported-hosts.md` around lines 33 - 42, Update the
supported-hosts requirements matrix to accurately distinguish rows backed by
named mitos doctor checks from prerequisite-only requirements: use
kernel-module-nf_tables for nf_tables, and either separate the real-filesystem
prerequisite row or revise the matrix introduction so it no longer implies every
row has a doctor check.

Comment on lines +49 to +50
"Supported" below means "can be a KVM worker". Anything can host the control
plane.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not claim that “anything” can host the control plane.

The prerequisite documentation limits this to conformant Kubernetes nodes. Replace this with “any conformant Kubernetes node” and preserve the supported/unsupported distinction.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/platforms/supported-hosts.md` around lines 49 - 50, Update the
definition of “Supported” in the platform documentation to state that any
conformant Kubernetes node can host the control plane, while preserving the
distinction that supported hosts can be KVM workers and unsupported hosts
cannot.

@stubbi
stubbi merged commit 9f0c2b8 into main Jul 16, 2026
35 of 36 checks passed
@stubbi
stubbi deleted the docs/selfhost-platform-matrix branch July 16, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant