Kubernetes-native Android device farm — each pod is a browser-accessible Android device
Deploy fleets of Android virtual devices on any standard Kubernetes cluster. No KVM, no node modifications. Every device streams to the browser via WebRTC.
Each Kubernetes pod runs a complete Android device (Google Cuttlefish) with WebRTC built-in plus a small envoy sidecar
that exposes the Cuttlefish gRPC API as gRPC-Web over HTTP/2. The operator creates one pod per device, manages pools,
claims devices for test sessions, and writes one HTTPRoute per device on the cluster's shared Cilium Gateway
so each device gets its own hostname.
kubectl apply DeviceTemplate + DevicePool
↓
Operator creates StatefulSet (one pod = one Android device)
↓
Each pod: envoy sidecar (h2c :8080) → Cuttlefish gRPC :8554 + WebRTC media
↓
Operator writes HTTPRoute on the shared Cilium Gateway
(kube-system/cilium-gateway, https listener)
↓
status.streamURL = https://staging-pool-0.local.geekxflood.io
status.appiumEndpoint = http://device-0.pool-emulator.ns.svc:4723# 1. Add chart repository
helm repo add droidfarm https://christopherime.github.io/droidfarm/
helm repo update
# 2. Deploy
helm install droidfarm droidfarm/droidfarm \
--namespace droidfarm-system --create-namespace \
--set turn.credentials.username=myuser \
--set turn.credentials.password=mypass
# 3. Define a device profile
kubectl apply -f - <<EOF
apiVersion: droidfarm.io/v1alpha1
kind: DeviceTemplate
metadata:
name: android14
namespace: droidfarm-system
spec:
androidVersion: "14"
emulationBackend: cuttlefish-qemu # no KVM, WebRTC built-in
resources:
cpu: "2"
memory: "4Gi"
EOF
# 4. Create a pool (fleet)
kubectl apply -f - <<EOF
apiVersion: droidfarm.io/v1alpha1
kind: DevicePool
metadata:
name: mypool
namespace: droidfarm-system
spec:
templateRef:
name: android14
replicas:
min: 2
max: 20
EOF
# 5. Run a test session
kubectl create -f manifests/examples/test-session-basic.yaml
# Get browser URL and Appium endpoint
kubectl get testsession -n droidfarm-systemThe cuttlefish-qemu backend runs Cuttlefish with QEMU software emulation inside a standard container. No /dev/kvm,
no node labels, no DaemonSets on worker nodes.
Optional: Set
emulationBackend: cuttlefishon nodes with KVM for ~10× faster boot times.
The operator creates one pod per device. A DevicePool with replicas.max: 1000 deploys 1000 independent Android devices.
KEDA autoscales the pool based on pending test session queue depth.
https://christopherime.github.io/droidfarm/
- Getting Started — deploy in 5 minutes
- CRD Reference — DeviceTemplate, DevicePool, TestSession
- CLI Reference —
droidfarmcommand - Architecture
Apache 2.0