闲置安卓手机跑 Docker:termux-containers 免 Root 把旧手机变成小服务器

阅读时长:13分钟

抽屉里那台吃灰的旧手机,屏幕碎了、电池鼓了、系统卡成 PPT,但你舍不得扔——万一哪天有用呢?

现在它真有用武之地了。

一个 10 月 31 日刚上线的开源项目 termux-containers,让你可以在不 Root、不刷机、不跑虚拟机的前提下,用 Docker Compose 风格的 YAML 配置文件,在安卓手机里跑起 Nginx、Cloudflared、Aria2 这类服务。

听起来像是"把手机变成服务器"的又一个标题党?

我研究了一圈它的实现原理,发现这次真的不太一样。它没有伪造一个 Docker Engine,而是老老实实走 Termux + PRoot-Distro 的路子——不是"兼容 Docker",而是补上 Docker 最缺的那块拼图:声明式多容器编排。

TL;DR

  • termux-containers 基于 PRoot-Distro,无需 Root、无需 Docker 守护进程,用 YAML 管理多个 OCI 容器
  • 项目 2026-10-31 上线,GitHub 49 stars,作者仅用两个镜像(cloudflared、fast note sync、cli proxy api)做了验证
  • 它是"类 Docker Compose"而非"Docker 替代":无端口映射、无内核级隔离、强依赖 ARM64 镜像
  • 适合做低功耗常驻小服务(消息机器人、Webhook、下载工具),不适合跑重型应用
  • 折腾成本极低(一条命令安装),但要做好"后台被杀"和"镜像架构不兼容"的心理准备

它到底是个什么东西?

先给结论:termux-containers 不是一个容器运行时,而是一个配置管理器。

它自己不拉镜像、不跑容器、不管网络。真正干活的是 Termux 生态里的 PRoot-Distro——一个能在 Android 用户空间里跑 Linux 发行版的工具。termux-containers 做的事情,是给 PRoot-Distro 套上一层"类 Docker Compose"的壳:

services:
  web:
    image: nginxinc/nginx-unprivileged:stable-alpine
    enabled: true
    volumes:
      - type: directory
        source: ./data/web
        target: /usr/share/nginx/html
    environment:
      PORT: "8080"

写一个 YAML,跑一句 termux-containers apply,它就帮你把镜像拉下来、容器建起来、服务跑起来。改完配置再 apply 一次,它会 diff 出变化并重建对应容器。

整个技术栈是四层套娃:

层 组件 作用
1 Android 提供 Linux 内核(但应用跑在用户空间)
2 Termux 终端模拟器 + 包管理器 + Linux 用户空间
3 PRoot-Distro 用 PRoot 模拟 root,跑 OCI 镜像
4 OCI 镜像 真正干活的应用(Nginx / cloudflared 等)

关键点在第 3 层:PRoot 不是 Docker。它不靠内核的 namespace/cgroup 做隔离,而是用 ptrace 在用户空间里"伪造"出一个 root 环境。所以它能跑,但隔离性、性能、兼容性都跟真 Docker 有差距。

上手全流程:从装到跑起来

第一步:装 Termux

去 F-Droid 或 GitHub Releases 装 Termux(Play 商店那个版本已经很久没更新了)。装完打开,先把包管理源换成国内镜像(可选,但强烈建议):

termux-change-repo

然后装基础依赖:

pkg update && pkg install git

第二步:克隆项目并安装

git clone https://github.com/BHznJNs/termux-containers ~/termux-containers
cd ~/termux-containers
bash install.sh

安装脚本会干这几件事:

  1. 装 Python 3.10+(termux-containers 是 Python 写的)
  2. 装 PRoot-Distro 及其依赖
  3. 创建 termux-containers 命令入口
  4. 写一个默认的空 containers.yaml
  5. 配置 Bash Session 自启动(这样每次打开 Termux 都会自动恢复服务)

装完执行 termux-containers --help 确认命令可用。

第三步:写配置

nano ~/termux-containers/containers.yaml

官方示例是 Nginx。我建议第一次跑用 nginxinc/nginx-unprivileged:stable-alpine 这个镜像——它是专门为非 root 环境构建的,体积小(约 40MB), ARM64 支持完善,不会一上来就踩权限坑。

第四步:启动

termux-containers apply

它会读 YAML、拉镜像、建容器、启动服务。完成后:

termux-containers status

看到服务状态是 running 就说明成了。手机浏览器打开 http://127.0.0.1:8080,看到你写的 HTML 页面,那种感觉——一台拿在手里的手机,托管着一个网页——确实挺妙的。

常用命令

命令 作用
termux-containers apply [服务名] 应用配置:装镜像、启动、重启、停止被禁用的服务
termux-containers start [服务名] 启动已安装且启用的服务(不重新拉镜像)
termux-containers stop [服务名] 停止服务,保留容器文件系统和挂载数据
termux-containers status [服务名] 查看实际安装和运行状态
termux-containers -f <路径> apply 用指定配置文件,不局限于默认位置
bash uninstall.sh --yes 卸载工具和自启动入口,保留容器与数据

省略服务名表示处理全部配置服务。

它和真 Docker 差在哪?

这是本文最该讲清楚的部分。别指望它跑 Docker Hub 上所有镜像。

差异一:没有内核级隔离

Docker 靠 Linux 内核的 namespace 和 cgroup 做资源隔离。PRoot 是用户空间程序,用 ptrace 拦截系统调用、伪造 root 权限。这意味着:

  • 没有真正的进程隔离:容器里的进程和 Termux 共享同一个 PID namespace(虽然 PRoot 会做一层映射)
  • 没有资源限制:没有 --memory、--cpus 这类限制,一个失控容器能把手机搞卡
  • 没有安全边界:容器不是沙箱,跑可信镜像

差异二:没有端口映射

Docker 的 -p 8080:80 是内核级 NAT。PRoot 没这个能力,所以:

  • 容器监听的端口就是 Termux 监听的端口
  • 手机本地访问 127.0.0.1:8080 没问题
  • 局域网/公网访问需要额外手段(Cloudflare Tunnel 是最优解)

差异三:镜像架构强绑定 ARM64

Android 手机几乎都是 ARM64。Docker Hub 上很多镜像只提供 amd64,没 arm64。虽然 PRoot-Distro 号称能"拉取后构建镜像",但兼容性不保证。

作者自己在 V2EX 原帖里说测过三个镜像:cloudflared、fast note sync、cli proxy api,都能跑。但这是个 49 stars 的新项目,别拿它跑生产服务。

差异四:后台运行受 Android 摆布

Android 的 Doze 模式、后台限制、电池优化,全都会杀进程。作者提过"手机休眠或系统清理后台时,服务可能中断"。解决办法:

  1. 手机设置里把 Termux 加入"电池优化白名单"
  2. 保持 Termux 在前台(开个常驻通知)
  3. 或者接受"偶尔断"——反正它就是个玩具

我实算的账本:值不值得折腾?

成本侧

项目 数值
硬件成本 0(闲置手机本来就在抽屉里)
电费 手机待机 + 常亮屏幕约 2-5W,按 0.6 元/度算,一天 0.03-0.07 元
时间成本 首次安装 15 分钟(换源 + 拉镜像),后续配置改一次 2 分钟
镜像体积 Nginx 约 40MB,cloudflared 约 80MB
存储占用 每个容器约 50-200MB,看镜像大小

对比一下:一台 N100 小主机 24 小时开着,一年电费约 100-150 元。手机方案的电费可以忽略不计。

收益侧

  • 零硬件投入:旧手机本来就是沉没成本
  • 便携:随身带一台"服务器",这个场景 N100 做不到
  • 低功耗:2-5W vs 6-15W(N100 待机),差距不大但手机赢在"不用买"
  • 学习价值:YAML 编排 + PRoot 原理 + OCI 镜像结构,都是可迁移知识

风险侧

  • 稳定性:后台被杀、系统更新后 Termux 失效、镜像拉取失败,都属于"预期内会出问题"
  • 安全:PRoot 无隔离,跑陌生镜像前请三思
  • 维护:项目太新,作者更新频率未知,可能半年后就停更

结论

如果你手边正好有闲置安卓手机,且想找个周末小项目折腾,值得玩。

如果你是为了"稳定跑一个家庭服务",别折腾——买台 N100 或者用云 VPS,省心十倍。

能跑什么、不能跑什么

适合的场景

  • 家庭消息转发机器人(Node.js / Python 常驻进程)
  • 轻量 Webhook 接收服务
  • Aria2 / yt-dlp 下载工具
  • Cloudflare Tunnel 客户端(官方示例就是它)
  • 简单的 Web 服务器(Nginx / Caddy)
  • 临时测试环境(跑个 Redis 练手)

不适合的场景

  • 数据库(MySQL / PostgreSQL):PRoot 下 IO 性能差,且无资源限制
  • 重型应用(Discourse / Nexus):镜像大、依赖复杂、内存吃紧
  • 多用户服务:无隔离,安全边界太薄
  • 7×24 生产服务:Android 后台策略不允许

常见问题

Q1: 需要 Root 吗?需要解锁 Bootloader 吗?

A: 都不需要。PRoot 的核心价值就是在用户空间模拟 root,不碰底层权限。

Q2: 和 Termux 里跑 Qemu 虚拟机装 Docker 比,哪个快?

A: termux-containers 快得多。Qemu 是硬件虚拟化,在 ARM 上跑 x86 镜像要走模拟,性能损失巨大。PRoot 是系统调用拦截,开销小一个数量级。作者做这个项目的初衷就是嫌弃 Qemu 太慢。

Q3: 能跑 amd64 镜像吗?

A: 理论上 PRoot-Distro 支持拉取后构建,但兼容性不保证。最稳妥的做法是找官方提供 linux/arm64 的镜像。Nginx、cloudflared、Alpine 系都有 ARM64 版本。

Q4: 手机锁屏后服务会断吗?

A: 会。Android 的 Doze 模式会冻结后台进程。把 Termux 加入电池优化白名单、允许后台活动、保持屏幕常亮(或至少不锁屏),能缓解但不能根除。

Q5: 多个容器之间能通信吗?

A: 能。它们都跑在同一个 PRoot 环境里,共享网络栈。容器 A 监听 8080,容器 B 可以用 127.0.0.1:8080 访问。但没有 Docker 那种自定义 bridge 网络。

Q6: 配置文件里的 PORT 是端口映射吗?

A: 不是。README 里明确写了:"PORT 是应用环境变量,不是端口映射。" 它只是传给容器的环境变量,应用自己决定监听哪个端口。

Q7: 改了镜像 tag 会丢数据吗?

A: 会。README 警告:“修改镜像引用后执行 apply 会重建对应容器,丢失容器内未挂载的数据。” 重要数据务必通过 volumes 挂载出来。

相关阅读

© 2026 softon.top

本站已稳定运行 309 天 15 小时 · 148 篇文章

使用 Hugo 构建 主题 Stack 由 Jimmy 设计 由 softon 魔改

最近构建时间:2026-11-06 23:53:19 CST