Running Android inside Docker is no longer just a curiosity for automation labs. The HQarroum/docker-android project provides a minimal and customizable image that runs the Android emulator as a service, exposes it through ADB and allows remote control with tools such as scrcpy. The idea is simple: package the emulator, its dependencies and the required configuration inside a reproducible container.
For Android developers, QA teams, CI/CD pipelines and testing labs, this solves a familiar problem. Setting up an emulation environment often means installing Android Studio, SDKs, system images, platform tools, Java, drivers, KVM and host-level configuration. With Docker, much of that complexity becomes an image that can be built, versioned, repeated and launched on demand.
What docker-android is and why it matters
docker-android is described as a minimal and customizable Docker image that runs the Android emulator as a service. It is based on Alpine, includes KVM support, bundles Java Runtime Environment 11 and allows the Android version, image type and architecture to be adjusted at build time.
The container exposes ADB over the network, by default on port 5555, and can run headless, which is especially useful for CI farms. According to the repository, it is also compatible with scrcpy, allowing users to control the emulator screen remotely from their local machine.
The difference from having a manually installed emulator is not that Android itself is different, but how it is deployed. Docker allows several environments to use the same image, lets a pipeline start a clean emulator for each run and enables teams to test an app against different Android versions without maintaining hand-configured machines.
| Feature | What it provides |
|---|---|
| Alpine-based image | Smaller footprint and fewer unnecessary components |
| KVM support | Better performance when supported by the host |
| Headless execution | Suitable for CI/CD and servers without a desktop |
| ADB exposed over the network | Allows app installation, testing and debugging from outside the container |
scrcpy compatibility | Remote visual control of the emulator |
| Configurable API level | Testing against different Android versions |
| Optional Play Store image | Useful when Google Play services are required |
| MIT license | Open-source, reusable and modifiable project |
The repository has a clear focus: it does not try to be a full Android desktop distribution, but a lightweight way to provide an emulator that can be controlled over the network. In fact, the image contains only what is needed: the Android emulator, an ADB server for remote connection and QEMU with libvirt support.
How to run it with Docker
Basic usage starts with two options: docker compose or plain Docker. With Compose, the repository includes preconfigured services:
docker compose up android-emulator
For the GPU-accelerated variant, the project documents:
docker compose up android-emulator-cuda
And for a variant with GPU acceleration and Google Play Store:
docker compose up android-emulator-cuda-store
With plain Docker, the image is built first:
docker build -t android-emulator .
Then it is launched by mounting KVM and exposing ADB:
docker run -it --rm \
--device /dev/kvm \
-p 5555:5555 \
android-emulator
The /dev/kvm detail matters. Without KVM, the emulator may perform poorly or become unsuitable for serious testing. KVM depends on the host, virtualization being enabled in BIOS/UEFI and the right system permissions. On Linux, this is usually the most natural path; on other environments, compatibility and performance must be checked.
Once the container starts, ADB can connect from the host:
adb connect 127.0.0.1:5555
adb devicesCode language: CSS (css)
And to view and control the emulator interface:
scrcpy
According to the documentation, the emulator runs by default with a Pixel preset at 1080 × 1920. This makes it useful for functional testing, UI automation, visual debugging and running apps without opening Android Studio.
Persistence, versions and customization
By default, emulator images are wiped every time the emulator restarts. This is good for CI because every execution begins from a controlled state. But in local development, it may be useful to preserve data, installed apps or AVD configuration. For that, a volume can be mounted at /data:
docker run -it --rm \
--device /dev/kvm \
-p 5555:5555 \
-v ~/android_avd:/data \
android-emulatorCode language: JavaScript (javascript)
The project also allows the Android version, image type and architecture to be changed at build time. By default, the image is built with API 33, Google APIs and x86_64 architecture. To create, for example, an Android Pie image with Google Play Store and x86, the command would be:
docker build \
--build-arg API_LEVEL=28 \
--build-arg IMG_TYPE=google_apis_playstore \
--build-arg ARCHITECTURE=x86 \
--tag android-emulator .
The main variables are:
| Variable | Purpose |
|---|---|
API_LEVEL | Defines the Android version through its API level |
IMG_TYPE | Selects the image type, such as Google APIs or Play Store |
ARCHITECTURE | Defines the architecture, with active support for x86_64 and x86 |
MEMORY | Memory assigned to the emulator, 8192 MB by default |
CORES | Assigned CPU cores, 4 by default |
EXTRA_FLAGS | Additional emulator flags |
DISABLE_ANIMATION | Allows animations to be disabled |
SKIP_AUTH | Controls ADB authentication, shown as true by default |
For API 33, the repository recommends at least 4 GB of memory and 8 GB of disk space. Image size should also be considered. These are not tiny containers when they include the SDK and emulator.
| Variant | Uncompressed size | Compressed size |
|---|---|---|
| API 33 + Emulator | 5.84 GB | 1.97 GB |
| API 32 + Emulator | 5.89 GB | 1.93 GB |
| API 28 + Emulator | 4.29 GB | 1.46 GB |
| Without SDK and emulator | 414 MB | 138 MB |
For teams with a shared SDK, the project allows the image to be built without installing the Android SDK inside it:
docker build -t android-emulator \
--build-arg INSTALL_ANDROID_SDK=0 .
The SDK is then mounted externally:
docker run -it --rm \
--device /dev/kvm \
-p 5555:5555 \
-v /shared/android/sdk:/opt/android/ \
android-emulatorCode language: JavaScript (javascript)
This can be useful in corporate environments, CI servers or systems with shared storage, where downloading the SDK into every image increases build time and storage usage.
Where it makes the most sense
The clearest use case is continuous integration. A pipeline can start an Android emulator, install an APK, run instrumented tests and destroy the environment when finished. This reduces differences between machines and avoids relying on a manually configured emulator on each runner.
It also fits QA labs. A team can build several images with different API levels and run tests against Android 9, Android 12 or Android 13. Combined with tools such as Appium, Espresso or custom ADB scripts, it can automate a significant part of validation.
Another interesting use case is remote development. A powerful server with KVM can run the emulator while the developer connects from a laptop through ADB and scrcpy. This can be useful when the local machine lacks resources or when teams want to centralize a testing environment.
| Use case | Advantage |
|---|---|
| Android CI/CD | Reproducible and disposable emulators |
| Automated QA | Multiple Android versions in separate images |
| Remote development | Emulator runs on a more powerful machine |
| Headless testing | No graphical desktop required |
| Training | Easy-to-replicate environment for students |
| ADB-based validation | Installation, logs and commands from the host |
A basic automated test flow could look like this:
adb connect 127.0.0.1:5555
adb install app-debug.apk
adb shell monkey -p com.example.app 100
adb logcat -d | grep "FATAL EXCEPTION"Code language: JavaScript (javascript)
It does not replace a complete testing strategy, but it shows why encapsulating the Android emulator in Docker can simplify infrastructure significantly.
Limits and precautions
The proposal is powerful, but it should not be presented as magic. Running an Android emulator inside Docker still consumes CPU, RAM and storage. The container simplifies deployment, but it does not remove the host’s virtualization requirements. KVM must be available and properly exposed.
Security also matters. Exposing ADB on port 5555 is convenient locally, but it should not be opened to public networks. ADB can install apps, execute commands and access logs. In shared environments, the port should be restricted to localhost, controlled internal networks or isolated runners.
The project itself includes SKIP_AUTH=true by default, a practical decision for automation, but one that requires caution. On a local laptop, it may be acceptable. On a server reachable over the network, it is not. If images with Google Play Store are used, the repository also states that the same ADB key must be shared between emulator and client.
It is also not the only option. The README points to related projects such as alpine-android and another docker-android project with a WebRTC interface. The choice will depend on whether the team needs a minimal image, ADB control, a web interface, Appium integration, GPU support or easier access for non-technical QA users.
What matters is that this type of project confirms a clear trend: mobile development is moving closer to reproducible infrastructure. Just as backends are tested in containers, databases are launched with Compose and frontend environments are pinned by version, Android can also become part of more declarative and automated workflows.
For teams testing mobile applications every day, an Android emulator inside Docker can save a lot of time. For occasional users, Android Studio may still be enough. But when teams need reproducible, headless, ADB-controllable environments ready for CI, docker-android offers a simple, open and practical route.
Frequently asked questions
Does docker-android run a full Android device inside Docker?
It runs the Android emulator inside a container and exposes it as a service controllable through ADB. It is not an Android desktop ROM, but an emulator designed for development, testing and CI.
Does it need KVM to perform well?
Yes. The project is designed to use KVM on the host. Without virtualization acceleration, performance may be insufficient for real testing.
Can I see the emulator screen?
Yes. The container can run headless, and the screen can be controlled externally with scrcpy after connecting through ADB.
Is it useful for CI/CD pipelines?
Yes. This is one of its clearest use cases. It allows reproducible emulators to be started, tests to be run and the environment to be destroyed afterward.
Is it safe to expose port 5555?
Only in controlled environments. ADB should not be exposed to the internet or untrusted networks. It should be limited to localhost or isolated internal networks.
