Android Docker Host
该方案在已 root 的 arm64 Android 设备上运行 Docker Engine。它并不代表“通用 Android 支持”;内核、mount、存储和网络条件都需要逐项确认。
它比普通 Linux 服务器需要更多主机侧配置。不要只检查 Docker CLI,还要确认容器启动、外网访问、published port 和持久化。
从头到尾的完整步骤请参阅“Android 完整指南”。 本页用于快速判断设备属于哪一种情况。
结构
Android arm64 device
├─ Android OS / vendor kernel
│ ├─ root (KernelSU / Magisk 等)
│ ├─ 面向 container 的 kernel config
│ ├─ Android netd / policy routing
│ └─ SELinux
├─ Termux
│ ├─ BusyBox / SSH / tmux
│ └─ 获取 Ubuntu rootfs
├─ Ubuntu rootfs (real chroot)
│ ├─ Docker Engine / containerd / runc
│ └─ Compose
├─ ext4 loop image → /var/lib/docker
└─ containers
└─ vyline
optional:
Portainer / Tailscale / Cloudflare Tunnel 等proot-distro 可用于获取 rootfs,但 Docker Engine 本身应在 real chroot 中运行。Portainer 和远程访问工具都不是 Vyline 的必需组件。
Preflight
uname -m
id
getenforce
cat /proc/cgroups
mount | grep -E 'cgroup|cgroup2'
ls -l /dev/block/loop* 2>/dev/null除 arm64 和 root 外,还要确认 Docker 所需的 namespaces、cgroups、seccomp、OverlayFS、veth/bridge、netfilter、loop/ext4 等能力。详情见 Android 内核。
| 现象 | 下一步 |
|---|---|
| dockerd 本身无法启动 | 检查 内核、storage 和 cgroup |
hello-world 可以运行,但容器无法访问 Internet | 网络 |
可以访问 Internet,但 LAN 无法访问 :3000 | 检查 published-port 与 nft/legacy 数据包路径 |
| Docker 和网络都正常 | 继续配置 Vyline Compose |
Termux
pkg update -y
pkg install -y proot-distro busybox openssh tmux coreutils curl
termux-wake-lock
proot-distro install ubuntuUbuntu rootfs 的常见位置:
/data/data/com.termux/files/usr/var/lib/proot-distro/containers/ubuntu/rootfs
real chroot 的 mount
PREFIX=/data/data/com.termux/files/usr
ROOT="$PREFIX/var/lib/proot-distro/containers/ubuntu/rootfs"
BB="$PREFIX/bin/busybox"
su
$BB mount --bind "$ROOT" "$ROOT"
$BB mount --make-rslave "$ROOT"
$BB mount --rbind /dev "$ROOT/dev"
$BB mount --make-rslave "$ROOT/dev"
$BB mount -t proc proc "$ROOT/proc"
$BB mount --rbind /sys "$ROOT/sys"
$BB mount --make-rslave "$ROOT/sys"
$BB mount -t tmpfs -o mode=755,nosuid,nodev tmpfs "$ROOT/run"将 rootfs self-bind 为 mountpoint 并设为 rslave,是为了让 runc 的递归 mount 操作在部分 Android 配置上正常工作。否则可能出现 remount / ... invalid argument 一类错误。
只在需要时把 Docker data-root 放到 ext4
先测试 Android 当前文件系统上能否正常使用 overlay2。只有 F2FS、casefold 与 vendor kernel 等组合导致 EINVAL 的设备,才需要把 /var/lib/docker 放到 ext4 loop image。
stat -f -c '%T' /data
docker info 2>/dev/null | grep -E 'Storage Driver|Backing Filesystem'mkdir -p /data/local/docker-storage
truncate -s 64G /data/local/docker-storage/docker-ext4.img
/system/bin/mke2fs -t ext4 -F /data/local/docker-storage/docker-ext4.img
LOOP=$(/system/bin/losetup -f)
/system/bin/losetup "$LOOP" /data/local/docker-storage/docker-ext4.img
$BB mount -t ext4 -o rw,noatime "$LOOP" "$ROOT/var/lib/docker"
chroot 内的 Docker
{
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=cgroupfs"],
"log-driver": "local"
}rm -f /var/run/docker.pid
nohup dockerd >/var/log/dockerd.log 2>&1 </dev/null &
docker run --rm hello-world
docker run --rm alpine uname -m
docker run --rm alpine ping -c 1 1.1.1.1
网络是独立问题
即使 Docker 能运行,Android netd 的 policy routing 或 legacy/nft 不一致仍可能破坏容器访问 Internet、LAN 访问 published port 等路径。请按 Android 网络 的顺序排查。
Vyline Compose
services:
vyline:
image: ghcr.io/tqmane/vyline:latest
pull_policy: always
platform: linux/arm64
ports:
- "3000:3000"
volumes:
- /opt/vyline/data:/app/data
- /opt/vyline/storage:/app/storage
environment:
VYLINE_HOST: 0.0.0.0
PORT: 3000
VYLINE_DATA_DIR: /app/data
VYLINE_STORAGE_DIR: /app/storage
VYLINE_LAN_ACCESS: "false"
VYLINE_TRUST_REMOTE_OWNER: "false"
TZ: Asia/Tokyo
restart: unless-stopped因为镜像是 multi-arch,platform: linux/arm64 通常可以省略,只在需要显式指定时保留。先使用标准 healthcheck;只有在 Android chroot 中主机侧 HTTP 正常、但 healthcheck/exec 路径异常时才加入:
healthcheck:
disable: true即便如此,也要先通过 curl http://127.0.0.1:3000/healthz 确认 Vyline 本体正常。只有 docker exec 的 mount namespace 异常时,请参阅完整指南。