Skip to content

How to build a Lightweight Docker Container for Android Build

Thuan Nguyen edited this page Jul 28, 2022 · 1 revision

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.

What are we gonna do?

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:

  1. Create Docker Hub account, then create a repository.
  2. 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.
  3. Link Github or Bitbucket repository to Docker Hub.
  4. Setup automated builds for your master branch or feature branches.
  5. 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
  1. Start a docker container on top of Ubuntu
  2. Install packages manually
  3. Take the manual steps to build a Dockerfile
  4. 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.

Start a docker container

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

Install packages manually

Dependencies and needed tools

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.

Gradle and Graddle Wrapper

  • 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

Android SDK command line tool

  • 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

Run sdkmanager to install platform, build-tools, platform-tools, NDK (side by side) (4*)

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

Set up environment variables

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

Clean up

Remove the downloaded files in /tmp

rm /tmp/commandlinetools-linux-6200805_latest.zip
rm /tmp/gradle-6.3-all.zip

It's ready!

So you are now can test it to ensure it contains everything you need! Be ready to convert this into Dockerfile

Create Dockerfile base on above manual steps

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