Skip to content

Self-Host

Neutree Agent Platform — Self-HostInstall the platform on your own Kubernetes cluster, pulling images from public registries

What one install gives you

This is the connected / online installer: the target cluster must be able to reach the public internet. Images are pulled directly from public registries (ghcr.io / docker.io / registry.k8s.io) and prerequisite charts/manifests are fetched from their public sources. There is no offline image bundle, no in-cluster registry, and no host image-loading step. For fully air-gapped sites, a separate offline installer ships an image tarball, an in-cluster registry, and a host-prep step.

Core platform (always installed)

  • Control plane — agent management, scheduling, user and workspace management
  • Channel gateway — the entry point for external events (webhooks, Slack, etc.) to reach agents
  • Data layer — PostgreSQL (CloudNativePG) + shared NFS
  • Agent workspace runtime — one pod per workspace runs the agent; agents can @ each other, share files, and share a memory store

Optional modules (off by default)

  • Code Sandbox — lets agents run code and serve temporary web previews. Powered by the third-party OpenSandbox, which you install yourself; the platform points at it via OPENSANDBOX_URL
  • Remote Browser — lets agents drive a real browser while users watch live over WebRTC. Ships a bundled TURN relay (coturn) and a published headful Chromium image
  • LDAP — let users sign in with their LDAP account

Prerequisites

Infrastructure

ResourceRequirementNotes
Kubernetesv1.28+ (multi-node), or a single k3s node (single-node profile)3+ workers recommended
Worker nodes4 vCPU / 8GB RAM minimumAgent pods are created per workspace dynamically
Public registry accessNodes can pull from ghcr.io, docker.io, registry.k8s.ioOverride REGISTRY only to use a mirror
RWX shared storageA CSI that supports ReadWriteMany (NFS is the most common)Backs the AFS shared directory, 500Gi by default
RWO volume storageAny CSI that can run PostgreSQL (Ceph RBD, vSAN, etc.; the same NFS also works)PostgreSQL data volumes + agent workspace container disks

Network

ItemRequirement
Node IPAt least one worker IP reachable by users (NodePort uses it)
NodePort3 free ports in 30000–32767: TOS_NODE_PORT / BROWSER_NODE_PORT / SANDBOX_NODE_PORT
TURN portsWhen the Remote Browser's TURN relay is enabled: open 3478/tcp+udp and 49152-49252/udp on the coturn node
Storage reachabilityAll nodes can mount the two storage classes above (NFS / block-storage CSI, etc.)
Registry reachabilityAll nodes can pull images from the public registries

LLM API

The platform does not bundle any model. Depending on the agent types you enable, you must provide protocol-compatible API endpoints:

Agent typeAPI protocol required
CodexOpenAI Responses API (note: not Chat Completions)
Claude CodeAnthropic API

If your existing model service only supports the OpenAI Chat Completions API, one option is to put a translating proxy in front of it that converts the OpenAI Chat protocol to the Anthropic protocol, then point Claude Code-style agents at the proxy.

kubeconfig permissions

Installation requires cluster-admininstall.sh touches resources that a namespace-scoped admin cannot (CRDs, webhooks, ClusterRoles, StorageClasses, etc.). You can revoke it immediately after install; at steady state the control plane authenticates via its own in-cluster ServiceAccount with tightly scoped permissions (normal read/write within the namespace + cluster-scoped get/list on nodes only).

The operator's kubeconfig is never mounted into any platform pod. If a temporary cluster-admin is not acceptable, here is an equivalent minimal ClusterRole.

Equivalent minimal ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nap-installer
rules:
  - apiGroups: [apiextensions.k8s.io]
    resources: [customresourcedefinitions]
    verbs: [get, list, watch, create, update, patch, delete]
  - apiGroups: [admissionregistration.k8s.io]
    resources: [validatingwebhookconfigurations, mutatingwebhookconfigurations]
    verbs: [get, list, watch, create, update, patch, delete]
  - apiGroups: [""]
    resources: [namespaces]
    verbs: [get, list, create, update, patch]
  - apiGroups: [rbac.authorization.k8s.io]
    resources: [clusterroles, clusterrolebindings, roles, rolebindings]
    verbs: [get, list, watch, create, update, patch, delete]
  - apiGroups: [storage.k8s.io]
    resources: [storageclasses]
    verbs: [get, list, create, update, patch]
  - apiGroups: [postgresql.cnpg.io]
    resources: ["*"]
    verbs: ["*"]
  - apiGroups: [opensandbox.alibaba.com]
    resources: ["*"]
    verbs: ["*"]
  - apiGroups: ["", apps, batch, networking.k8s.io, policy]
    resources: ["*"]
    verbs: ["*"]
  - apiGroups: [""]
    resources: [nodes]
    verbs: [get, list, watch]

This is still close to cluster-admin in practice (*/* on the core/apps/batch groups), but spelling out the resources makes a security review easier.

Once the prerequisites are in place: