Scope and prerequisites#
Commands and output use generic examples. Kernel, image, package, and service versions affect specific behavior; check the documentation for the versions you use as you read.
Back up Android data and stop the relevant sessions before changing containers, images, mounts, or firewall rules; examples involving deletion or forced shutdown may cause data loss. Manage NixOS system and user environment configuration through Nix. The generic Linux sections covering apt/pacman, direct writes to /etc, and pip installation do not apply to a NixOS host. The build, test, and switch stages of a rebuild are separate from functional verification after startup.
This article covers checking environment dependencies, comparing installation across distributions, the image-download process with
waydroid init, the container’s first startup, and end-to-end verification.
Environment requirements#
Waydroid is neither an emulator nor a virtual machine. It uses Linux namespace isolation and binder passthrough to run Android userspace directly on the host kernel. This brings extremely low overhead but also imposes firm requirements on the host environment. Assess requirements by component: container startup, the graphical session, and application compatibility are separate levels of acceptance testing.
A Wayland session: A firm requirement
Waydroid must run in a Wayland session; it does not natively support X11. This is because the Android graphics stack renders directly to the host compositor through the wayland-client protocol, bypassing the X11 intermediary.
# 检查当前图形会话协议
echo $XDG_SESSION_TYPE
# 期望输出: wayland
# 如果输出 x11,检查当前登录管理器是否支持 Wayland
loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p TypeWhat can X11 users do? If your desktop environment still runs on X11, such as certain older GNOME versions, Xfce, or MATE, there are two options:
Switch to a Wayland session: In the login manager (SDDM/GDM/LightDM), select a session option with a "Wayland" suffix. This is the recommended approach.
Use a nested Wayland compositor: Start a nested Wayland compositor inside X11, then run Waydroid within it. Common tools include:
cage— A minimal kiosk-style Wayland compositor that supports only a single fullscreen applicationweston— A full-featured reference compositor with support for nested mode# 使用 weston 嵌套模式启动一个最小 Wayland 环境 # 终端 A: 启动 weston weston --width=1280 --height=720 & # 终端 B: 在 weston 内启动 Waydroid WAYLAND_DISPLAY=wayland-1 waydroid show-full-uiA nested compositor adds performance overhead and should be used only as a temporary transition.
CPU instruction-set requirements
On x86_64, Waydroid’s Android system images are built for x86_64, but some key components, such as the libhoudini ARM translation engine, depend on specific SIMD instruction sets.
# 检查必需指令集
grep -o -E 'ssse3|sse4_1|sse4_2' /proc/cpuinfo | sort -u
# 转译组件可能要求其中部分指令,不是所有 Waydroid 场景的统一要求:
# ssse3
# sse4_1
# sse4_2
# 一行版本:所有指令都存在则返回 3
grep -o -E 'ssse3|sse4_1|sse4_2' /proc/cpuinfo | sort -u | wc -l
# 期望输出: 3Kernel modules
Check the Binder, shared-memory, PSI, and networking support required by the current version; not every name corresponds to a loadable kernel module.
binder / rust_binder
binder is Android’s core IPC mechanism. Binder has a C implementation and a newer Rust implementation; module names and availability depend on the specific kernel/distribution. You cannot infer a replacement relationship from version numbers such as 5.7 or 6.7. The common module name for the C implementation is binder_linux.
# 检查 binder 或 rust_binder 模块是否可用
modprobe --dry-run binder_linux 2>&1 || modprobe --dry-run rust_binder 2>&1
# 如果上述命令报 "modprobe: FATAL: Module binder not found"
# 说明内核未编译 binder 支持,需重新编译内核或更换支持 Android 的内核
# 检查模块是否已加载
lsmod | grep -E 'binder'binder vs rust_binder
Module Kernel version Configuration option Characteristics binder_linuxProvided by the specific kernel CONFIG_ANDROID_BINDER_IPCC implementation rust_binderCheck the specific distribution and version Depends on kernel configuration Rust implementation Kernels in modern distributions (Ubuntu 22.04+, Fedora 37+, and current Arch) usually include one of the two. NixOS requires manual configuration; see 03 In-depth NixOS integration.
PSI (Pressure Stall Information)
PSI is the kernel’s resource-pressure monitoring infrastructure. Waydroid’s lxc-monitord depends on PSI to detect resource pressure in the container. Check CONFIG_PSI and /proc/pressure/ first; when PSI is disabled by default, enable it with psi=1. This involves both the build configuration and boot policy; it is not a dependency of the Binder protocol itself.
# 检查 PSI 是否已启用
cat /proc/pressure/cpu
# 如果文件存在且有输出,说明 PSI 已启用
# 如果报 "No such file or directory",说明未启用
# 检查内核启动参数中是否有 psi=1
cat /proc/cmdline | grep -o 'psi=1'If psi=1 is not set, modify the bootloader configuration:
| Bootloader | Configuration file | Method |
|---|---|---|
| GRUB | /etc/default/grub |
On the GRUB_CMDLINE_LINUX line, append psi=1, then run sudo update-grub or sudo grub-mkconfig -o /boot/grub/grub.cfg |
| systemd-boot | /boot/loader/entries/*.conf |
Append to the options line: psi=1 |
| NixOS | configuration.nix |
boot.kernelParams = ["psi=1"]; |
A missing psi=1 is the most common cause of installation failure If
waydroid container startis followed bylxc-monitord[xxx]: Failed to open /proc/pressure/cpuor the container exits immediately, inspect the actual failure logs and check/proc/pressure/. There is no statistical evidence for assigning a fixed probability to this cause.
IPv6 must be enabled
Inside the Waydroid container, some system services rely on IPv6 for communication, even if the host does not use IPv6 to reach external networks.
# 检查 IPv6 是否启用
sysctl net.ipv6.conf.all.disable_ipv6
# 期望输出: net.ipv6.conf.all.disable_ipv6 = 0
# 如果为 1,临时启用
sudo sysctl net.ipv6.conf.all.disable_ipv6=0
# 永久启用:确保 /etc/sysctl.conf 或 /etc/sysctl.d/ 中没有
# net.ipv6.conf.all.disable_ipv6 = 1GPU recommendations
Waydroid’s GPU acceleration support varies by vendor and directly affects graphics performance in Android applications.
| GPU vendor | Support level | Driver | Notes |
|---|---|---|---|
| Intel | Commonly supported path | i915/xe + Mesa | Verify the image, driver, and actual rendering |
| AMD | Commonly supported path | amdgpu + Mesa | No guarantee that all configurations work from a fixed version onward |
| NVIDIA (proprietary driver) | Filtered out by the upstream selector | nvidia | The software-rendering approach in the official documentation can be configured explicitly |
| NVIDIA (Nouveau) | Requires hands-on verification | nouveau + Mesa | The current mapping includes nouveau; compatibility with a specific GPU/application is not guaranteed |
| Virtual machine (VM) | Partial | virtio-gpu / vmwgfx | Depends on host GPU passthrough or virtualized GPU configuration |
The reality of NVIDIA proprietary drivers Modern NVIDIA drivers support GBM. The Waydroid version examined still filters out the nvidia driver because host GBM support alone does not guarantee complete Android graphics integration. When no usable hardware node exists, the software path also requires checking the image and configuration. The following are only common workload observations, not performance guarantees:
- Lightweight applications such as WeChat and Douyin are reasonably usable
- 3D games are almost unplayable
- Video playback may stutter noticeably
NVIDIA users can try the experimental approaches in 04 GPU and hardware acceleration.
LXC version requirements
Waydroid requires LXC >= 4.0; LXC >= 5.0 is recommended.
# 检查 LXC 版本
lxc-info --version
# 期望输出: 5.0.x 或 4.0.x
# 同时检查 Python LXC 绑定
python3 -c "import lxc; print(lxc.__version__)"Installation across distributions#
Waydroid installation differs significantly across Linux distributions, from a single-step install through a community repository to manual kernel-module configuration. The following table gives the complete installation paths for major distributions.
| Aspect | Ubuntu / Debian | Arch Linux | NixOS | Fedora |
|---|---|---|---|---|
| Package name | waydroid |
waydroid |
pkgs.waydroid-nftables (recommended) |
waydroid |
| Installation source | Add the apt repository using the official curl script | extra repository |
nixpkgs virtualisation.waydroid |
Official Fedora repositories (older tutorials used COPR) |
| Installation command | apt install waydroid |
pacman -S waydroid |
Declarative enable = true |
dnf copr enable + dnf install |
| Initialization command | sudo waydroid init |
sudo waydroid init |
sudo waydroid init |
sudo waydroid init |
| Container service name | waydroid-container |
waydroid-container |
waydroid-container |
waydroid-container |
| Kernel modules | binder included in the kernel | binder included in the kernel | Requires separate boot.kernelModules configuration |
binder included in the kernel |
| Maintainer | Official (Waydroid team) | Official Arch repositories | nixpkgs maintainers | aleasto (COPR) |
Ubuntu / Debian
On Ubuntu and Debian, prefer the official apt repository to receive the latest version and updates.
# 1. 添加官方 apt 仓库并安装 GPG 密钥(需要 curl)
# 该脚本自动检测发行版版本并配置对应的 apt source
curl -s https://repo.waydro.id | sudo bash
# 2. 安装 Waydroid 主程序
sudo apt install waydroid
# 3. 可选:安装 Google Play Services 支持
# GAPPS 通过 waydroid init -s GAPPS 选择,不假定有 waydroid-gapps 包| File | Path |
|---|---|
| apt source list | /etc/apt/sources.list.d/waydroid.list |
| GPG key | /usr/share/keyrings/waydroid.gpg |
| Main binary | /usr/bin/waydroid |
| systemd unit | /usr/lib/systemd/system/waydroid-container.service |
Arch Linux
Waydroid is in Arch’s extra repository; no additional repository is needed.
# 安装 Waydroid(含所有运行时依赖)
sudo pacman -S waydroid
# 内核模块:Arch 的 linux/linux-lts 内核默认包含 binder
# 确认 binder 已加载:
lsmod | grep binder
# 如果需要额外工具
yay -S waydroid-image # 第三方来源:先确认包仍存在; 预下载的镜像(可选,跳过 init 下载)
yay -S waydroid-script-git # 第三方来源:先确认包仍存在; 额外辅助脚本(可选)Arch bwrap permission issues On some Arch installations,
bubblewrap(bwrap) may fail because of kernel restrictions onunprivileged user namespaces:# 检查是否受限 sysctl kernel.unprivileged_userns_clone # 如果为 0,需要设为 1: sudo sysctl kernel.unprivileged_userns_clone=1
NixOS
NixOS integrates Waydroid through declarative configuration, making it the most distinctive approach among these distributions. Key points:
# /etc/nixos/configuration.nix 或 flake 配置
{
virtualisation.waydroid = {
enable = true;
# package = pkgs.waydroid-nftables; # 默认随 networking.nftables.enable 选择,不固定
};
# 26.05 模块已经配置 psi=1 并检查 Binder/BinderFS/MEMFD
# 自定义内核另行检查实际支持,不盲目重复指定模块
}Apply the configuration:
sudo nixos-rebuild switch
sudo waydroid initThe NixOS section is covered fully in article 03 Waydroid integration on NixOS involves module options (
virtualisation.waydroid.*), nftables network rules, the waydroid-helper tool, and the boundary between imperative and declarative operations. The above is only a minimal configuration; see 03 In-depth NixOS integration for the full explanation.
Fedora
The current official Fedora installation instructions use the distribution repositories; the older COPR approach is historical reference only.
# 启用 COPR 仓库
# 当前常规安装不需要启用旧 COPR
# 安装 Waydroid
sudo dnf install waydroid
# SELinux 可能需要调整(如遇权限问题)
# 先查看 SELinux AVC 日志并修正标签/策略,不默认关闭 SELinux
# 永久:需编写 SELinux 策略模块(超出本文范围)waydroid init in detail#
waydroid init is the core step in the installation process. It downloads Android system images, verifies their integrity, and creates the filesystem structure needed by the container on the host.
Basic usage
# 最简初始化:下载标准 LineageOS 镜像(无 Google 服务)
sudo waydroid init
# 带 Google Play Services 的初始化
sudo waydroid init -s GAPPS
# 强制重新下载(即使已有镜像)
sudo waydroid init -f # 强制初始化;先核对当前状态与备份
# 指定下载渠道
sudo waydroid init -c https://ota.waydro.id/system # 默认渠道| Argument | Full name | Purpose |
|---|---|---|
| None | — | Downloads the x86_64 LineageOS system image (Android 13) without Google services |
-s GAPPS |
--system_type GAPPS |
Downloads the GAPPS variant with Google Play Services, Play Store, Gboard, and other components preinstalled |
-f |
--force |
Forces initialization/handles custom images; does not guarantee a fresh download every time and does not automatically mean user data is erased |
-c URL |
--system_channel URL |
Specifies the system OTA URL; use -v separately for the vendor channel |
Image download details
waydroid init downloads two core image files from sourceforge.net, totaling about 700~1000 MB depending on whether you choose the GAPPS variant.
| File | Size (standard) | Size (GAPPS) | Contents |
|---|---|---|---|
system.img |
~500 MB | ~680 MB | Android system partition: LineageOS mainline + additional components in the GAPPS variant (Play Services, Play Store, Gboard, WebView, etc.) |
vendor.img |
~300 MB | ~300 MB | Hardware abstraction layer (HAL): GPU drivers, audio HAL, sensor shims, Wayland gralloc |
After download, the images are stored in the /var/lib/waydroid/ directory:
# 查看已下载的镜像
ls -lh /var/lib/waydroid/images/
# 期望输出:
# -rw-r--r-- 1 root root xxxM ... system.img
# -rw-r--r-- 1 root root xxxM ... vendor.imgUnderlying process
When waydroid init runs, it performs the following internal steps:
graph TD
A["waydroid init 启动"] --> B{本地已有镜像?}
B -->|否,或指定 -f| C["从 SourceForge 下载<br/>system.img + vendor.img"]
B -->|是| D[跳过下载]
C --> E["校验 SHA256 哈希<br/>确保镜像完整性"]
D --> E
E --> F["创建 /var/lib/waydroid/ 目录树"]
F --> G["挂载 system.img<br/>按实际镜像格式与 overlay 布局"]
G --> H["创建 /var/lib/waydroid/waydroid_base.prop"]
H --> I["写入 build.prop 属性<br/>(ro.waydroid.version 等)"]
I --> J["生成 LXC 配置文件<br/>/var/lib/waydroid/lxc/waydroid/config"]
J --> K["init 完成"]Filesystem structure Waydroid uses overlayfs to combine the read-only system.img with a writable data layer:
- The system image is usually at
/var/lib/waydroid/images/system.img; it must first be mounted as a directory before it can serve as an overlay lower layer- Android
/datauses the user data directory; it is not a general-purpose upperdir for the system/vendor overlay- This means each OTA upgrade of the system image leaves user data and installed applications unaffected
Image storage locations at a glance
| Path | Contents | Permissions |
|---|---|---|
/var/lib/waydroid/images/system.img |
LineageOS system partition image | root:root (644) |
/var/lib/waydroid/images/vendor.img |
Hardware abstraction layer image | root:root (644) |
/var/lib/waydroid/waydroid_base.prop |
Android system property baseline | root:root (644) |
/var/lib/waydroid/lxc/waydroid/config |
LXC container runtime configuration | root:root (644) |
~/.local/share/waydroid/data/ |
User data and installed APKs | Current user |
~/.local/share/applications/waydroid.*.desktop |
Desktop launcher entries for Android applications | Current user |
First startup and verification#
After the images finish downloading, start Waydroid and perform end-to-end verification in the following order.
Start the container service
Waydroid operates in two layers: the container daemon (a systemd service that manages the LXC container lifecycle) and the Android session (userspace, managing the Android runtime).
# 启动容器服务并设为开机自启
sudo systemctl enable --now waydroid-container
# 检查服务状态
sudo systemctl status waydroid-container
# 期望输出关键行:
# Active: active (running) since ...
# CGroup: /system.slice/waydroid-container.service
# ├─ /usr/bin/python3 /usr/bin/waydroid -w container start
# └─ /usr/bin/lxc-start -F -n waydroid -- /initThe role of the container service
waydroid-container.serviceruns with root privileges and is responsible for:
- Starting
lxc-startto boot the Androidinitprocess- Managing binder device nodes (
/dev/binder)- Setting up namespace isolation and cgroup resource limits
- Mounting the Android system partition overlay
Android userspace operation is controlled by a regular user through the session bus and does not involve root privileges.
Start the Android session
Once the container is running, Android still needs to start its session manager, equivalent to an Android "user login".
# 启动 Waydroid 会话
waydroid session start
# 等待日志中出现 "Android with user 0 is ready"
# 这表示 Android 服务框架(system_server, SurfaceFlinger 等)全部就绪While the session is starting, use another terminal to monitor it in real time:
# 跟踪 Waydroid 日志(容器 + 会话)
waydroid log # -c 是清除日志,不是跟踪标志
# 或者只看会话层日志
journalctl -u waydroid-container -bOpen the Android desktop
Once the session is ready, launch the full Android desktop environment:
waydroid show-full-uiThis opens a window showing the complete LineageOS desktop, including the launcher, status bar, and navigation bar, just like a native Android device.
Health check commands
| Command | Purpose | Expected result |
|---|---|---|
waydroid status |
Check container and session status | Session: RUNNING + Container: RUNNING |
waydroid app list |
List installed Android applications | Shows at least system applications such as com.android.settings and com.android.launcher3 |
sudo waydroid shell |
Enter the Android container shell | Displays a waydroid:/ # prompt where you can run Android commands such as getprop and pm list packages |
waydroid log |
View runtime logs | Outputs runtime information line by line for subsystems such as Wayland/EGL/binder |
Specific usage examples:
# 1. 状态检查
$ waydroid status
Session: RUNNING
Container: RUNNING
Vendor type: MAINLINE
Session user: 0 (0)
Wayland display: wayland-1
# 2. 列出已安装应用
$ waydroid app list
Name: Settings, package: com.android.settings
Name: Trebuchet, package: com.android.launcher3
...
# 3. 进入容器 shell
$ sudo waydroid shell
waydroid:/ # getprop ro.build.version.release
13
waydroid:/ # pm list packages | head -5
package:com.android.settings
...
waydroid:/ # exitApplication management quick reference
# 通过包名启动应用
waydroid app launch com.android.settings # 打开设置
waydroid app launch com.android.launcher3 # 打开启动器
# 安装 APK 文件
waydroid app install /path/to/application.apk # 安装单个 APK
# 通过 Google Play 安装(GAPPS 变体)
waydroid app launch com.android.vending # 启动 Play Store
# 然后在 Play Store 中正常搜索安装
# 为 Android 应用创建桌面快捷方式
# 安装 APK 后,waydroid 会自动在 ~/.local/share/applications/ 下
# 生成 waydroid.<package>.desktop 文件
ls ~/.local/share/applications/waydroid.*.desktopSet Android system properties
# 查看当前属性
waydroid prop get persist.waydroid.width
waydroid prop get persist.waydroid.height
# 设置属性(影响 Android 设备行为)
waydroid prop set persist.waydroid.width 720 # 设置窗口宽度
waydroid prop set persist.waydroid.height 1280 # 设置窗口高度
waydroid prop set persist.waydroid.fake_wifi "com.example.app" # 伪装 Wi-Fi 连接
waydroid prop set persist.waydroid.multi_windows true # 启用多窗口模式
# 部分属性修改后需重启会话才能生效
waydroid session stop
waydroid session startStop Waydroid
# 先停止 Android 会话
waydroid session stop
# 再停止容器服务
sudo systemctl stop waydroid-container
# 完全清理(停止会话 + 停止容器 + 释放资源)
waydroid session stop && sudo systemctl stop waydroid-containerShutdown order Stop the session before stopping the container. If you stop the container while the session is still running, the D-Bus session manager repeatedly attempts to reconnect, flooding the logs and causing abnormal resource usage.
Startup troubleshooting quick reference
| Symptom | Possible cause | Check command |
|---|---|---|
container is not running |
binder module not loaded | lsmod | grep binder |
| Container exits immediately after startup | psi=1 not set |
cat /proc/cmdline | grep psi=1 |
Failed to connect to wayland |
X11 session or invalid WAYLAND_DISPLAY | echo $XDG_SESSION_TYPE |
Wayland connection failed |
Wayland compositor refuses the connection | echo $WAYLAND_DISPLAY + confirm that the compositor is running |
Failed to open /dev/binder |
Insufficient permissions on the binder device | ls -la /dev/binder* |
| Network unavailable (no IPv4) | waydroid0 bridge not created | ip link show waydroid0 |
| Play Protect certification fails | Device ID not registered for the GAPPS variant | See 07 Troubleshooting |
| GPU rendering fails; black screen | NVIDIA proprietary driver | waydroid log | grep -i gpu |
Debug mode For startup problems, waydroid provides detailed debug output:
# 前台运行容器(日志直接输出到终端) sudo waydroid --details-to-stdout container start # 前台运行会话 waydroid --details-to-stdout session start # 结合 journalctl 查看系统日志 sudo journalctl -u waydroid-container -f
Summary#
After completing the steps, verify each of the following:
- Wayland session environment confirmed
- All required kernel modules loaded (binder/rust_binder, PSI, IPv6)
- Waydroid installed through the distribution’s native package manager
- Android system images downloaded and mounted through
waydroid init waydroid-container.servicestarts automatically at boot- Android session starts normally and the desktop UI is displayed
You can now:
- Launch system applications with
waydroid app launch - Install third-party APKs with
waydroid app install - Run most applications on the Android desktop with near-native performance
Next: 03 In-depth NixOS integration explains fully automated Waydroid deployment on NixOS through declarative configuration, including nftables network rules and kernel-module management.
Verification sources#
Official Waydroid installation instructions.
Official Waydroid command documentation.
References & further reading
- Official Waydroid installation instructions ↗
- Official Waydroid command documentation ↗
- Waydroid upstream source ↗
- NixOS 26.05 module ↗
- Official NVIDIA GBM documentation ↗
Adapted from technical notes. Examples use generic names.
Continue along a reading path
Waydroid
- 01Waydroid architecture: LXC, Binder, and session bridging
- 02Waydroid installation and basic setup
- 03Waydroid integration on NixOS
- 04Waydroid GPU detection and hardware acceleration
- 05Waydroid bridges, NAT, and security boundaries
- 06Waydroid properties, multi-window mode, and ARM translation
- 07Waydroid troubleshooting and FAQ
- 08Waydroid tips: windows, translation, and shared directories