-
Notifications
You must be signed in to change notification settings - Fork 4
How to build a Lightweight Docker Container for Android Build
Automated build and test helps us to speed up the development and increase productivity. But it takes time because it requires the installation of many dependencies and devices to run the tests.
Using a docker container will help us to build and tests for multiple branches, and save us a lot of time.
We can search and find many existing android containers for Android, e.g. in docker hub. But they are so big as they support most of versions of Android API, platform tools, NDK… That makes the docker images are too big.
So you may want to build your own Android docker container which contains only your needed APIs.
In this article, we will know how to create a lightweight Android docker and push it to Docker Hub automatically by associating a git repository (1*) to Docker Hub.
(1*) Docker Hub supports Github and Bitbucket
The final image will contain:
- Latest Gradle & Gradlew
- Latest Android API
- Latest Android Build Tools
- Latest Android NDK (Side by side)
- Accepted all licenses
Step by step:
- Create Docker Hub account, then create a repository.
- Create a git repository to store the Dockerfile. I prefer Bitbucket because it’s free and Atlassian has many products which can be integrated with Bitbucket and manage projects effectively.
- Link Github or Bitbucket repository to Docker Hub.
- Setup automated builds for your master branch or feature branches.
- Download and install Docker. (2*)
-
If you’re running Windows 10, Docker cannot run on Windows 10 Home, then you have some options:
- Using a Docker Toolbox, but this is a legacy solution and isn’t recommended.
- Upgrade to Windows 10 Pro
- Install Docker in a virtual machine, e.g. VirtualBox
- Start a docker container on top of Ubuntu
- Install packages manually
- Take the manual steps to build a Dockerfile
- Commit Dockerfile to your Bitbucket repository and wait for the build in Docker Hub.
(2*) Important note:
- Docker Desktop for Windows requires Windows 10 and Microsoft Hyper-V
- If you are running Windows 8.1, so you need to run Docker Toolbox.
- Microsoft Hyper-V is an optional hypervisor-based virtualization technology feature for certain x64 versions of Windows (which includes Windows 8.1)
- Docker Toolbox uses Oracles’s hypervisor-based virtualization technology which is called Virtualbox
- VirtualBox cannot be used with Microsoft Hyper-V (the 2 products conflict with each other)
We focus on the step (6), (7) and (8) to build a Dockerfile, as we don’t really have any issues with the other steps or I already linked the documentation.
We’re going to build an image on top of Ubuntu.
Start a docker and go to bash (3*):
docker run --privileged -it --name android-container ubuntu bash
-
--privileged
: grant permission to launch VM on container. -
-it
: interactively execute shell cmd -
--name android-container
: container’s name
(3*) To go to bash later:
$ docker exec -it android-container /bin/bash
apt update && apt install -y openjdk-8-jdk vim git unzip libglu1 libpulse-dev libasound2 libc6 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxi6 libxtst6 libnss3 wget
You may not want to install all above dependencies, e.g. you may not a fan of vim and want another replacement tool.
- Download Gradle to
/tmp
- Unzip the content to
/opt/gradle
wget https://services.gradle.org/distributions/gradle-6.3-bin.zip -P /tmp && unzip -d /opt/gradle /tmp/gradle-6.3-bin.zip
- Make directory /opt/gradlew
- Install Gradle Wrapper
mkdir /opt/gradlew && /opt/gradle/gradle-6.3/bin/gradle wrapper --gradle-version 6.3 --distribution-type all -p /opt/gradlew && /opt/gradle/gradle-6.3/bin/gradle wrapper -p /opt/gradlew
- Make directory
/opt/android/cmdline-tools
- Download Android SDK command line tool and unzip
mkdir /opt/android
mkdir /opt/android/cmdline-tools
wget 'https://dl.google.com/android/repository/commandlinetools-linux-6200805_latest.zip' -P /tmp && unzip -d /opt/android/cmdline-tools /tmp/commandlinetools-linux-6200805_latest.zip
yes Y | /opt/android/cmdline-tools/tools/bin/sdkmanager --install "build-tools;29.0.3" "platforms;android-29" "platform-tools" "ndk;21.1.6352462"
(4*) Add
"emulator"
if you’re gonna run tests with emulators with this docker image
Edit file .bashrc by using any installed tool, e.g. vim, to add these environment variables:
- GRADLE_HOME=/opt/gradle/gradle-6.3
- ANDROID_HOME=/opt/android
- ANDROID_NDK_HOME=/opt/android/ndk/21.1.6352462
- PATH "$PATH:/opt/gradle/gradle-6.3/bin:/opt/gradlew:/opt/android/emulator:$ANDROID_HOME/cmdline-tools/tools/bin:/opt/android/platform-tools:/opt/android/ndk/21.1.6352462"
- LD_LIBRARY_PATH "$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib"
Compile the changes:
source ~/.bashrc
Remove the downloaded files in /tmp
rm /tmp/commandlinetools-linux-6200805_latest.zip
rm /tmp/gradle-6.3-all.zip
So you are now can test it to ensure it contains everything you need! Be ready to convert this into Dockerfile
After testing, you think your docker container is working great. Then based on the previous manual steps, you can create a Dockerfile. It should be like this:
FROM ubuntu
LABEL maintainer "simplatex.com.au@gmail.com"
WORKDIR /
SHELL ["/bin/bash", "-c"]
# To avoid "tzdata" asking for geographic area
ARG DEBIAN_FRONTEND=noninteractive
# Version of tools
ARG GRADLE_VERSION=6.3
ARG ANDROID_API_LEVEL=29
ARG ANDROID_BUILD_TOOLS_LEVEL=29.0.3
ARG ANDROID_NDK_VERSION=21.1.6352462
# Dependencies and needed tools
RUN apt update -qq && apt install -qq -y openjdk-8-jdk vim git unzip libglu1 libpulse-dev libasound2 libc6 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxi6 libxtst6 libnss3 wget
# Download gradle, install gradle and gradlew
RUN wget -q https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -P /tmp \
&& unzip -q -d /opt/gradle /tmp/gradle-${GRADLE_VERSION}-bin.zip \
&& mkdir /opt/gradlew \
&& /opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle wrapper --gradle-version ${GRADLE_VERSION} --distribution-type all -p /opt/gradlew \
&& /opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle wrapper -p /opt/gradlew
# Download commandlinetools, install packages and accept all licenses
RUN mkdir /opt/android \
&& mkdir /opt/android/cmdline-tools \
&& wget -q 'https://dl.google.com/android/repository/commandlinetools-linux-6200805_latest.zip' -P /tmp \
&& unzip -q -d /opt/android/cmdline-tools /tmp/commandlinetools-linux-6200805_latest.zip \
&& yes Y | /opt/android/cmdline-tools/tools/bin/sdkmanager --install "build-tools;${ANDROID_BUILD_TOOLS_LEVEL}" "platforms;android-${ANDROID_API_LEVEL}" "platform-tools" "ndk;${ANDROID_NDK_VERSION}" \
&& yes Y | /opt/android/cmdline-tools/tools/bin/sdkmanager --licenses
# Environment variables to be used for build
ENV GRADLE_HOME=/opt/gradle/gradle-$GRADLE_VERSION
ENV ANDROID_HOME=/opt/android
ENV ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}
ENV PATH "$PATH:$GRADLE_HOME/bin:/opt/gradlew:$ANDROID_HOME/emulator:$ANDROID_HOME/cmdline-tools/tools/bin:$ANDROID_HOME/platform-tools:${ANDROID_NDK_HOME}"
ENV LD_LIBRARY_PATH "$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib"
# Clean up
RUN rm /tmp/gradle-${GRADLE_VERSION}-bin.zip \
&& rm /tmp/commandlinetools-linux-6200805_latest.zip