ByteNoteByteNote
一条命令把 Android 模拟器跑进 Docker
字

字节笔记本

2026年10月5日 · 约 16 分钟读完

一条命令把 Android 模拟器跑进 Docker

API中转
¥120

测 Android 应用,最大的痛点之一是环境。本地跑模拟器,吃内存、占 CPU,还经常因为各种玄学问题起不来。团队里每个人都要配一遍 SDK、装一遍镜像、调一遍 KVM。到了 CI(持续集成)更头疼:服务器上没有显示器,模拟器跑不起来,只能靠真机农场或者云服务,又贵又慢。

开源社区有个项目直接治这个病:docker-android。它把 Android 模拟器打包进 Docker 镜像,跑在容器里,通过网络远程操作。一个 docker run,模拟器就上线。本文就来拆这个「把模拟器服务化」的开源项目。

docker-android 容器里跑起来的模拟器

容器里跑起来的 Android 模拟器:桌面、设备信息、浏览器都正常工作,ADB 连上后可用 scrcpy 投屏操作。

一、它解决什么问题

先说清楚传统做法的三个痛点。

痛点 1:本地环境难配。 Android Studio 装一遍、SDK 下载几个 G、KVM 虚拟化要开 BIOS、HAXM/WHPX 还经常和别的虚拟化冲突。新人入职光配环境就一天。

痛点 2:CI 上跑不了模拟器。 大多数 CI runner 是无头(headless)的 Linux 服务器,没有图形界面,没有显示设备。模拟器需要 GPU 和显示支持,跑不起来。结果就是,CI 只能跑单元测试,UI 测试要么砍掉,要么用昂贵的云真机服务。

痛点 3:多版本矩阵测试是噩梦。 App 要覆盖 Android 10 到 14,每个版本一个模拟器,本地根本开不了那么多。云服务按机器和时长计费,账单吓人。

docker-android 的解法是,把模拟器变成一个 Docker 容器,像启动一个 Web 服务一样启动它。需要哪个版本,拉对应镜像跑就行;CI 流水线里 docker run 一行就能集成;远程通过 ADB 网络连接操作。

二、核心设计:极简加服务化

README 开宗明义:A minimal and customizable Docker image running the Android emulator as a service,一个极简、可定制的 Docker 镜像,把 Android 模拟器作为服务运行。

两个关键词:minimal(极简)和 as a service(服务化)。

极简:镜像里只装必要的东西

它基于 Alpine Linux(体积最小的 Docker 基础镜像之一),里面只装四样东西:Android Emulator 本体、ADB Server(远程连接用)、QEMU 加 libvirt(虚拟化支撑,跑 Android 系统)、JRE 11(emulator 需要 Java 运行时)。

不装 Android Studio、不装 IDE、不装开发工具,因为它是个运行时容器,不是开发环境。这种克制让镜像尽可能小。

体积对比(README 给出的数据):

变体未压缩压缩后
API 33 + Emulator5.84 GB1.97 GB
API 32 + Emulator5.89 GB1.93 GB
API 28 + Emulator4.29 GB1.46 GB
不含 SDK 和 Emulator414 MB138 MB

最后一行很关键:可以构建一个不含 SDK 和 emulator 的裸镜像,只有 414MB,然后把 SDK 挂载进去(构建时加 INSTALL_ANDROID_SDK=0,运行时把 SDK 挂到容器的 /opt/android)。这对 CI 农场特别有用,共享一份 SDK 放在 NFS 之类的共享文件系统上,每个容器只挂载,不重复下载。

服务化:模拟器是个网络服务

容器启动后,模拟器和 ADB 监听在容器网络接口上,外部通过端口转发连接:

  • ADB 端口(5555):adb connect 127.0.0.1:5555 远程连上去;
  • 模拟器端口(5554):用作模拟器控制台。

连上 ADB 后,所有 ADB 命令照常用:adb install、adb shell、adb logcat,就像模拟器在本地一样。还可以用 scrcpy 远程投屏控制:

bash
adb connect 127.0.0.1:5555
scrcpy    # 弹出窗口,实时显示并操控 Android 屏幕

这就是服务化的精髓:模拟器不再是一个本地 GUI 程序,而是一个网络端点,任何能连到这个端点的机器都能操作它。默认情况下,模拟器使用 Pixel 预设,分辨率 1080x1920。

docker-android 工作流

docker-android 工作流:宿主机把 /dev/kvm 传给容器,容器内模拟器加 ADB 监听 5555 端口,外部通过 adb connect 连接后跑测试或投屏。

三、三种镜像变体

docker-compose.yml 里定义了三个服务,对应三种使用场景。

  1. android-emulator(基础版):纯 CPU 模拟器,Google APIs 镜像,适合大多数测试场景,不需要 GPU。
  2. android-emulator-cuda(GPU 加速版):用 Dockerfile.gpu 构建,挂载 NVIDIA GPU。GPU 加速让模拟器渲染流畅很多,尤其适合游戏、图形密集型 App 的测试。
  3. android-emulator-cuda-store(GPU 加 Play Store 版):在 GPU 版基础上改用 google_apis_playstore 镜像,带 Google Play 商店,适合需要测内购、Play 服务、应用更新的场景。

用 Play Store 版需要配置 adbkey:用 adb keygen adbkey 生成私钥和公钥两个文件,覆盖到 keys 目录,保证模拟器和客户端的认证一致。

四、怎么用:三步上手

第 1 步:确保宿主机支持 KVM

模拟器需要硬件虚拟化。Linux 上检查:

bash
ls -la /dev/kvm    # 存在即支持

重要前提:宿主机必须是 Linux 且 CPU 支持 KVM。macOS 和 Windows 的 Docker Desktop 跑不了这个,因为 KVM 是 Linux 内核特性,Docker Desktop 的虚拟化层不透传。这个项目主要面向 Linux 服务器和 CI 环境。

第 2 步:拉镜像或自建

用预构建镜像(最快):

bash
docker pull halimqarroum/docker-android:api-33

或自建(可定制):

bash
docker build -t android-emulator .

定制构建参数(对应 Android 9、带 Play 商店、x86 架构):

bash
docker build \
  --build-arg API_LEVEL=28 \
  --build-arg IMG_TYPE=google_apis_playstore \
  --build-arg ARCHITECTURE=x86 \
  --tag android-emulator .

第 3 步:运行加连接

bash
# 运行(挂载 KVM,暴露 ADB 端口)
docker run -it --rm --device /dev/kvm -p 5555:5555 android-emulator

# 等几十秒让 Android 启动完,然后连接
adb connect 127.0.0.1:5555

# 像本地模拟器一样用
adb install my-app.apk
adb shell monkey -p com.example 1
scrcpy

需要持久化数据(默认每次重启擦除):

bash
docker run -it --rm --device /dev/kvm -p 5555:5555 \
  -v ~/android_avd:/data android-emulator

挂载 /data 后,安装的 App 和用户数据都会保留。

五、关键配置参数

docker-compose.yml 暴露的可调环境变量:

变量默认值作用
MEMORY16384模拟器内存(MB)
CORES16模拟器 CPU 核数
DISABLE_ANIMATIONfalse关动画,CI 测试更快更稳
DISABLE_HIDDEN_POLICYtrue关隐藏策略
SKIP_AUTHfalse跳过 ADB 认证
EXTRA_FLAGS-no-metrics -no-audio -partition-size=8192额外模拟器参数

CI 场景的关键配置有三点:DISABLE_ANIMATION 设为 true,动画会让 UI 测试变慢且不稳定;MEMORY 要给够,不够会卡死;EXTRA_FLAGS 里保留 -no-audio,无头环境不需要音频。

六、CI 集成:这才是它的主战场

docker-android 最大的价值在 CI。GitHub Actions 的典型集成方式(示意):

yaml
jobs:
  instrumented-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: 启动 Android 模拟器容器
        run: |
          docker run -d --name android \
            --device /dev/kvm \
            -p 5555:5555 \
            -e DISABLE_ANIMATION=true \
            halimqarroum/docker-android:api-33
      - name: 等待模拟器启动
        run: sleep 60
      - name: 连接并测试
        run: |
          adb connect 127.0.0.1:5555
          ./gradlew connectedAndroidTest

和常见方案的对比:

维度docker-androidandroid-emulator-runner云真机服务
成本自托管 runner 几乎免费GitHub runner 免费按时长收费
灵活性高,任意定制镜像中,固定配置低
多版本矩阵拉不同 tag 即可每次重建要买不同设备
速度容器秒级启动每次冷启动慢看排队
远程访问支持 ADB 与 scrcpy仅限 CI 内部支持但收费

对需要测试多版本矩阵的团队,docker-android 加自托管 runner 是性价比最高的组合。

七、一个值得注意的设计:每次重启擦除

README 提了一句:Emulator images are wiped each time the emulator re-starts,模拟器每次重启时镜像被擦除。

这是个刻意的设计决策,保证每次测试都从干净状态开始,避免上一次测试的残留污染下一次结果。对 CI 来说这是正确的取舍,确定性比省时间重要。

如果需要保留状态(比如调试时不想每次重装 App),挂载 -v ~/android_avd:/data 就行。它给了你选择权,但默认落在最安全的那一档。

八、和同类项目对比

README 的 See also 提到两个相关项目:

项目特点区别
本项目 docker-androidAlpine 加 KVM,极简,ADB 加 scrcpy最轻,适合 CI
budtmo/docker-android带 WebRTC 接口,浏览器直接看屏幕更易用,但镜像更大
alvr/alpine-android不同的 Alpine 基础镜像类似思路,社区维护

选型建议:纯 CI 命令行测试选本项目,最轻最快;需要浏览器远程看屏幕选 budtmo/docker-android,WebRTC 免装客户端;需要深度定制也选本项目,构建参数丰富。

九、谁该用,注意什么

强烈推荐,如果你:做 Android 开发且要在 CI 里跑插桩测试(instrumented tests);要测多 Android 版本矩阵;想搭自己的模拟器农场,不想用云服务;做移动端自动化(Appium、Espresso、UI Automator);或者想远程控制 Android 做自动化任务。

注意几点:

  1. 必须 Linux 加 KVM。 macOS 和 Windows 的 Docker Desktop 跑不了;CI runner 要是 Linux 且支持嵌套虚拟化(裸金属实例、nested VM、自建物理机等)。
  2. 资源要给够。 README 明确要求 API 33 至少 4GB 内存、8GB 磁盘,给不够会卡死或启动失败。
  3. Play Store 版要配 adbkey。 不配的话连不上带 Play 服务的镜像。
  4. 镜像体积不小。 带 SDK 和 emulator 压缩后约 2GB,CI 里建议从 Docker Hub 拉预构建镜像,别每次现建。
  5. 启动有延迟。 容器起来后,Android 系统就绪还要等几十秒,CI 脚本里要 sleep 或轮询 adb get-state。

十、小结

一句话:docker-android 把 Android 模拟器变成了一个 Docker 容器,一条命令启动,网络远程连接,版本随意切换,专为 CI 测试和远程控制而生。

它的价值不在技术多炫,而在把一件本来就麻烦的事(搭 Android 测试环境)变得极其简单。docker run 一行,模拟器上线;换个 tag,就是另一个 Android 版本;CI 流水线里无脑集成。

对 Android 开发团队来说,这种环境容器化是提升工程效率的基础设施级改进。当你不再花时间配环境,才能把时间花在真正重要的事上:写好 App。如果你的团队正在维护原生或跨端 Android 项目,把这套方案接进 CI,UI 测试就能从偶尔为之变成日常动作。


本文基于开源项目 docker-android 的仓库文档与配置文件整理,仓库地址 https://github.com/HQarroum/docker-android ,采用 Apache 2.0 协议,运行需要 Linux 加 KVM 环境。

相关文章

分享: