Skip to content

🖥️ Emulator Support

Full Android emulator lifecycle management via Docker containers with KVM hardware acceleration. Create, start, stop, and delete emulators from the dashboard or REST API, and scale to multiple concurrent headless instances for testing.

Ghost uses budtmo/docker-android containers instead of the Android SDK emulator. Each container runs a full Android 11 emulator, exposes ADB on port 5555, and is hardware-accelerated via KVM.

Ghost backend
|
v
Docker daemon → budtmo/docker-android container
| Android 11 (API 30)
| ADB server :5555
|
v
adb connect localhost:<host_port>
|
v
Device(serial) — same API as a physical phone

Why Docker instead of SDK AVDs:

  • No Android SDK required — just Docker + KVM
  • Works on any Linux machine with /dev/kvm
  • Emulators are isolated, reproducible, and easy to reset
  • No SDK version management headaches

Manages multiple containers for parallel testing:

  • Thread-safe serial-to-status tracking (idle/busy)
  • System resource monitoring (CPU, RAM, disk)
  • Scale up: spin N containers at once
  • Scale down: stop idle containers
  • Job assignment via mark_busy/mark_idle
Terminal window
# Check
docker info # Docker daemon running
ls /dev/kvm # KVM available (Linux)
adb version # ADB in PATH
# Pull the image (6.9 GB, one-time)
docker pull budtmo/docker-android:emulator_11.0
# Verify via Ghost
curl http://localhost:5055/api/emulators/prerequisites

The prerequisites endpoint returns:

{
"backend": "docker",
"docker_available": true,
"kvm_available": true,
"adb_binary": true,
"hw_accel": true,
"hw_accel_type": "KVM",
"image": "budtmo/docker-android:emulator_11.0"
}

Open the Emulators tab → click Create → enter a name → the container starts and connects via ADB automatically.

Terminal window
# Create + start
curl -X POST http://localhost:5055/api/emulators \
-H "Content-Type: application/json" \
-d '{"name": "test-emu", "api_level": 30}'
# Poll boot status
curl http://localhost:5055/api/emulators/test-emu/boot-status
# {"serial": "localhost:5555", "booted": true}
# Use it — same as a physical phone
curl http://localhost:5055/api/phone/devices
# Stop + delete
curl -X POST http://localhost:5055/api/emulators/test-emu/stop
curl -X DELETE http://localhost:5055/api/emulators/test-emu
# docker-compose.emulators.yml — ships with the repo
services:
emu-1:
image: budtmo/docker-android:emulator_11.0
devices:
- /dev/kvm:/dev/kvm
ports:
- "5555:5555"
Terminal window
docker compose -f docker-compose.emulators.yml up -d
adb connect localhost:5555

Both emulators and physical phones are ADB serials. Device("localhost:5555") works identically to Device("L9AIB7603188953"). All 38 MCP tools, all skills, all agent workflows run unchanged on emulators.

MethodEndpointDescription
GET/api/emulatorsList all containers with status
POST/api/emulatorsCreate + start a new container
DELETE/api/emulators/<name>Stop + remove container
POST/api/emulators/<name>/stopStop container
GET/api/emulators/<name>/boot-status{serial, booted}
GET/api/emulators/runningRunning containers reachable via ADB
GET/api/emulators/prerequisitesDocker + KVM availability check
GET/api/emulators/system-imagesAvailable Docker images
POST/api/emulators/system-images/installPull a Docker image
MethodEndpointDescription
GET/api/emulator-pool/statusActive / idle / busy counts
GET/api/emulator-pool/resourcesCPU / RAM / disk usage
POST/api/emulator-pool/scale-upStart N containers
POST/api/emulator-pool/scale-downStop idle containers
POST/api/emulator-pool/stop-allStop all pool containers
FilePurpose
gitd/services/emulator_service.pyEmulatorManager + EmulatorPool
gitd/services/_emulator_helpers.pyDocker client, discovery, config dataclass
gitd/services/_emulator_pool.pyPool lifecycle
gitd/routers/emulators.pyREST API routes
docker-compose.emulators.ymlManual multi-emulator compose file

Snapshots are not supported in Docker mode — containers start fresh each time. For persistent state, commit a custom Docker image from a running container:

Terminal window
docker commit <container_id> my-emulator-state:v1
  • ADB Device — Device class works identically with emulators
  • Scheduler — assign automated jobs to emulators
  • Ghost Bench — run benchmark suites across emulator pools