Skip to content

ravindu644/Ubuntu-Chroot

Repository files navigation

Ubuntu Chroot banner

Latest release Telegram channel License: MIT Android support Linux desktop


🟠 Ubuntu-Chroot

A comprehensive Android Linux environment featuring Ubuntu 24.04 with a built-in WebUI Control Panel, Beautiful desktop environment, advanced namespace isolation, and in-built development tools for a seamless Linux desktop experience on Android - with full hardware access and x86_64 emulation.

Quick Navigation

πŸ‘€ Requirements

❔ Why This Is Different

Advanced Namespace Isolation

  • Utilizes Linux namespaces (mount, PID, UTS, IPC) for true namespace isolation. Unlike basic chroot setups, this creates separate filesystem mounts, process IDs, hostnames, and IPC spaces - preventing interference between the chroot and Android host.[1]

    Process isolation demonstration

    Namespace isolation diagram
    Illustration of isolated namespaces

Tip

Why Namespaces Matter:

Traditional chroot only changes the root directory. Namespaces create isolated environments, ensuring processes inside the chroot cannot see or affect host system processes, hostnames, or IPC resources.

This allows full Linux services to run without conflicts, security risks, or performance loss.

Full Hardware Access

  • Complete access to all hardware features of your Android device, including WiFi adapters, ADB, Odin, and more.[2]

    Using an external WIFI adapter inside chroot

    Hardware access screenshot
    Example tools running with full device access

x86_64 Emulation

  • Preconfigured x86_64 emulation enables you to run x86_64 applications and binaries directly on your Android device with full hardware access.[3]

    Odin4 x86_64 running with full hardware access

    Odin4 x86_64 binary running
    Rebooting a phone in Download Mode using x86_64 Odin4 on an ARM64 device

"It Just Works" Philosophy

  • No complex terminal commands required. The desktop environment starts automatically when the chroot launches, and most developer tools are preconfigured and ready to use out of the box.

Containerization Ready

  • When you flash the module, it extracts the Ubuntu rootfs to /data/local/ubuntu-chroot, which the backend uses as the installed rootfs.

  • Under Experimental Features in the WebUI, you can migrate your directory-based chroot to an ext4 sparse image, containerizing your environment into a single .img file.

  • The Linux environment runs on an ext4 image outside Android partitions, benefiting from improved I/O, caching, and flexibility.

  • You can freely shrink, grow, and FSTRIM your sparse image after migration.

  • A sparse image can be created at any size (even 1TB) but only consumes real storage as data is written - an efficient storage method for your Linux environment.

Seamless Desktop Experience

πŸ“Έ Desktop Screenshots (click to expand)

Ubuntu Chroot desktop landscape
Landscape mode

Ubuntu Chroot desktop portrait
Portrait mode

  • A complete Linux desktop experience on Android, capable of running GUI applications smoothly.[4]

Forward Chroot Traffic to Any Network Interface

  • Native WiFi hotspot functionality supporting both 2.4GHz and 5GHz bands. Automatically configures hostapd and DHCP services within the chroot environment for instant localhost sharing.
  • If the Native WiFi hotspot didn't work for you, you still have a separated menu to forward all the chroot traffic to any desired network interface. (e.g., USB Tethering/WiFi Hotspot created using Android userspace)

πŸ’‘ Example:

Use the GUI running on your phone and project it to another large screen with near-zero latency.

Incremental OTA Updates

  • Version-tracked incremental updates preserve user data and configurations across upgrades, eliminating the need for full reinstallation.

Backup and Restore

  • Back up your chroot environment to a compressed archive and restore it later, or transfer it to another device.

Post-Exec Scripts and "Run on Boot"

  • Define scripts to run automatically when the chroot boots.

πŸ’‘ Example:

Enable "Run on boot" and reboot your phone - the chroot will automatically start (even while locked), executing your post-exec script so you can host bots, SSH, or background services effortlessly.

Modern WebUI

  • Access and manage your chroot environment from KernelSU/APatch in-built WebUI.
WebUI screenshots
WebUI screenshot 1 WebUI screenshot 2 WebUI screenshot 3
WebUI screenshot 4 WebUI screenshot 5 WebUI screenshot 6

πŸš€ Installation

  1. Download the latest release from GitHub releases
  2. Flash the ZIP file using APatch/KernelSU managers
  3. Reboot your device

πŸ§‘β€πŸ’» Get Started

  1. Access the chroot control panel using APatch/KernelSU's built-in WebUI
  2. On the first installation, you have to set up your user account to access GUI functionality (VNC/RDP):
    • Start the chroot from the WebUI
    • Copy the login command
    • Paste it in Termux and complete the user account setup
    • Return to the WebUI and click "Restart" to apply changes
  3. You can now log in as the created user via:
    • CLI: Copy the login command and paste it in Termux or any other terminal emulator, including ADB Shell
    • GUI (VNC): Use the AVNC Android app (recommended for best performance)
    • GUI (RDP): Uncomment the # start_xrdp line in the Post-exec Script from the WebUI and restart the chroot

Note: There is currently no perfect RDP app for Android. Please create an issue if you find a better option.

πŸ’» Access the GUI

Once you've set up your user account following the Get Started section, the XFCE Desktop Environment will automatically start when you start the chroot from the WebUI - no need to type anything in the terminal !

The default method to access the GUI is using the VNC protocol with a VNC viewer application.

Recommended VNC Clients:

Local Access (Same Device)

Connection Settings for AVNC (Android):

  • Host: localhost
  • Port: 5901
  • Username: Your chroot user account username
  • Password: Your chroot user account password

Remote Access (External Device)

To access the GUI from a different device (e.g., a computer or tablet), you need to forward the chroot traffic to a network interface. There are two methods available:

Method 1: Built-in Hotspot

This method creates a WiFi hotspot directly from the chroot environment:

  1. Open the WebUI and navigate to the Hotspot Configuration option
  2. Configure your hotspot settings (Upstream, SSID, password, band, channel)
  3. Click Start Hotspot
  4. Connect your external device to the created hotspot
  5. Install a VNC client on the external device
  6. Use the IP address and port displayed in the console log along with your login credentials to connect

Method 2: USB Tethering (Fastest)

If the built-in hotspot doesn't work, or you need the lowest latency experience, you can use Android's USB Tethering feature:

  1. Open the WebUI and click the Refresh button
  2. Navigate to Forward Chroot Traffic and note the currently available network interfaces
  3. Connect your phone to the target device using a USB cable
  4. Enable USB Tethering on your Android device
  5. Return to the WebUI, click Refresh again, and navigate to Forward Chroot Traffic
  6. You should now see a new network interface that wasn't present before
  7. Select the new network interface and click Start Forwarding
  8. Use the IP address and port displayed in the console log along with your login credentials to connect

Tip

The IP address will be displayed in the WebUI console after starting the hotspot or forwarding.

Look for messages like Gateway IP to determine the value for Host required for the VNC client. For VNC, the port is always 5901.

Advanced: RDP Access

For advanced users who prefer RDP over VNC:

  1. Open the WebUI and navigate to Options β†’ Post-exec Script
  2. Remove the comment (#) from the start_xrdp line
  3. Restart the chroot from the WebUI
  4. Use an RDP client to connect using the same connection method as VNC (hotspot or USB tethering)

Note: There is currently no perfect RDP app for Android. VNC is recommended for the best experience.

πŸ§ͺ Experimental Features

Sparse Image Mode Installation

  • Edit the experimental.conf file before installation:
    • Set SPARSE_IMAGE=true
    • Define the image size in GB using SPARSE_IMAGE_SIZE

Converting to Sparse Image

  • You can convert your existing directory-based installation to an isolated ext4 sparse image from the WebUI under Experimental Features.

Downloading Firmware

  • If you want to download and decompress firmware files (useful for installing WIFI firmware without installing random Magisk modules from the internet), run the following command inside the chroot:

    sudo download-firmware

    This script will install the linux-firmware package, decompress all .zst firmware archives, and update symlinks to point to the decompressed files. The script creates a marker file to prevent re-running, so it's safe to execute multiple times.

  • After downloading the firmware, restart the chroot from the WebUI to apply the changes.

πŸ“‹ To-Do

The following features are currently not planned for implementation by the maintainer, but Pull Requests are always welcome if you figure out a way to implement them:

  • Audio forwarding in RDP
  • Termux-independent GPU acceleration

πŸ› Known issues

  1. Snap and Flatpak support

    • Snap and Flatpak are not native applications like those we install from .deb, .AppImage, or APT. They are containerized applications running in an isolated environment without any privileged access.

    • To create those isolated, containerized applications, your Android kernel must have support for various filesystems and drivers, as well as kernel patches to enable unprivileged user namespaces.

    • Even if you somehow compiled a custom kernel with all the required features enabled, the functionality is not guaranteed because we are creating an isolated environment within an already isolated environment.

    • Related issue: #1

  2. Error: sh: <stdin>[5]: /system/bin/su: No such file or directory in KernelSU LKM mode/Kernels with KernelSU KProbe Hooks

    • This is a known limitation in KernelSU when using LKM mode or GKI kernels with KProbe hooks or non-GKI Kernels without proper 32-bit support hooks.
    • This occurs because official KernelSU dropped support for 32-bit applications starting from versions above v0.9.2, and all KernelSU forks have inherited this limitation.
    • This causes all 32-bit applications to lose their ability to detect root, including ADB shell on devices with dual ABI support, Nethunter terminal, Root explorer, etc.
    • The only fix for this issue is to use a proper kernel with KernelSU manual hooks that support 32-bit applications, instead of using LKM mode or GKI kernels with KProbe hooks.
    • This error does not originate from this project; it's coming from KernelSU's side.
    • More info: telegram, Github issue created by me in 2024, Another similar issue

πŸ›  Kernel Requirements

These configurations are optional, as 80% are enabled in Android by default. However, to ensure everything works perfectly and achieve maximum potential from this project, these kernel configs should be enabled.

01. Core Namespace Support (Required for Isolation)

CONFIG_NAMESPACES=y
CONFIG_PID_NS=y
CONFIG_UTS_NS=y
CONFIG_MNT_NS=y
CONFIG_IPC_NS=y

02. Essential Filesystems for Hardware Access

CONFIG_DEVTMPFS=y
CONFIG_PROC_FS=y
CONFIG_SYSFS=y

03. Running x86_64 Binaries Natively

CONFIG_BINFMT_MISC=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_BINFMT_ELF=y

04. GUI Applications Support

# IPC mechanisms (required by many apps and daemons)
# KDiskMark and Brave Browser will fail without these
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_PROC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y

05. Docker Support in Chroot

CONFIG_CGROUPS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_MEMCG=y
Complete Kernel Configuration (click to expand)
# Ubuntu Chroot Kernel Configuration
# Copyright (C) 2025 ravindu644 <droidcasts@protonmail.com>
# Note: A custom kernel is not required, but most features
# will be limited without these configurations.

# CRITICAL: Essential for basic chroot functionality

# Core namespace support (required for isolation)
CONFIG_NAMESPACES=y
CONFIG_PID_NS=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y

# Essential filesystems
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
CONFIG_DEVTMPFS=y
CONFIG_TMPFS=y
CONFIG_EXT4_FS=y

# QEMU support
CONFIG_BINFMT_MISC=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_BINFMT_ELF=y

# Terminal support (required for login)
CONFIG_UNIX98_PTYS=y
CONFIG_TTY=y
CONFIG_DEVPTS_FS=y

# Basic networking
CONFIG_NET=y
CONFIG_INET=y
CONFIG_UNIX=y

# Threading support
CONFIG_FUTEX=y

# File operations
CONFIG_FILE_LOCKING=y

# IMPORTANT: Common functionality requirements

# IPC mechanisms (required by many apps and daemons)
# KDiskMark and Brave Browser will fail without these
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y

# Device management
CONFIG_DEVTMPFS_MOUNT=y

# Extended filesystem features
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y

# Control groups (essential for Docker)
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_MEMCG=y

# Event handling
CONFIG_EPOLL=y
CONFIG_EVENTFD=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y

# File monitoring
CONFIG_INOTIFY_USER=y

# Security
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y

# Networking features
CONFIG_IPV6=y
CONFIG_PACKET=y

# Legacy PTY (for compatibility)
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256

# OPTIONAL: Advanced features and specific use cases

# Advanced cgroup controllers
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_MEMCG_SWAP=y

# Overlay filesystem (for Docker-like functionality)
CONFIG_OVERLAY_FS=y

# FUSE (for userspace filesystems like sshfs, AppImage)
CONFIG_FUSE_FS=y

# Firmware loading
CONFIG_FW_LOADER=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_COMPRESS=y

# Loop devices (for mounting disk images)
CONFIG_BLK_DEV_LOOP=y

# Async I/O (for database servers and high-performance apps)
CONFIG_AIO=y

# System control interface
CONFIG_PROC_SYSCTL=y
CONFIG_SYSVIPC_SYSCTL=y

🐳 Running Docker inside Chroot

Tip

Docker is already installed and configured by default, so you don't need to do anything to install it.

The quick way to verify if you can run Docker containers is to check if the "Devices Cgroups" are mounted.

  • If you see these logs in the console, then your device has minimal Docker support:

    [INFO] Setting up minimal cgroups for Docker...
    [INFO] Cgroup devices mounted successfully.
    
  • Otherwise, there's no way to run Docker inside the phone unless you compile a custom kernel.

Next, verify if your /data partition is ext4.

  • If it is f2fs, you MUST use the migrate feature from "Options -> Experimental Features -> Migrate to Sparse Image" so Docker can properly wire up OverlayFS on top of the ext4 mounted rootfs.

After verifying your kernel supports Devices Cgroups and resolving any ext4 filesystem issues, you need to start the Docker daemon using the command below.

  • Run this inside the chroot terminal: sudo dockerd

  • If the Docker daemon started successfully, it should show something like this:

    INFO[2025-12-08T16:59:04.981797971Z] Completed buildkit initialization
    INFO[2025-12-08T16:59:05.016738894Z] Daemon has completed initialization
    INFO[2025-12-08T16:59:05.017061663Z] API listen on /var/run/docker.sock
    
  • If it failed, that means your kernel does not support running Docker even though the "Devices Cgroups" are available.

  • In that case, you need to compile a custom kernel with all the required Docker configurations enabled.

To verify Docker is fully functional, you can run this command in a new terminal: docker run -it hello-world

To run the Docker daemon whenever the chroot starts, you can modify the "Post-exec Script" from the WebUI by going into the "Options" menu.

  • To enable it, remove the comment from the beginning of the dockerd > /dev/null 2>&1 & line, like this:

    Docker Daemon
    Uncomment dockerd in post-exec

Note

Networking inside Docker

For maximum compatibility, we ship the pre-built rootfs with Docker networking features disabled and force configured to use NAT instead of creating Docker's own docker0 network interface.

You can modify this behavior by editing /etc/docker/daemon.json if needed.

Additionally, every action you run with the docker run command will automatically use docker run --net=host via the docker function in this script, which tells Docker to use the host network for all networking tasks, including internet access.

Important

Even if you have a custom kernel with all the necessary configurations enabled, Docker still won't be able to create the docker0 interface without flushing the existing iptables filter chains.

To do this, first, you need to use iptables-legacy and ip6tables-legacy.

Run these commands inside Ubuntu:

update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

Then, run these commands to fix the Docker iptables issue:

iptables -t filter -F
ip6tables -t filter -F

Now, you can edit /etc/docker/daemon.json to use iptables and run dockerd to see if it works. Keep in mind this will only work if your kernel has the necessary kernel configurations enabled.

πŸ™ Credits

πŸ“œ License

This project is released under the MIT License. You are free to use, modify, and distribute it as long as the original copyright notice and license terms are preserved.