Project Icon

docker-android-build-box

优化的Android和Flutter开发Docker镜像

docker-android-build-box是一个集成了Android SDK和Flutter SDK的优化Docker镜像。它包含多个Android SDK平台版本、构建工具、NDK和bundletool等最新Android开发工具。镜像还整合了Java、Python、Node.js和Ruby等常用开发环境。支持Bitbucket Pipelines和Github Actions,适用于CI/CD流程,简化Android和Flutter项目的构建过程。

Docker Android Build Box

docker icon Docker Image CI

Introduction

An optimized Docker image that includes the Android SDK and Flutter SDK.

What Is Inside

The latest image will always have the latest software installed, including the last 8 Android SDKs for platforms and associated build tools. The Dockerhub description, accessible by clicking the Docker badge above, has an always up-to-date listing of the software installed on the latest image. Please also see the matrixes file for details on the various software installed on the tagged release and the latest image.

The last tagged release includes the following components:

  • Ubuntu 22.04
  • Java - OpenJDK
    • 8 (1.8)
    • 11
    • 17
  • Android SDKs for platforms:
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • Android build tools:
    • 28.0.1 28.0.2 28.0.3
    • 29.0.2 29.0.3
    • 30.0.0 30.0.2 30.0.3
    • 31.0.0
    • 32.0.0
    • 33.0.0 33.0.1 33.0.2 33.0.3
    • 34.0.0
  • Android NDK - r26c
  • Android bundletool
  • Android Emulator
  • cmake
  • TestNG
  • Python 3.8.10
  • Node.js 20, npm, React Native
  • Ruby, RubyGems
  • fastlane
  • Flutter 3.16.9
  • jEnv

Pull Docker Image

The docker image is automatically built publicly on Github Action based on the Dockerfile in this repo, there is no hidden stuff in it.

To pull the latest docker image:

docker pull mingc/android-build-box:latest

Hint: You can use a tag to a specific stable version, rather than latest of docker image, to avoid breaking your build. e.g. mingc/android-build-box:1.25.0.

Take a look at the Tags List to see all the available tags, the Changelog to see the changes between tags, and the Compatibility Matrices to see matrices of the various software available, that is tag 1.2.0 has SDKs x, y, and z... etc.

Usage

Use the image to build an Android project

Please see the caches section for how to use caching.

You can use this docker image to build your Android project with a single docker command:

cd <android project directory>  # change working directory to your project root directory.
docker run --rm -v `pwd`:/project mingc/android-build-box bash -c 'cd /project; ./gradlew build'

To build .aab bundle release, use ./gradlew bundleRelease:

cd <android project directory>  # change working directory to your project root directory.
docker run --rm -v `pwd`:/project mingc/android-build-box bash -c 'cd /project; ./gradlew bundleRelease'

Run docker image with interactive bash shell:

docker run -v `pwd`:/project -it mingc/android-build-box bash -l

Caches

Please be aware that caching will not reduce the total disk space needed, but will increase it. For example, with the Android SDK this will potentially double the amound of space. First there is the space needed for the image itself, and then the space needed for the cache. For example for 1.25.0, the image needs 16.2GB of space and then if one where to cache the SDK, without any changes, then there would be an additional 6GB of space needed; 16.2GB (raw image) + SDK Cache (6GB by default).

jEnv Cache

To allow for the global java setting via jEnv, the file /root/.jenv/version, to be cached the simplest way is to cache the complete jEnv folder, /root/.jenv/.

First create the directory on the host where jEnv will be cached. For this example it will be in ~/.dockercache/jenv/:

# mkdir ~/.dockercache/jenv

Second create a named volume, named jenv-cache. A named volume is necessary to allow the container's contents of jEnv to remain. The simplest manner is as follows:

# docker volume create --driver local --opt type=none --opt device=~/.dockercache/jenv/ --opt o=bind jenv-cache

And finally when you create / run the container, be sure to include the named volume by adding the following to the command:

-v jenv-cache:"/root/.jenv/"

e.g.

# docker run --rm -v jenv-cache:"/root/.jenv/" mingc/android-build-box bash -l `echo "Hello World"`

Gradle Cache

Add the following arguments to the docker command to cache the home gradle folder:

-v "$HOME/.dockercache/gradle":"/root/.gradle"

e.g.

docker run --rm -v `pwd`:/project  -v "$HOME/.dockercache/gradle":"/root/.gradle"   mingc/android-build-box bash -c 'cd /project; ./gradlew build'

The final step is to turn caching on by adding:

org.gradle.caching=true

to your gradle.properties. Either the project's gradle.properties or the global gradle.properties in $HOME/.dockercache/gradle/gradle.properties.

Android SDK Cache

The benefit of caching the SDK is it allows for SDK platforms / build-tools to be updated / removed in the image. For example, in 1.25.0 one could drop SDKs 27, 28, and 29; as well as adding build-tools 34. As of 1.25.0 /opt/android-sdk/ will need about 6G of disk space.

As with the jEnv cache a named volume will be needed.

First create the directory on the host where the SDKs will be cached. For this example it will be in ~/.dockercache/android-sdk/:

# mkdir ~/.dockercache/android-sdk

Second create a named volume, named android-sdk-cache. A named volume is necessary to allow the container's contents to remain. The simplest manner is as follows:

# docker volume create --driver local --opt type=none --opt device=~/.dockercache/android-sdk/ --opt o=bind android-sdk-cache
android-sdk-cache

And finally when you create / run the container, be sure to include the named volume by adding the following to the command:

-v android-sdk-cache:"/opt/android-sdk/"

e.g.

# docker run --rm -v android-sdk-cache:"/opt/android-sdk/" mingc/android-build-box bash -l

Now within the container one may interact with the sdkmanager to install build tools, platforms, etc as needed. Some brief commands... to list what is installed:

# sdkmanager --list_installed

To uninstall a platform:

# sdkmanager --uninstall 'platforms;android-26'

To install a platform:

# sdkmanager --install 'platforms;android-26'

Both the --install and --uninstall flags allow for a list to be passed, that is:

# sdkmanager --uninstall 'platforms;android-26' 'platforms;android-27'

Full documentation is available here.

Suggested gradle.properties

Setting the following jvmargs for gradle are suggested:

  • -Xmx8192m
    • Sets the max memory the JVM may use to 8192m, values of g, that is gb, are supported.
  • -XX:MaxMetaspaceSize=1024m
    • Must set due to gradle bug gradle/gradle#19750, else is unbounded.
  • -XX:+UseContainerSupport
    • Allow JVM to know it's in a container, optional as is default.
  • -XX:MaxRAMPercentage=97.5
    • Allow JVM to use at most 97.5% of the RAM in container, can be set to 1.

The total memory available to the container should be greater than the Xmx value + the MaxMetaspaceSize. For example, if 10gb is allocated to the container, and using the already listed values, then we have 10gb = 8gb (Xmx) + 1gb (MaxMetaspaceSize) + 1gb (overhead / buffer / other). If the container has 4gb of memory available than the following would be reasonable settings: 4gb = 3072m (Xmx) + 756m (MaxMetaspaceSize) + 256mb (overhead / etc).

In total the gradle.properties would be:

org.gradle.jvmargs=-Xmx8192m -XX:MaxMetaspaceSize=1024m -XX:+UseContainerSupport -XX:MaxRAMPercentage=97.5

or

org.gradle.jvmargs=-Xmx3072m -XX:MaxMetaspaceSize=756m -XX:+UseContainerSupport -XX:MaxRAMPercentage=97.5

Build an Android project with Bitbucket Pipelines

If you have an Android project in a Bitbucket repository and want to use the pipeline feature to build it, you can simply specify this docker image. Here is an example of bitbucket-pipelines.yml:

image: mingc/android-build-box:latest

pipelines:
  default:
    - step:
        caches:
          - gradle
          - gradle-wrapper
          - android-emulator
        script:
          - . ~/.bash_profile
          - jenv global 11  # switch java version
          - bash ./gradlew assemble
definitions:
  caches:
    gradle-wrapper: ~/.gradle/wrapper
    android-emulator: $ANDROID_HOME/system-images/android-21

The caches are used to store downloaded dependencies from previous builds, to speed up the next builds.

Build a Flutter project with Github Actions

Here is an example .github/workflows/main.yml to build a Flutter project with this docker image:

name: CI

on: [push]

jobs:
  build:

    runs-on: ubuntu-20.04
    container: mingc/android-build-box:latest

    steps:
    - uses: actions/checkout@v3
    - uses: actions/cache@v3
      with:
        path: /root/.gradle/caches
        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
        restore-keys: |
          ${{ runner.os }}-gradle-
    - name: Build
      run: |
        echo "Work dir: $(pwd)"
        echo "User: $(whoami)"
        flutter --version
        flutter analyze
        flutter build apk
    - name: Archive apk
      uses: actions/upload-artifact@v3
      with:
        name: apk
        path: build/app/outputs/apk
    - name: Test
      run: flutter test
    - name: Clean build to avoid action/cache error
      run: rm -fr build

Note: For improved security reference the action directly by commit hash and not tag. Please see our own action for an examples.

Run an Android emulator in the Docker build machine

Using guidelines from...

...You can write a script to create and launch an ARM emulator, which can be used for running integration tests or instrumentation tests or unit tests:

#!/bin/bash

# Arm emulators can be quite slow. For this reason it is convenient
# to increase the adb timeout to avoid errors.
export ADB_INSTALL_TIMEOUT=30

# Download an ARM system image to create an ARM emulator.
sdkmanager "system-images;android-22;default;armeabi-v7a"

# Create an ARM AVD emulator, with a 100 MB SD card storage space. Echo "no"
# because it will ask if you want to use a custom hardware profile, and you don't.
# https://medium.com/@AndreSand/android-emulator-on-docker-container-f20c49b129ef
echo "no" | avdmanager create avd \
    -n Android_5.1_API_22 \
    -k "system-images;android-22;default;armeabi-v7a" \
    -c 100M \
    --force

# Launch the emulator in the background
$ANDROID_HOME/emulator/emulator -avd Android_5.1_API_22 -no-skin -no-audio -no-window -no-boot-anim -gpu off &

# Note: You will have to add a suitable time delay, to wait for the emulator to launch.

Note that x86_64 emulators are not currently supported. See Issue #18 for details.

Choose the system Java version

As of 1.23.0, jenv is used to switch java versions. Versions prior to 1.23.0 used update-alternatives; brief documentation is available here.

Please also see the installed java versions matrix for the installed java versions and jEnv Cache on how to cache the global java version.

To allow jenv work properly, please run following command before any jenv command:

. ~/.bash_profile

The following documentation is for jenv. Please note that if the container is removed, that is run with the --rm flag, global changes will not persist unless jEnv is cached.

List all the available java versions:

# jenv versions
  system
  11
  11.0
  11.0.17
  17
* 17.0 (set by /root/.jenv/version)
  17.0.5
  1.8
  1.8.0.352
  openjdk64-11.0.17
  openjdk64-17.0.5
  openjdk64-1.8.0.352

Switch global java version to Java 8:

root@f7e7773edb7f:/project# jenv global 1.8
root@f7e7773edb7f:/project# java -version
openjdk version "1.8.0_352"
OpenJDK Runtime Environment (build 1.8.0_352-8u352-ga-1~20.04-b08)
OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)

Switch global java version to Java 11:

root@f7e7773edb7f:/project# jenv global 11
root@f7e7773edb7f:/project# java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu220.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu220.04, mixed mode, sharing)

Switch local, that is current folder, java version to Java 1.8:

root@f7e7773edb7f:/project# jenv local 1.8
root@f7e7773edb7f:/project# java -version
openjdk version "1.8.0_352"
OpenJDK Runtime Environment (build 1.8.0_352-8u352-ga-1~20.04-b08)
OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)
root@f7e7773edb7f:/project# cd ..
root@f7e7773edb7f:/# java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号