Build AOSP on Docker

Famidha Thurab
Make Android
Published in
7 min readNov 26, 2023

About installing docker and building android open source project on Ubuntu machine.

Photo by Nick Dunn on Unsplash

Multiple OS running on a computer is not a new concept, we are now interested to keep tools handy including an Operating System also.

When it comes to run multiple OS on a computer, we are aware of hypervisor solutions like Virtual Box and VMWare.

In the hypervisor solution, we used to allocate the computer resources like ram, CPU and hard drive, this solution is good and efficient also, in that case, we almost fall with a half amount of resources in guest operating system what we actually have in host OS.

Building the AOSP source always require more CPU cores, ram, and a hard drive as well.

So why not we use a lightweight docker containers and use maximum resources from the host OS.

Also, building an android project requires a specific environment for each platform and target, with variety of packages preinstalled which becomes tedious when we start facing issues in the builds because of the contradictions in the versions of the packages installed as android upgrades and evolves.
This can be resolved with docker.

Lets see how to achieve it.

  1. Installing docker
  2. Building a docker image
  3. Running a container
  4. Building android

Installing docker

Set up the repository

Update the apt package index and install packages to allow apt to use a repository over HTTPS:

$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg

Add Docker’s official GPG key:

  $ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

Use the following command to set up the repository:

 $ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker Engine

Update the apt package index:

 $ sudo apt-get update

Install Docker Engine, containerd, and Docker Compose.

 $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify that the Docker Engine installation is successful by running the hello-world image.

$ sudo docker run hello-world

This command downloads a test image and runs it in a container. When the container runs, it prints a confirmation message and exits.

You have now successfully installed and started Docker Engine.

Building a docker image

Lets create an ubuntu image for building android.

  1. install required dependencies
  2. creating non-root user and group
  3. copying required files
FROM ubuntu:18.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && dpkg --add-architecture i386 && apt-get update
RUN apt-get install -y xxd apt-utils openjdk-8-jdk openjdk-11-jdk iputils-ping autoconf openssh-server bsdmainutils simg2img jq && \
update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java

RUN apt-get update && apt-get install -y git-core gnupg flex bison gperf zip curl zlib1g-dev \
gcc-multilib g++-multilib lib32ncurses5-dev lib32z1 \
x11proto-core-dev libx11-dev \
lib32z-dev python-argparse ccache libreadline6-dev \
libgl1-mesa-dev tofrodos python-markdown libxml2-utils \
xsltproc zlib1g-dev squashfs-tools bc tesseract-ocr \
imagemagick gettext python-libxml2 unzip dosfstools mtools \
dos2unix python-mako liblz4-tool libssl-dev build-essential \
minizip subversion texinfo git \
libxkbcommon-x11-0 git-lfs libncurses5 libncursesw5

RUN ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so || true

RUN echo "dash dash/sh boolean false" | debconf-set-selections \
&& dpkg-reconfigure dash

RUN apt-get update && apt-get install -y gawk wget diffstat \
chrpath socat cpio rpm2cpio xz-utils debianutils iputils-ping libegl1-mesa \
libsdl1.2-dev lzop lib32z1-dev libelf-dev xterm locales vim bash-completion screen \
texlive-full libterm-readkey-perl intltool xalan software-properties-common openssl groff-base cmake filepp device-tree-compiler \
gnupg2 apt-utils sudo rsync gnupg-agent gprbuild iproute2 net-tools u-boot-tools \
zstd jq

RUN apt-get update && apt-get install -y python python-pkg-resources python-setuptools lcov adb

RUN apt-get update && apt-get install -y python3 python3-pip python3-pkg-resources python3-pexpect python3-git python3-jinja2 \
python3-msgpack python3-setuptools

RUN add-apt-repository ppa:openjdk-r/ppa \
&& apt-get update && apt-get install -y openjdk-8-jdk

RUN curl "https://bootstrap.pypa.io/pip/2.7/get-pip.py" -o /"get-pip.py" && python /get-pip.py

RUN python -m pip install --user cryptography

RUN python -m pip install Jira pycryptodome

RUN pip3 install requests

RUN curl -o /usr/local/bin/repo https://storage.googleapis.com/git-repo-downloads/repo-1 && chmod a+x /usr/local/bin/repo

COPY gitconfig /home/$username/.gitconfig

RUN chown $userid:$groupid /home/$username/.gitconfig

CMD ["bash"]

Above is the source code of an ubuntu image for building android.

The image uses ubuntu18 as a base image, installs the packages/dependencies for building AOSP source code.

Below command builds an ubuntu image.

$ sudo docker build -t ubuntu -f dockerfile .

Now we have an ubuntu image available

$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 021445a60600 6 days ago 6.21GB

Running a container

So, now will spin up an ubuntu container.

$ sudo docker run -d -rm -v $HOME:$HOME ubuntu

A container with ubuntu image is up and running.

$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6abab0ab4f51 ubuntu "bash" 39 seconds ago Up 38 seconds 22/tcp ecstatic_keller

Building android

Now we have our container running with the environment to build android, lets start building the same.

With the below command will be interacting with the container shell

$ sudo docker exec -it 6abab0ab4f51 bash

By running the above command will get inside the container shell.

Now we have to set up the git account or copy the .gitconfig file while creating the docker image as given above in the dockerfile for downloading the AOSP source.

$ git config --global user.name "User name"
$ git config --global user.email "email"

User name and email is your GitHub account username and email, that we need to configure with the container.

As I said the repo uses manifest for managing the various git repositories, now the time to initialize the repo.

Lets create a folder and switch to that folder for executing build.

Will initialize the source with the command below.

$ repo init -u https://android.googlesource.com/platform/manifest

To initialize the source from a specific branch then can use -b <branch name> as a suffix to the above command.

$ repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r9

Now, to download the source code, run the command as below.

$ repo sync

As the source code is available, lets build the code by running the commands to set the environment, to select the target and then build the source.

$ source build/envsetup.sh

To select the target, have to run the lunch command which will be listing down the available target.

$ lunch

You're building on Linux

Lunch menu .. Here are the common combinations:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_barbet-userdebug
4. aosp_bluejay-userdebug
5. aosp_bluejay_car-userdebug
6. aosp_bramble-userdebug
7. aosp_bramble_car-userdebug
8. aosp_car_arm-userdebug
9. aosp_car_arm64-userdebug
10. aosp_car_x86-userdebug
11. aosp_car_x86_64-userdebug
12. aosp_cf_arm64_auto-userdebug
13. aosp_cf_arm64_phone-userdebug
14. aosp_cf_x86_64_auto-userdebug
15. aosp_cf_x86_64_auto_mdnd-userdebug
16. aosp_cf_x86_64_foldable-userdebug
17. aosp_cf_x86_64_only_phone_hsum-userdebug
18. aosp_cf_x86_64_pc-userdebug
19. aosp_cf_x86_64_phone-userdebug
20. aosp_cf_x86_64_tv-userdebug
21. aosp_cf_x86_phone-userdebug
22. aosp_cf_x86_tv-userdebug
23. aosp_cheetah-userdebug
24. aosp_cheetah_car-userdebug
25. aosp_cloudripper-userdebug
26. aosp_coral-userdebug
27. aosp_coral_car-userdebug
28. aosp_felix-userdebug
29. aosp_flame-userdebug
30. aosp_flame_car-userdebug
31. aosp_husky-userdebug
32. aosp_lynx-userdebug
33. aosp_oriole-userdebug
34. aosp_oriole_car-userdebug
35. aosp_panther-userdebug
36. aosp_panther_car-userdebug
37. aosp_raven-userdebug
38. aosp_raven_car-userdebug
39. aosp_ravenclaw-userdebug
40. aosp_redfin-userdebug
41. aosp_redfin_car-userdebug
42. aosp_redfin_vf-userdebug
43. aosp_ripcurrent-userdebug
44. aosp_shiba-userdebug
45. aosp_slider-userdebug
46. aosp_sunfish-userdebug
47. aosp_sunfish_car-userdebug
48. aosp_tangorpro-userdebug
49. aosp_trout_arm64-userdebug
50. aosp_trout_x86_64-userdebug
51. aosp_whitefin-userdebug
52. aosp_x86-eng
53. aosp_x86_64-eng
54. arm_krait-eng
55. arm_v7_v8-eng
56. armv8-eng
57. armv8_cortex_a55-eng
58. armv8_kryo385-eng
59. beagle_x15-userdebug
60. beagle_x15_auto-userdebug
61. car_ui_portrait-userdebug
62. car_x86_64-userdebug
63. db845c-userdebug
64. gsi_car_arm64-userdebug
65. gsi_car_x86_64-userdebug
66. hikey-userdebug
67. hikey64_only-userdebug
68. hikey960-userdebug
69. hikey960_tv-userdebug
70. hikey_tv-userdebug
71. poplar-eng
72. poplar-user
73. poplar-userdebug
74. qemu_trusty_arm64-userdebug
75. rb5-userdebug
76. sdk_car_arm-userdebug
77. sdk_car_arm64-userdebug
78. sdk_car_md_x86_64-userdebug
79. sdk_car_portrait_x86_64-userdebug
80. sdk_car_x86-userdebug
81. sdk_car_x86_64-userdebug
82. sdk_pc_x86_64-userdebug
83. silvermont-eng
84. uml-userdebug
85. yukawa-userdebug
86. yukawa_sei510-userdebug

Which would you like? [aosp_arm-eng]

The output of the lunch command, looks like above from where you can select the target by passing the number of the target into the command prompt or just run lunch <target-name>.

Pick from common choices above (e.g. 13) or specify your own (e.g. aosp_barbet-eng): 1
11:14:45 Build sandboxing disabled due to nsjail error.
11:14:47 Build sandboxing disabled due to nsjail error.

Hint: next time you can simply run 'lunch aosp_arm-eng'

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=14
PRODUCT_INCLUDE_TAGS=com.android.mainline
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=generic
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.15.0-1047-aws-x86_64-Ubuntu-18.04.6-LTS
HOST_CROSS_OS=windows
BUILD_ID=UD1A.230803.022.C1
OUT_DIR=out
============================================

Now will execute the below command to build the code.

$ m 
[100% 130088/130088] Target vbmeta image: out/target/product/generic/vbmeta.img

#### build completed successfully (02:01:44 (hh:mm:ss)) ####

root@566c6f418de1:/aosp#

Now we have successfully built the android source code.

Thanks for reading!!

--

--

Famidha Thurab
Make Android

DevOps Engineer| Editor Make Android | Writes on AIOps | Android IVI | AOSP | Docker | Kubernetes | AWS | Jenkins | Python | Shell | Git