在 docker 容器中运行 Android 模拟器

Posted

技术标签:

【中文标题】在 docker 容器中运行 Android 模拟器【英文标题】:Running Android emulator in docker container 【发布时间】:2021-10-02 22:57:45 【问题描述】:

我们正在使用 wix/Detox 在 React Native 中构建一个应用程序来编写 e2e 测试。

我们使用 Docker 进行构建和运行测试。具体来说,我们正在使用社区 react-native-android Docker 映像。

我已将 fastlane 添加到映像中以构建/发布我们的应用程序,现在尝试添加一个模拟器,以便我们也可以运行测试。

这是我们的 Dockerfile:

# reactnativecommunity/react-native-android:4.0
FROM reactnativecommunity/react-native-android@sha256:c3ad9b8ed5caac0718b1c1b8f10469eb75b0ac77c86143c94f9616ee46b80b4b

RUN gem install fastlane -NV

RUN sdkmanager --install "system-images;android-31;google_apis;arm64-v8a"
RUN echo no | avdmanager create avd --name default -k "system-images;android-31;google_apis;arm64-v8a"

但是,当我运行容器并尝试启动模拟器时,我得到以下信息:

root@7b862aa149c8:/# emulator -no-audio -no-boot-anim -no-window -use-system-libs  @default
emulator: Android emulator version 30.7.5.0 (build_id 7491168) (CL:N/A)
emulator: INFO: ignore sdcard for arm at api level >= 30
emulator: feeding guest with passive gps data, in headless mode
emulator: ERROR: AdbHostServer.cpp:102: Unable to connect to adb daemon on port: 5037
cannot add library /opt/android/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so: failed
added library /opt/android/emulator/lib64/vulkan/libvulkan.so
emulator: INFO: ignore sdcard for arm at api level >= 30
emulator: INFO: userspace-boot-properties.cpp:242: Sending adb public key [QAAAACG/f/Yfe1MON5LKVoRU+iuzZRCKQTvsqLWcWh8i5ii03oHLY7y7U+0uKSE5x84OrGS0g6G9HTU7Mazh18yhbmPAQociSCfrSRIWg3IAdduFDgYPnY2G3Lj11ZLQoyRt4+xXO7zVcUPtwERpgpYQXEN5KkkEZBUxxWvrejENPAffPp4DHFqJf63sAUPh9qo6cwfSMylnl7RTBicxZ+tuDwrxA1JgcvklAs38E9gzxjNDed+1VibNUjzCtRl4DnPPmIk1OqhvjU0xZV//YXDrdhb++jQOpcKAzkCvVks4RUjJ1okytnmDfh+YUH4thQYuqNdEBnGM4wz8cPQH0YjO1SsK2sOrD0VJaGjSDAwsjne2QCFy5ET+HOUcMNKCaC60MAcCgWXLm8MdoaVLgjoG0jbUEkr/BJ2hpN7/p+qi8qMSg3Vv2M/4kdHmIEzDpJTd8TFD1bbrRjdUIheDzE1b00SKhQzDJ39sQim31IqWGuRIJ4Cb39VaHCFK6ZwZPpG9KKLSV1ww5KCKVgSsJ5zaAvhagCjXXXVrtl40v72zYq/c0BtUG4LhLixtz/zuT1WFKq8HoGFkJBvw5fBVqcvOn6yN7xI3DAuzAlQcHPyRQdHm72+//KimCVHnkxlL3hpRMir06QhMk2DsKTntXjbYuhCCn0aetEUUpai6gl1NuCbv92QlDgEAAQA= @unknown]
emulator: INFO: GrpcServices.cpp:315: Started GRPC server at 127.0.0.1:8554, security: Local
WARNING. Using fallback path for the emulator registration directory.
emulator: INFO: EmulatorAdvertisement.cpp:93: Advertising in: /root/.android/avd/running/pid_9.ini
qemu-system-aarch64-headless: PCI bus not available for hda
saving arm snapshot.... !!!

saving done.... !!!

root@7b862aa149c8:/#

【问题讨论】:

您是否尝试添加此行的末尾?模拟器 -avd $AVD_NAME -no-audio -no-cache -no-snapshot -no-window & echo "等待设备准备好" ADB 等待设备 @Arunachalamk 这对你有用吗(添加-no-cache -no-snapshot)或者你只是建议尝试一些事情? 【参考方案1】:

所以,

是否可以通过 Docker 运行 (Android) 模拟器? 可以

我对 Fastlane|wix/Detox 了解不多,但我在一个 e2e/Appium 项目中做了这个

如果是这样,怎么做? 您需要支持虚拟化的硬件

    在 Linux 中查看 CPU 是否支持 KVM 的 Intel VT/AMD-V 虚拟化

    lscpu | grep 虚拟化

虚拟化:VT-x(如果支持“Intel VT-x”或“VT-x”功能)

虚拟化:完整(如果不支持“完整”)

On AWS, you need a bare metal instance (supported x86) like c5.metal
    Android 模拟器容器脚本

https://github.com/google/android-emulator-container-scripts

    按照这个 git,使用 google API(我的情况是 27-google-x86)创建一个图像并放入 docker repo,比如 AWS ECR。

    而且,我也为 Appium 创建了一个图像(我相信使用 wix/detox 是可能的)

    到 SDK

Dockerfile

FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

# Installs i386 architecture required for running 32 bit Android tools
RUN dpkg --add-architecture i386 && \
    apt-get update && \
    apt-get dist-upgrade -y && \
    apt-get install -y --no-install-recommends openjdk-8-jdk && \
    apt-get install -y --no-install-recommends git wget unzip curl make && \
    rm -rf /var/lib/apt/lists/* && \
    apt-get autoremove -y && \
    apt-get clean

ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/jre" \
    PATH=$PATH:$JAVA_HOME/bin

# Installs Android SDK
ENV ANDROID_HOME=/android-sdk
ENV ANDROID_SDK_HOME $ANDROID_HOME

ARG ANDROID_SDK_VERSION=6514223
ARG ANDROID_BUILD_TOOLS_VERSION=27.0.0
ARG ANDROID_PLATFORM_VERSION="android-27"

RUN mkdir -p $ANDROID_SDK_HOME/cmdline-tools && \
    wget -q https://dl.google.com/android/repository/commandlinetools-linux-$ANDROID_SDK_VERSION_latest.zip && \
    unzip *tools*linux*.zip -d $ANDROID_SDK_HOME/cmdline-tools && \
    rm *tools*linux*.zip

ENV PATH $PATH:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools

RUN mkdir -p ~/.android && \
    touch ~/.android/repositories.cfg && \
    echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager --licenses && \
    echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "platform-tools" && \
    echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "build-tools;$ANDROID_BUILD_TOOLS_VERSION" && \
    echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "platforms;$ANDROID_PLATFORM_VERSION"

# Installs Node
ARG NODE_VERSION=12.x

RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION | bash
RUN apt-get install --yes nodejs
    最后,我将所有内容都编排成了一个 Jenkinsfile

【讨论】:

好的,所以当你说“跟随这个 git,使用 google API(我的情况是 27-google-x86)创建一个图像并放入 docker repo,比如 AWS ECR”时——试过了,并收到错误:emu_docker.py", line 128, in create_docker_image_interactive sys_docker = SystemImageContainer(img, args.repo) AttributeError: 'Namespace' object has no attribute 'repo. 我可以直接启动他们的 Docker 镜像(例如us-docker.pkg.dev/android-emulator-268719/images/30-google-x64-no-metrics:30.1.2),但它是一个完整的黑匣子——所以它作为二进制“工作”,但没有回答我的问题 如何我自己来做这件事,所以我可以把它作为一个起点。例如他们的图像基于 Debian 9,无法找到更新的方法,因为找不到匹配的 Dockerfile 以查看他们为创建此所做的工作。 所以,唯一可以使用 ARM 架构的就是 system-images;android-25;google_apis;armeabi-v7a 但它完全不实用,因为启动模拟器需要 +30 分钟,而实际安装应用程序也需要花费 30 分钟.是的,使用 Intel x86_64 效果更好,例如system-images;android-31;google_apis;x86_64 但确实需要裸机【参考方案2】:

这最终奏效了,但需要裸机

# reactnativecommunity/react-native-android:4.0
FROM reactnativecommunity/react-native-android@sha256:c3ad9b8ed5caac0718b1c1b8f10469eb75b0ac77c86143c94f9616ee46b80b4b

ARG IMAGE="system-images;android-31;google_apis;x86_64"
RUN sdkmanager --install "$IMAGE"
RUN echo no | avdmanager create avd --name emulator_for_e2e_testing -k "$IMAGE"

ENTRYPOINT adb start-server && emulator -avd emulator_for_e2e_testing -no-audio -no-window -no-boot-anim

【讨论】:

嗯,希望在 Github 中将其用于 CI,但我想我最好完全摆脱 Docker 并咬紧牙关设置自托管运行器

以上是关于在 docker 容器中运行 Android 模拟器的主要内容,如果未能解决你的问题,请参考以下文章

持续集成环境下的 Android 模拟器

操作docker容器

04-使用docker容器

Docker容器-容器操作

为啥不需要在 Docker 容器中运行 sshd

如何避免Docker容器启动脚本运行后自动退出