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.

FeatureWhat it provides
Alpine-based imageSmaller footprint and fewer unnecessary components
KVM supportBetter performance when supported by the host
Headless executionSuitable for CI/CD and servers without a desktop
ADB exposed over the networkAllows app installation, testing and debugging from outside the container
scrcpy compatibilityRemote visual control of the emulator
Configurable API levelTesting against different Android versions
Optional Play Store imageUseful when Google Play services are required
MIT licenseOpen-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:

VariablePurpose
API_LEVELDefines the Android version through its API level
IMG_TYPESelects the image type, such as Google APIs or Play Store
ARCHITECTUREDefines the architecture, with active support for x86_64 and x86
MEMORYMemory assigned to the emulator, 8192 MB by default
CORESAssigned CPU cores, 4 by default
EXTRA_FLAGSAdditional emulator flags
DISABLE_ANIMATIONAllows animations to be disabled
SKIP_AUTHControls 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.

VariantUncompressed sizeCompressed size
API 33 + Emulator5.84 GB1.97 GB
API 32 + Emulator5.89 GB1.93 GB
API 28 + Emulator4.29 GB1.46 GB
Without SDK and emulator414 MB138 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 caseAdvantage
Android CI/CDReproducible and disposable emulators
Automated QAMultiple Android versions in separate images
Remote developmentEmulator runs on a more powerful machine
Headless testingNo graphical desktop required
TrainingEasy-to-replicate environment for students
ADB-based validationInstallation, 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.

Scroll to Top