DRAForge is provider-neutral and can be deployed on any compatible Kubernetes cluster. The repository provides two primary profiles: a Demo Profile for rapid local exploration and a Production Profile for robust Helm deployment.
The local profile uses the same policy-pinned kind installation exercised by pull-request CI. It creates a Kubernetes v1.35.5 cluster with DRA enabled, installs the hash-verified NetworkPolicy CNI, builds and loads all three local images, installs the complete Helm release, runs the scenario/API verification suite, and keeps the verified cluster for exploration.
tests/install-e2e/kubernetes-versions.jsonDRAFORGE_INSTALL_E2E_KEEP_CLUSTER=1 task e2e:install-kind
The command uses cluster name draforge-install-e2e, installs DRAForge in namespace draforge-system, and leaves diagnostics under artifacts/install-e2e/.
Access the dashboard locally:
kubectl port-forward svc/draforge-server -n draforge-system 8080:8080
Then open http://localhost:8080. For CLI/TUI exploration in another terminal:
task build
./bin/draforge doctor
./bin/draforge tui
Delete the disposable cluster when finished:
kind delete cluster --name draforge-install-e2e
The production profile installs credential-free GHCR images and internal ClusterIP services. External dashboard exposure is disabled by default. The server, controller, and sim-driver repositories are separate, and an empty image tag resolves to the chart appVersion.
The controller enables Kubernetes Lease leader election by default. This keeps a single active writer even when controller.replicaCount is increased for availability.
kubectl configured with cluster administrator access.resource.k8s.io/v1. Core DRA is enabled by default on the supported baseline; distribution-specific configurations must still be verified.git clone https://github.com/oaslananka/draforge.git
cd draforge
helm install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace
The default render uses:
ghcr.io/oaslananka/draforge-server:<appVersion>ghcr.io/oaslananka/draforge-controller:<appVersion>ghcr.io/oaslananka/draforge-sim-driver:<appVersion>No image pull secret, Gateway, HTTPRoute, or Ingress is rendered by default.
helm upgrade --install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace \
--set-string server.image.digest=sha256:<server-digest> \
--set-string controller.image.digest=sha256:<controller-digest> \
--set-string nodePlugin.image.digest=sha256:<sim-driver-digest>
A configured digest takes precedence over the component tag.
kubectl get pods -n draforge-system
kubectl get svc -n draforge-system
kubectl port-forward svc/draforge-server -n draforge-system 8080:8080
The default chart uses nodePlugin.outputMode: demo. It writes two explicit test devices to a pod-local emptyDir, runs as UID 1000, and does not touch the host kubelet CDI directory.
Host-integrated output is an explicit opt-in:
helm upgrade --install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace \
--set nodePlugin.outputMode=node
Node mode mounts /var/lib/kubelet/device-plugins/cdi and therefore runs as UID 0 to write the root-owned host directory. It is still non-privileged: privilege escalation is disabled, all capabilities are dropped, the root filesystem is read-only, and RuntimeDefault seccomp remains enabled.
The sim-driver validates that the CDI directory is a writable, non-symlink directory. It writes mode 0644 files through a temporary file, fsync, and atomic rename. Kubernetes API or write failures do not introduce static fallback devices or truncate the current document; the pod becomes not-ready and preserves the last-known-good CDI file until a refresh succeeds. Kubelet probes use /healthz and /readyz on port 8083.
For a disposable cluster, the local demo profile enables direct HTTP routing and wildcard CORS:
helm upgrade --install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace \
-f deploy/helm/draforge/values-local-demo.yaml
This profile is unauthenticated and must not be used with sensitive data or production clusters.
The chart does not deploy an identity provider. Before using values-public-example.yaml, provide:
draforge-example-tls in the release namespace.oauth2-proxy:4180 in the same namespace.http://draforge-server:8080 Service.helm upgrade --install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace \
-f deploy/helm/draforge/values-public-example.yaml
The secure Gateway route targets the authentication proxy, not the DRAForge Service, preventing the public route from bypassing authentication. The proxy must enforce OIDC login/session policy, forward SSE without buffering, set secure cookies, and add HSTS and other edge headers. CORS only controls browser origin access and does not replace authentication.
For an Ingress controller, set gateway.enabled: false and gateway.ingress.enabled: true while retaining the same hostname, TLS Secret, proxy Service, and HTTPS CORS origin. Controller-specific annotations may be placed under gateway.ingress.annotations.
Earlier chart defaults created an HTTP Gateway automatically. The current chart creates no external listener unless an explicit profile enables one. Existing public installations must choose either the short-lived local-demo profile or a TLS/authenticated public configuration before upgrading.
This provider-specific showcase is not required for normal DRAForge installations. The optional DOKS showcase build flow publishes component images to a private DigitalOcean Container Registry layout. task demo:up creates the registry-draforge pull secret in draforge-system and installs the chart with:
helm upgrade --install draforge deploy/helm/draforge \
--namespace draforge-system \
--create-namespace \
-f deploy/helm/draforge/values-showcase-docr.yaml
Do not use this override for ordinary public installs; it requires private DOCR credentials.