Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
Docker-Android
https://github.com/budtmo/docker-android
Admin
Docker-Android provides a Docker image for Android development and testing, supporting emulators
...
Tokens:
10,226
Snippets:
129
Trust Score:
9.9
Update:
2 weeks ago
Context
Skills
Chat
Benchmark
85.1
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Docker-Android Docker-Android is a Docker image designed to provide a complete Android development and testing environment inside a container. It supports running Android emulators (Android 9.0–14.0) with hardware acceleration via KVM, as well as integration with Genymotion cloud virtual devices (SaaS and AWS). The project enables native, web, and hybrid Android app testing without requiring a physical device, making it well-suited for CI/CD pipelines, cloud deployments, and automated UI testing frameworks such as Appium and Espresso. The core functionality is orchestrated by a Python-based CLI (`docker-android`) that launches and manages the emulator lifecycle (create, start, wait-for-boot, reconfigure, keep-alive), VNC servers for visual access, a web VNC proxy (noVNC), a log-sharing HTTP server, and an Appium test server — all configurable entirely through environment variables passed to the Docker container. Device profiles and skins are bundled for a range of Samsung Galaxy and Nexus devices, and the emulator config can be overridden by mounting a custom `.ini` file. The build and release pipeline (`app.sh` + GitHub Actions) automates testing, building, tagging, and pushing images for each supported Android version. --- ## Running the Android Emulator Container Start a containerized Android 11.0 emulator with a Samsung Galaxy S10 device profile and web VNC access. KVM (`/dev/kvm`) must be available on the host for hardware acceleration. ```bash docker run -d \ -p 6080:6080 \ -e EMULATOR_DEVICE="Samsung Galaxy S10" \ -e WEB_VNC=true \ --device /dev/kvm \ --name android-container \ budtmo/docker-android:emulator_11.0 # Open the emulator in a browser # http://localhost:6080 # Check emulator boot status docker exec -it android-container cat device_status # Output: ready ``` --- ## Environment Variables — Emulator Configuration All emulator behaviour is controlled via environment variables. The table below covers the key knobs; pass them with `-e KEY=value` to `docker run`. ```bash # Full-featured run: custom name, large data partition, Appium, log sharing, VNC with password docker run -d \ -p 6080:6080 \ -p 5900:5900 \ -p 4723:4723 \ -p 9000:9000 \ -e EMULATOR_DEVICE="Samsung Galaxy S9" \ -e EMULATOR_NAME="my_s9_emu" \ -e EMULATOR_DATA_PARTITION="900m" \ -e EMULATOR_NO_SKIN=false \ -e EMULATOR_ADDITIONAL_ARGS="-memory 2048" \ -e WEB_VNC=true \ -e WEB_VNC_PORT=6080 \ -e VNC_PASSWORD=secret123 \ -e WEB_LOG=true \ -e WEB_LOG_PORT=9000 \ -e APPIUM=true \ -e APPIUM_ADDITIONAL_ARGS="--allow-insecure chromedriver_autodownload" \ --device /dev/kvm \ --name android-full \ budtmo/docker-android:emulator_13.0 # Available EMULATOR_DEVICE values: # Nexus 4, Nexus 5, Nexus 7, Nexus One, Nexus S # Samsung Galaxy S6, S7, S7 Edge, S8, S9, S10 # Pixel C, Pixel 8, Pixel 9 # Supported Android versions (image tags): # emulator_9.0 (API 28) # emulator_10.0 (API 29) # emulator_11.0 (API 30) # emulator_12.0 (API 32) # emulator_13.0 (API 33) # emulator_14.0 (API 34) ``` --- ## Persisting Emulator Data By default the emulated device is wiped on container restart. Mount a named volume at `/home/androidusr` to persist app data, AVD state, and emulator storage across restarts. ```bash # Create a named volume and mount it docker run -d \ -p 6080:6080 \ -e EMULATOR_DEVICE="Nexus 5" \ -e WEB_VNC=true \ --device /dev/kvm \ -v android-data:/home/androidusr \ --name android-persistent \ budtmo/docker-android:emulator_14.0 # On subsequent restarts the AVD is reused (no --wipe-data) docker restart android-persistent ``` --- ## Overriding the Emulator Config File Append custom AVD `config.ini` options at container startup by mounting a file and pointing `EMULATOR_CONFIG_PATH` to it. ```bash # emulator-override-config.ini (on host) # hw.ramSize=3072 # hw.cpu.ncore=4 docker run -d \ -p 6080:6080 \ -e EMULATOR_DEVICE="Samsung Galaxy S10" \ -e WEB_VNC=true \ -e EMULATOR_CONFIG_PATH=/tmp/emulator-override-config.ini \ -v /path/on/host/emulator-override-config.ini:/tmp/emulator-override-config.ini \ --device /dev/kvm \ --name android-custom-cfg \ budtmo/docker-android:emulator_14.0 ``` --- ## VNC Access — Native Client and Web UI The VNC server runs on port 5900; the noVNC web proxy runs on port 6080. Both can be secured with a password. ```bash # Expose both ports docker run -d \ -p 5900:5900 \ -p 6080:6080 \ -e EMULATOR_DEVICE="Nexus 5" \ -e WEB_VNC=true \ -e VNC_PASSWORD=mypassword \ --device /dev/kvm \ --name android-vnc \ budtmo/docker-android:emulator_11.0 # Connect with a native VNC client (e.g. TigerVNC, RealVNC) # Host: localhost Port: 5900 Password: mypassword # Web UI endpoints (noVNC) # Auto-connect: http://localhost:6080/?autoconnect=true # View-only: http://localhost:6080/?autoconnect=true&view_only=true # Auto-connect with password: http://localhost:6080/?autoconnect=true&password=mypassword ``` --- ## Log Sharing via Web UI Enable a built-in HTTP log server to browse container log files from a browser. ```bash docker run -d \ -p 6080:6080 \ -p 9000:9000 \ -e EMULATOR_DEVICE="Nexus 5" \ -e WEB_VNC=true \ -e WEB_LOG=true \ -e WEB_LOG_PORT=9000 \ --device /dev/kvm \ --name android-logs \ budtmo/docker-android:emulator_11.0 # Browse log index curl http://localhost:9000/ # <html><body><p><a href="appium.log">appium.log</a></p>...</body></html> # Fetch a specific log file curl http://localhost:9000/appium.log ``` --- ## Running Appium Server Enable the Appium 2.x server inside the container for mobile UI testing. The server starts on port 4723. ```bash docker run -d \ -p 6080:6080 \ -p 4723:4723 \ -e EMULATOR_DEVICE="Samsung Galaxy S10" \ -e WEB_VNC=true \ -e APPIUM=true \ -e APPIUM_ADDITIONAL_ARGS="--relaxed-security" \ --device /dev/kvm \ --name android-appium \ budtmo/docker-android:emulator_11.0 # Verify Appium is up curl http://localhost:4723/status # {"value":{"build":{"version":"2.x.x"},"ready":true},...} # Run a Python Appium test against the container # pip install Appium-Python-Client from appium import webdriver desired_caps = { "platformName": "Android", "deviceName": "emulator-5554", "app": "/path/to/app.apk", "automationName": "UiAutomator2" } driver = webdriver.Remote("http://localhost:4723", desired_caps) driver.find_element("id", "com.example.app:id/button").click() driver.quit() ``` --- ## Controlling the Emulator via ADB from the Host Expose ADB ports so the host `adb` can connect directly into the container emulator. ```bash docker run -d \ -p 5554:5554 \ -p 5555:5555 \ -e EMULATOR_DEVICE="Nexus 5" \ --device /dev/kvm \ --name android-adb \ budtmo/docker-android:emulator_11.0 # Connect from host adb connect <docker-host-ip>:5555 # connected to 192.168.1.100:5555 adb devices # List of devices attached # 192.168.1.100:5555 device # Install an APK adb -s 192.168.1.100:5555 install myapp.apk # SMS simulation docker exec -it android-adb adb emu sms send +1234567890 "Hello from Docker-Android" ``` --- ## Building an Android Project Inside the Container Use the Docker-Android image as a build environment by mounting the project and overriding the entrypoint. ```bash # Clone a sample project git clone git@github.com:android/testing-samples.git # Build the Espresso sample with Gradle inside the container docker run -it --rm \ -v $PWD/testing-samples/ui/espresso/BasicSample:/home/androidusr/tmp \ -w /home/androidusr/tmp \ --entrypoint "/bin/bash" \ budtmo/docker-android:emulator_11.0_v2.0 \ -c "./gradlew build" # Run only unit tests docker run -it --rm \ -v $PWD/testing-samples/ui/espresso/BasicSample:/home/androidusr/tmp \ -w /home/androidusr/tmp \ --entrypoint "/bin/bash" \ budtmo/docker-android:emulator_11.0_v2.0 \ -c "./gradlew test" ``` --- ## Genymotion SaaS Integration Run Genymotion cloud virtual devices instead of a local emulator by providing an auth token and a `saas.json` device template. ```bash # saas.json — define one or more cloud devices cat > saas.json <<'EOF' [ { "name": "SamsungS10-Test", "template": "a2a0c86c-7572-45fe-98d0-66f8efed9fa0", "local_port": 51345 }, { "template": "80a67ae9-430c-4824-a386-befbb19518b9" } ] EOF export AUTH_TOKEN="your-genymotion-auth-token" docker run -d \ -p 4723:4723 \ -v $PWD/saas.json:/home/androidusr/genymotion_template/saas.json \ -e DEVICE_TYPE=geny_saas \ -e GENY_AUTH_TOKEN=${AUTH_TOKEN} \ -e APPIUM=true \ --name android-geny-saas \ budtmo/docker-android:genymotion # Devices are ADB-connected automatically inside the container. # Stop the container to remove cloud devices and logout: docker stop android-geny-saas ``` --- ## Genymotion AWS Integration Provision Genymotion AMI instances on AWS via Terraform automatically managed by the container. ```bash # aws.json — define EC2-backed Genymotion devices cat > aws.json <<'EOF' [ { "name": "device1", "region": "eu-west-1", "ami": "ami-68d78411", "instance_type": "t2.small", "ingress_rules": [ {"from_port": 22, "to_port": 22, "protocol": "tcp", "cidr_blocks": ["0.0.0.0/0"]}, {"from_port": 51000, "to_port": 51100, "protocol": "tcp", "cidr_blocks": ["0.0.0.0/0"]} ], "egress_rules": [ {"from_port": 0, "to_port": 65535, "protocol": "udp", "cidr_blocks": ["0.0.0.0/0"]} ] } ] EOF export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE" export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" docker run -it --rm \ -p 4723:4723 \ -v $PWD/aws.json:/home/androidusr/genymotion_template/aws.json \ -e DEVICE_TYPE=geny_aws \ -e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ -e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ -e APPIUM=true \ budtmo/docker-android:genymotion # Terraform init/plan/apply runs automatically. # SSH tunnel to ADB is set up and adb connect is called. # On container exit, terraform destroy is run automatically. # Allow ~3 min for AWS resource teardown: docker stop --time=180 android-geny-aws ``` --- ## CLI — `docker-android start <app>` The internal Python CLI manages each sub-service independently. These commands are invoked by the container entrypoint, but can be called manually for debugging. ```bash # Start the Android emulator device docker exec android-container docker-android start device # Start only Appium server (APPIUM=true must be set) docker exec android-container docker-android start appium # Start VNC server docker exec android-container docker-android start vnc_server # Start noVNC web proxy (WEB_VNC=true must be set) docker exec android-container docker-android start vnc_web # Start virtual display (Xvfb) docker exec android-container docker-android start display_screen # Start window manager (Openbox) docker exec android-container docker-android start display_wm # Start ADB port forwarder (socat, exposes ports 5554/5555) docker exec android-container docker-android start port_forwarder ``` --- ## CLI — `docker-android share log` Start the built-in HTTP log-sharing server (equivalent to setting `WEB_LOG=true`). ```bash # Manually trigger log sharing on port 9000 docker exec -e WEB_LOG=true -e WEB_LOG_PORT=9000 \ -e LOG_PATH=/home/androidusr/log \ android-container docker-android share log # GET / → HTML index of available log files curl http://localhost:9000/ # GET /<filename> → raw log content curl http://localhost:9000/emulator.log ``` --- ## `app.sh` — Build, Test, and Push Images The `app.sh` script drives local development tasks: running unit tests in a Docker container, building images, and pushing to Docker Hub. ```bash # Run unit tests (spins up python:3.12-slim container) ./app.sh test emulator test 11.0 # Build emulator image for Android 14.0, release v2.1.0-p0 ./app.sh build emulator v2.1.0-p0 14.0 # Produces: # budtmo/docker-android:emulator_14.0_v2.1.0-p0 (specific release) # budtmo/docker-android:emulator_14.0 (latest for this Android version) # budtmo/docker-android:latest (if 14.0 is the last supported version) # Build the base image ./app.sh build base v2.1.0-p0 # Build the Genymotion image ./app.sh build genymotion v2.1.0-p0 # Push an emulator image (runs build first, then docker push) ./app.sh push emulator v2.1.0-p0 13.0 ``` --- ## WSL2 Setup (Windows 11 — Hardware Acceleration) Enable nested virtualization for KVM access in WSL2 before running the container on Windows 11. ```powershell # 1. Add user to kvm group (inside WSL2 terminal) sudo usermod -a -G kvm ${USER} # 2. Configure /etc/wsl.conf (inside WSL2) # [boot] # command = /bin/bash -c 'chown -v root:kvm /dev/kvm && chmod 660 /dev/kvm' # 3. Configure .wslconfig (PowerShell on Windows host) notepad $env:USERPROFILE\.wslconfig # Add: # [wsl2] # nestedVirtualization=true # 4. Restart WSL2 (PowerShell) wsl --shutdown ``` ```bash # After WSL2 restart, run the container normally docker run -d \ -p 6080:6080 \ -e EMULATOR_DEVICE="Nexus 5" \ -e WEB_VNC=true \ --device /dev/kvm \ budtmo/docker-android:emulator_11.0 ``` --- ## Cloud Deployment Requirements Nested virtualization must be enabled on the underlying VM when running Docker-Android in a cloud environment. ```bash # Azure — use Dv3 or Ev3 VM series (supports nested virtualization) # https://docs.microsoft.com/en-us/azure/virtual-machines/windows/nested-virtualization # AWS — use EC2 Bare Metal instances (e.g. i3.metal) # https://aws.amazon.com/blogs/aws/new-amazon-ec2-bare-metal-instances-with-direct-access-to-hardware/ # GCP — enable nested virtualization on the instance gcloud compute instances create android-ci \ --machine-type=n2-standard-4 \ --min-cpu-platform="Intel Cascade Lake" \ --enable-nested-virtualization \ --zone=us-central1-a # Then SSH in and run the container as usual docker run -d \ -p 6080:6080 \ -p 4723:4723 \ -e EMULATOR_DEVICE="Samsung Galaxy S10" \ -e WEB_VNC=true \ -e APPIUM=true \ --device /dev/kvm \ budtmo/docker-android:emulator_14.0 ``` --- ## Pro Version — Proxy, Language, and Headless Mode Docker-Android-Pro (sponsor-only, `budtmo2/docker-android-pro`) adds proxy support, language configuration, headless mode, and newer Android versions (15.0, 16.0). ```bash # Pro: emulator with corporate proxy and Spanish locale docker run -d \ -p 6080:6080 \ -e EMULATOR_DEVICE="Samsung Galaxy S10" \ -e WEB_VNC=true \ -e HTTP_PROXY="http://172.17.0.1:3128" \ -e HTTPS_PROXY="http://172.17.0.1:3128" \ -e NO_PROXY="localhost" \ -e EMULATOR_PROXY_URL="http://172.17.0.1:3128" \ -e EMULATOR_LANGUAGE="es" \ -e EMULATOR_COUNTRY="ES" \ --device /dev/kvm \ budtmo2/docker-android-pro:emulator_14.0 # Pro headless mode (no Web-UI, saves resources) docker run -d \ -p 4723:4723 \ -e EMULATOR_DEVICE="Nexus 5" \ -e APPIUM=true \ --device /dev/kvm \ budtmo2/docker-android-pro:emulator_headless_14.0 # Pro Selenium node (connects to a Selenium Grid 4.x hub) docker run -t --rm \ --name selenium-node \ -p 4444:4444 \ -v $PWD/pro-example/node.json:/home/seleniumusr/selenium_node_config/node.json \ budtmo2/docker-android-pro:selenium ``` --- Docker-Android's primary use cases span automated mobile CI/CD pipelines, Appium-based UI testing, Android build servers, and cloud-based emulator farms. In a typical CI scenario the image is pulled in a pipeline job, started with `APPIUM=true` and the desired `EMULATOR_DEVICE`, tests are executed against `http://localhost:4723`, and the container is discarded — all without a physical device or a persistent machine. The built-in log sharing and noVNC web UI make it straightforward to debug failures without SSH access. Integration patterns follow a few common shapes: (1) **Standalone emulator** — a single `docker run` command with environment variables, suitable for local development or simple CI runners; (2) **Appium + Selenium Grid** — multiple Docker-Android containers each running Appium 2.x, connected to a Selenium Grid 4.x hub for parallel cross-device testing, using the Pro Selenium node image; (3) **Genymotion cloud** — the `genymotion` image variant manages cloud virtual device lifecycle via `gmsaas` (SaaS) or Terraform (AWS), abstracting device provisioning entirely; (4) **Build-only** — the entrypoint is overridden to run Gradle directly, using the Android SDK and build tools bundled in the image without starting the emulator.