
Isolate your Android build tools and keep your modern Linux clean
Setting up a working AOSP (Android Open Source Project) environment on a modern Linux distribution like Ubuntu 22.04 can be a frustrating experience. The build tools are picky, dependencies are often outdated, and your system’s compiler may be “too new.” That’s why using Docker to create a clean, isolated Ubuntu 18.04 environment is a practical, no-compromise solution.
In this guide, I’ll show you how I created and used a Dockerized Ubuntu 18.04 container to build AOSP cleanly, reliably, and without disrupting my main system.
Step 1: Create the Docker Image:
First, we need to build a Docker image based on Ubuntu 18.04 that includes all the necessary AOSP dependencies.
(You may already have your Dockerfile for this, but if not, I can help you write one.)
Once built, verify your image:
docker images
You should see something like:
REPOSITORY TAG IMAGE ID CREATED SIZE
aosp-ubuntu18 latest abc123456789 X minutes ago Y GB
Step 2: Run the Docker Container:
Launch the container with proper permissions and volume mappings. These flags are important for AOSP building and emulator support:
docker run -it \
--name aosp-dev \
--device /dev/kvm \
--device /dev/dri \
--privileged \
-e DISPLAY=$DISPLAY \
-e QT_X11_NO_MITSHM=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v ~/aosp:/aosp \
-v ~/.android:/root/.android \
aosp-ubuntu18
This gives your container access to GPU rendering, emulator support, and mounts your AOSP source tree (~/aosp) directly into /aosp in the container.
Tip: If you need to kill a previously running emulator, just run:
ps aux | grep emulator
kill -9 <PID>
Step 3: Set Up the Build Environment:
Once inside the container:
Navigate to your source directory:
cd /aosp
Source the environment:
. build/envsetup.sh
Choose a target device using lunch. For example, if you’re building a generic x86_64 emulator image:
lunch sdk_phone_x86_64
You should see output like:
============================================
PLATFORM_VERSION=12
TARGET_PRODUCT=sdk_phone_x86_64
TARGET_BUILD_VARIANT=eng
...
============================================
Step 4: Build AOSP:
With the target selected, initiate the build with:
m -j16
The -j16 flag tells the build system to run up to 16 parallel jobs. Adjust this number depending on your system’s CPU core count and memory.
(Optional) Run X11 Test Apps
apt update && apt install -y x11-apps
xeyes
This should pop up a pair of eyes following your cursor—proof that GUI forwarding is working!
Cleaning Up:
If you want to delete the image to save space:
docker rmi aosp-ubuntu18
To re-run your container later:
docker run -it \
--name aosp-dev \
--device /dev/kvm \
--device /dev/dri \
--privileged \
-e DISPLAY=$DISPLAY \
-e QT_X11_NO_MITSHM=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v ~/.android:/root/.android \
-v ~/aosp:/aosp \
aosp-ubuntu18
Conclusion:
By using Docker to isolate an Ubuntu 18.04 build environment, you keep your host system clean and sidestep countless compatibility headaches. Whether you’re working on custom ROMs, emulator targets, or device bring-up, this approach makes the AOSP experience smoother and more predictable.
However, in the end, the emulator failed to appear, and I ultimately gave up on it.