Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 

Repository files navigation

Android in Docker on ARM64 (redroid) — what actually works in 2026

Running redroid (Android in a Docker container) on a plain ARM64 cloud server. Empty Ubuntu box to a working Android instance answering ADB: under 30 minutes, about €0.60 of server time.

Most redroid guides online still document the pre-binderfs way of setting up the kernel side. On any current kernel that produces a container which starts, sits there, and dies with nothing useful in the logs. This repo is the version that works on kernel 6.x, with the dead ends written down.

Tested 2026-08-28 on Scaleway BASIC2-A2C-4G (Ampere ARM64, 2 vCPU, 4 GB), Ubuntu 24.04, kernel 6.8.0-106-generic, PAR1. Connected over ADB from a laptop in Hanoi to a server in Paris.


TL;DR

# 1. Check the environment BEFORE installing anything
uname -m           # aarch64
getconf PAGESIZE   # 4096   <-- this is the gate
uname -r           # 6.8.0-106-generic

# 2. binder
apt update
apt install -y linux-modules-extra-$(uname -r)
modprobe binder_linux devices="binder,hwbinder,vndbinder"

# 3. binderfs — the step almost every guide is missing
mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
ls /dev/binderfs          # binder-control, binder, hwbinder, vndbinder

# 4. Docker
curl -fsSL https://get.docker.com | sh

# 5. Run it (ADB bound to localhost only — see Security)
mkdir -p /root/redroid-data
docker run -itd --privileged --name redroid13 \
  -v /root/redroid-data:/data \
  -p 127.0.0.1:5555:5555 \
  redroid/redroid:13.0.0_64only-latest

1. The page-size gate

getconf PAGESIZE

Must be 4096. redroid requires 4 KB memory pages.

Oracle Linux on Ampere now defaults to 64 KB pages, and redroid fails there with mprotect errors that look like a redroid bug and are not one. Ubuntu on ARM64 uses 4 KB.

Run this check first. It takes one second and saves hours.

2. binder: the part the tutorials get wrong

Android's IPC needs the binder_linux kernel module. On a fresh Ubuntu 24.04 ARM image it isn't present:

apt install -y linux-modules-extra-$(uname -r)
modprobe binder_linux devices="binder,hwbinder,vndbinder"

modprobe succeeds. And then /dev/binder, /dev/hwbinder and /dev/vndbinder do not exist.

That is where most people stop, because every older guide says those device nodes should now be there. On kernel 6.x they never are. Binder moved to a filesystem — binderfs — and the devices= module parameter is accepted but creates nothing on its own. You have to mount it:

mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
ls /dev/binderfs
# binder  binder-control  hwbinder  vndbinder

One-line diagnostic that identifies this instantly:

grep binder /proc/filesystems
# nodev   binder     <-- binderfs kernel, mount it

3. ashmem: skip it

A lot of guides tell you to load ashmem_linux. On kernel 5.18+ with Android 12+ images this is obsolete — those images use memfd instead. Chasing ashmem_linux on a modern system is wasted time.

4. Persistence

None of the above survives a reboot unless you write it down:

echo binder_linux > /etc/modules-load.d/redroid.conf
echo 'options binder_linux devices=binder,hwbinder,vndbinder' > /etc/modprobe.d/redroid.conf
echo 'binder /dev/binderfs binder defaults 0 0' >> /etc/fstab

5. Security: ADB has no authentication

This matters more than anything else here.

ADB on port 5555 has no authentication at all. Published as -p 5555:5555, it is open to the whole internet and anyone who finds it has full control of the Android instance — install, read files, run shell.

Bind it to localhost and reach it through an SSH tunnel instead:

docker run ... -p 127.0.0.1:5555:5555 ...

From your own machine:

ssh -i <your-key> -L 5555:127.0.0.1:5555 root@SERVER
# then, in another terminal:
adb connect 127.0.0.1:5555
adb devices
adb shell getprop ro.product.cpu.abi   # arm64-v8a

6. Resource cost

One idle Android 13 instance:

metric value
RAM 594 MiB
CPU 0.07%
processes ~1005

So roughly five instances fit in 4 GB. Measure with docker stats.

7. Provider note: price is not the whole story

Hetzner CAX (ARM) is the cheapest at about €0.011/hour. On the day of this test its ARM stock was sold out in every location — Helsinki, Falkenstein and Nuremberg all unavailable. Scaleway had capacity immediately at €0.0293/hour.

If you are recommending a provider for ARM workloads, mention availability, not just the hourly price.

8. Verifying it worked

docker logs -f redroid13
adb shell getprop sys.boot_completed      # 1
adb shell getprop ro.product.cpu.abi      # arm64-v8a  (native ARM, no translation)

9. Teardown

docker rm -f redroid13

Then delete the server in your provider's console so billing stops. Hourly billing does not stop when the container does.


Why this repo exists

I needed to answer a client honestly about whether redroid runs on ARM64 cloud servers and what it costs, so I ran it instead of guessing. These are the notes from that run, including the things that went wrong.

Corrections and additions welcome — open an issue.

— Bill · fullstacksolutiondev.com

About

Android in Docker on ARM64: the binderfs step that most guides miss

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors