Linux containers on Android.
No root required.

Podroid spins up a real Alpine Linux VM using QEMU and a custom kernel.
Run Podman, Docker, and LXC with a polished built-in terminal,
or open the in-app X11 viewer for GUI apps. Install the APK, tap Start, go.

Download APK Read the docs View on GitHub

ARM64 · Android 9+ · No root · GPLv2

Everything a dev environment should have

Built from the kernel up for containers, not just shell access.

Podman, Docker, LXC

All three major container engines work zero-config. Native kernel overlay2 for Docker, fuse-overlayfs for rootless Podman, and a pre-configured lxcbr0 bridge for LXC. Pull any OCI image and run it.

Custom Linux 7.0.5 Kernel

Compiled from scratch with netfilter, bridge, overlayfs, veth, IPVS, VXLAN, IPsec, cgroup v2, and binfmt_misc all built-in. Docker's check-config.sh reports zero fixable complaints.

Real Terminal

Termux TerminalView with xterm-256color, proper PTY, full mouse support, 122 color themes, 13 fonts (plus your own .ttf via the system file picker), and an extra-keys bar with F1–F12, ESC, CTRL, ALT.

Port Forwarding

Expose any VM port to your Android device at runtime via QMP control. Run a web server, database, or API and hit it from your phone's browser.

Built-in SSH

Dropbear SSH server on port 9922 (configurable). Connect from your laptop, VS Code Remote, or any SSH client on the same network.

Persistent & Fast

Overlayfs over a persistent ext4 image. Containers, packages, and configs survive reboots. ZRAM swap gives 2× effective RAM. Boots in 6–30 seconds.

In-app X11 Desktop

Tap the monitor icon in the terminal and an in-app viewer opens, talking RFB to Xvnc inside the VM. Touch becomes mouse, soft-keyboard becomes keyboard, and PCM audio streams from PulseAudio. Run firefox, xterm, anything from Alpine.

One-tap Diagnostics

Settings → Export Diagnostic Log bundles app info, settings, VM state, app logcat, and the full QEMU console into a single log.txt and shares it via the system share sheet. No ADB needed to file a useful bug report.

Tuned for Software Emulation

KVM needs root, so we leaned hard on TCG instead. Multi-thread TCG with a 512 MB translation cache, a dedicated I/O thread for the rootfs disk, ZRAM lz4 swap at half RAM, and mitigations=off in the guest combine for a 5–15% CPU win. Native 16 KB page alignment, so Pixel 8/9/10 are first-class.

How Podroid stacks up

Termux gives you a Linux shell. Google Terminal gives you a VM with optional manual container setup. Podroid ships three container engines out of the box.

Capability
Podroid this project
Termux v0.118+
Google Terminal AVF
Root required ✓ No ✓ No ✓ No
Real container runtime ✓ Podman + Docker + LXC manual setup
VM isolation ✓ QEMU ✗ shared kernel ✓ AVF
Docker Hub images manual setup
Custom kernel ✓ Linux 7.0.5 ✗ host kernel
Works on any ARM64 ✓ Android 9+ ✗ Pixel only
Port forwarding ✓ via QMP via socat
Downloads folder sharing ✓ virtio-9p
SSH server ✓ Dropbear via pkg manual setup
xterm-256color + mouse basic
Configurable RAM / CPUs ✓ 512MB–4GB, 1–8 cores limited

How it works

Four sockets, one VM, zero root. Here's what happens when you tap Start.

┌────────────────────── Android App (Compose) ─────────────────────────┐ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ PodroidService │ │ QEMU 11 TCG │ │ Terminal UI │ │ │ │ (ForegroundSvc) │ │ ARM64-native │ │ Termux View │ │ │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ └───────────┼─────────────────────┼─────────────────────┼──────────────┘ │ │ │ │ ┌─────────────────▼────────────────┐ │ │ │ Alpine Linux 3.23 VM │ │ │ │ /sbin/init (busybox) │ │ │ │ OpenRC (PID 1) │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ │ │ Podman + │ │ Linux 7.0.5 │ │ │ └──►│ │ Docker │ │ (custom) │ │◄───┘ boot stages │ │ + LXC │ └──────────────┘ │ libpodroid-bridge.so │ └──────────┘ │ PTY ↔ virtio-console │ │ │ /dev/vda ext4 overlay (rw) │ │ /dev/vdb squashfs base (ro) │ └──────────────────────────────────┘ terminal.sock ↔ hvc0 → primary shell I/O ctrl.sock ↔ hvc1 → debounced SIGWINCH resize signals serial.sock ↔ ttyAMA0 → boot log stream → boot stage detection qmp.sock → runtime port-forward control
1

QEMU loads the kernel

Custom Linux 7.0.5 + a tiny initramfs and an Alpine squashfs are extracted from APK assets on first launch.

2

Overlay + switch_root

Init mounts the squashfs as the read-only base, the ext4 image as the writable upper, then switch_roots into /sbin/init.

3

OpenRC services start

Cgroup v2, network, Docker bind-mount, lxcbr0 bridge, MASQUERADE NAT, sysctls, and Dropbear SSH all come up automatically.

4

Bridge connects

libpodroid-bridge.so relays your PTY to the VM's virtio-console. Shell is ready.

Running in under a minute

No configuration needed. Download, install, go.

1

Download the latest APK from the Releases page.

2

Install it on your Android device (ARM64, Android 9+).

3

Tap Start VM. Watch the boot progress; typically ready in 6–30 seconds.

4

Tap Open Terminal to access the Alpine shell.

5

Run containers. Any image from Docker Hub works out of the box.

# Podman: rootless, works out of the box # podman run --rm alpine echo hi # Docker: pre-installed, auto-started # docker run -d -p 8080:80 nginx # LXC: pre-installed, bridge ready # lxc-create -t alpine -n test # lxc-start -n test # GUI apps: tap the monitor icon # apk add firefox && firefox & # SSH (enable in Settings) $ ssh root@<phone-ip> -p 9922

Common questions

For the full picture, read the documentation. If something still isn't covered, open an issue on GitHub.

Does this require root or a modified Android?
No. Podroid runs entirely in userspace using QEMU's TCG (software emulation). No root, no custom recovery, no Magisk. Any stock Android 9+ ARM64 device works.
Why not just use Termux + proot?
Termux is great for a Linux shell, but it runs on Android's host kernel. That kernel doesn't have the namespaces, cgroups, or netfilter rules needed for real containers. proot is a chroot emulation; containers built for Docker, Podman, or LXC won't work reliably. Podroid runs a real VM with its own custom kernel, so every OCI image from Docker Hub just works.
How is this different from Google Terminal / AVF?
Google's Terminal app uses Android Virtualization Framework (AVF), a system-level hypervisor available only on recent Pixel devices. It gives you a Debian VM but no container runtime and limited configurability. Podroid uses QEMU TCG (software emulation), so it works on any ARM64 Android 9+ device, not just Pixels, and ships with three container engines, port forwarding, SSH, and a configurable terminal.
Is performance usable? QEMU is slow.
TCG is software emulation, so compute-heavy workloads are slower than native. Podroid ships several optimizations: a 256–512 MB translation cache, a dedicated I/O thread for virtio-blk (big win for image pulls), ZRAM swap for 2× effective RAM, and mitigations=off in the guest kernel for a 5–15% CPU gain. For typical dev tasks like running a web server, a database, or CLI tools, it's very usable.
Can I run GUI apps like Firefox?
Yes. Tap the monitor icon in the terminal's top bar to open the in-app X11 viewer. It speaks RFB 3.8 to Xvnc running inside the VM and streams audio from PulseAudio. Then just apk add firefox (or anything else from the Alpine repos) and launch it from the shell. Touch becomes mouse, the soft-keyboard becomes keyboard, and the picture letterboxes to your phone's aspect ratio.
Can I access my Android files from the VM?
Yes. Toggle Downloads folder sharing in Settings and the Android Downloads folder is exposed to the VM via virtio-9p, mounted inside the guest at /mnt/downloads. Files you drop in Downloads on the phone show up there immediately, and anything the VM writes to /mnt/downloads appears back in Downloads.
How much storage does it use?
The APK is ~200 MB (QEMU + kernel + initramfs + Alpine squashfs + fonts). On first launch you choose a VM disk size between 2 GB and 64 GB; this is a sparse storage.img that only grows as you pull images and install packages.
Can I connect from my laptop over SSH?
Yes. Dropbear SSH runs on port 9922 by default (configurable in Settings). As long as your laptop and phone are on the same network, ssh root@<phone-ip> -p 9922 gives you a remote shell. Useful for VS Code Remote or any SSH client.