How hqarroum/docker-android works
1. What this repository produces
- This repo builds a Docker image that runs the Android Emulator as a headless service.
- The container is intended for CI, automated testing, and remote control rather than interactive desktop use.
2. Core runtime boundary
- The main runtime boundary is the container vs. host.
- The host must provide KVM hardware acceleration via /dev/kvm, and the container exposes the emulator/ADB network ports so external tools can connect.
- The emulator itself runs inside the container; control happens from outside through ADB, and optionally through tools like scrcpy.
3. Image composition
- The image is based on Alpine Linux and includes the Android emulator stack plus JRE 11.
- The build can include or omit the Android SDK / emulator components, which materially changes image size and build time.
- The repo supports building a minimal runtime image or a larger pre-bundled variant.
4. Build-time configuration subsystem
- Image contents are parameterized by build args such as API_LEVEL, IMG_TYPE, ARCHITECTURE, and INSTALL_ANDROID_SDK.
- These determine:
- Android version
- Image flavor, such as Google APIs vs Play Store
- CPU architecture, mainly x86_64 and x86
- Whether SDK installation is baked into the image
- This is the main mechanism for producing multiple emulator variants from one repository.
5. Container startup flow
- At runtime, the container starts the emulator, then brings up an ADB server bound inside the container.
- The emulator is configured to run headless, with defaults tuned for automation: fixed memory, CPU cores, and extra emulator flags.
- The startup scripts in scripts/ likely split responsibilities between SDK installation, emulator launch, and monitoring/recovery.
6. Persistence and wipe behavior
- Emulator state is stored under /data in the container.
- If no volume is mounted, emulator storage is effectively ephemeral and gets wiped on restart.
- If a host volume is mounted to /data, the AVD state can persist across container runs.
- This creates a clear separation between disposable runtime state and persistent device images.
7. ADB and remote control path
- External clients connect to the container’s ADB port 5555.
- Once connected, the Android device inside the emulator becomes available for automation, testing, and optional screen control.
- The README explicitly positions scrcpy as a supported remote-control path that rides on top of the ADB connection.
8. GPU and variant support
- The repo includes a separate Dockerfile.gpu and compose targets for GPU-accelerated variants.
- That indicates two runtime modes: software/headless emulation and accelerated emulation using host GPU capabilities where available.
- The compose file acts as the main orchestration layer for choosing between variants like standard, CUDA, and Play Store images.
9. Key management boundary for Play Store images
- Play Store-based emulator images require matching ADB keys between the emulator container and the client.
- The keys/ directory contains default adbkey / adbkey.pub, and the README documents overriding them.
- This is an authentication boundary that matters only for certain image flavors, especially Play Store builds.
10. Operational scripts
- install_android.sh and the scripts under scripts/ are the operational glue for fetching SDK content, starting the emulator, and supervising it.
- emulator-monitoring.sh suggests the container includes a lightweight process-management layer to keep the emulator usable in unattended environments.
- These scripts are the main internal implementation surface, while Docker and Compose define the deployment surface.
11. CI/CD and release flow
- GitHub Actions workflows build and publish Docker images, likely for multiple image variants.
- The repo also contains .travis.yml, showing legacy or secondary CI support.
- The resulting artifacts are published to Docker Hub, where tags correspond to emulator API levels and image flavors.
12. Primary external dependencies
- The architecture depends on:
- Android SDK / emulator distributions for the guest runtime
- KVM on the host for performance
- Docker for packaging and execution
- Optional GPU drivers/CUDA for accelerated variants
- These dependencies are central to the design; the repo is essentially a packaging and orchestration layer around them.
13. How to diagram it
- A good architecture diagram would show:
- Build inputs: Dockerfiles, scripts, build args, keys
- Build pipeline: GitHub Actions producing tagged images
- Runtime container: Android emulator + ADB server + optional SDK
- Host interfaces: /dev/kvm, mounted /data, exposed port 5555, optional GPU
- External clients: adb, scrcpy, CI jobs, and test runners connecting over ADB
Main entry points: Dockerfile Dockerfile · start-emulator.sh Start emulator · Dockerfile.gpu GPU Dockerfile · docker-compose.yml Compose
Components 18
Build & release
Image definitions, build-time parameters, and publishing workflows.
- Dockerfile · Main image definition for the standard headless emulator runtime.
Dockerfile - GPU Dockerfile · Alternative image definition for accelerated emulator runs.
Dockerfile.gpu - Compose · Local deployment entrypoint for selecting image variants and runtime settings.
docker-compose.yml - Build args · API level, image type, architecture, and SDK-install toggles.
- Android install · Top-level installer for fetching and preparing Android components.
install_android.sh - GitHub Actions · Workflows that build and publish tagged Docker image variants.
.github/workflows/docker-image.yml - Travis CI · Secondary CI configuration for validating builds.
.travis.yml
Container runtime
Emulator process, startup scripts, and in-container state management.
- Alpine base · Lean Linux foundation for the container image.
- Android SDK · Optional bundled SDK and emulator components baked into the image.
scripts/install-sdk.sh - Start emulator · Launches the headless emulator and brings up ADB.
scripts/start-emulator.sh - Monitoring · Lightweight recovery and process supervision for unattended runs.
scripts/emulator-monitoring.sh - AVD state · Emulator data stored under /data; persists only when mounted from the host.
Host & clients
Host acceleration, external automation, and authentication boundaries.
- KVM · Hardware virtualization exposed to the container through /dev/kvm.
- GPU drivers · Optional GPU/CUDA acceleration path for accelerated variants.
- ADB clients · CI jobs, test runners, and automation tools connecting over ADB.
- scrcpy · Optional screen/control client layered on top of ADB.
- ADB keys · Keypair used for Play Store-compatible image authentication.
keys/adbkey - Docker Hub · Published destination for tagged emulator image artifacts.
Connections 22
- Dockerfile → Alpine base: builds on · Standard image starts from Alpine Linux.
- GPU Dockerfile → Alpine base: builds on · GPU variant also uses the Alpine base.
- Dockerfile → Build args: parameterized by · Build args control emulator flavor, CPU architecture, and SDK inclusion.
- GPU Dockerfile → Build args: parameterized by · Accelerated variant also depends on build-time configuration.
- Android install → Android SDK: installs · Bootstrap script fetches and prepares Android tooling.
- Dockerfile → Android SDK: includes · SDK content is baked into the image when enabled.
- Compose → Dockerfile: runs · Compose can launch the standard image path.
- Compose → GPU Dockerfile: runs · Compose can select the accelerated variant.
- Compose → Start emulator: starts · Container startup path launches the emulator and ADB server.
- Start emulator → Monitoring: uses · Startup flow relies on monitoring for unattended operation.
- Monitoring → Start emulator: supervises · Monitoring keeps the emulator usable during long runs.
- Start emulator → AVD state: persists state · Emulator state is stored under /data and can survive restarts when mounted.
- KVM → Start emulator: accelerates · Host KVM acceleration improves emulator performance.
- GPU drivers → GPU Dockerfile: enables · GPU variant relies on host graphics acceleration.
- ADB clients → Start emulator: connects to · External automation reaches the device through ADB.
- scrcpy → Start emulator: uses · Remote control rides on top of the ADB connection.
- ADB keys → Dockerfile: supports · Key material is used for Play Store-compatible images.
- ADB keys → ADB clients: trusted by · Certain variants require matching client and container keys.
- GitHub Actions → Dockerfile: builds · CI builds and publishes standard image variants.
- GitHub Actions → GPU Dockerfile: builds · CI also builds GPU-enabled variants.
- GitHub Actions → Docker Hub: publishes · Built images are pushed as tagged artifacts.
- Travis CI → Dockerfile: validates · Legacy CI can still exercise the main build.