抽屉里那台退役的手机,现在是 7×24 在线的低功耗 Linux 服务器。
两年前的手搓方案,配置下来要半天,现在只需要20分钟(从小时级骤降至分钟级,效率提升 18 倍,配置耗时减少近 95%→_→ 串台了,这里不看这个。)。
- 一、背景:旧手机卖不掉、用不着只能躺抽屉吃灰
- 二、旧手机当服务器,硬件上其实很占便宜
- 三、做完之后,你会得到三样东西
- 四、用到的东西,以及每一件为什么必须在
- 五、如果全手工做,是什么体验
- 六、转折:把执行交给 AI
- 七、人需要做的事:四步软件 + 一件硬件
- 八、它自己接上的第一条手臂:Termux 里的 SSH
- 九、丢一个提示词,剩下的事它自己干
- 十、跑起来之后长什么样
- 十一、最后:AI 的价值不是替你写代码
一、背景:旧手机卖不掉、用不着只能躺抽屉吃灰
换手机之后,旧机器通常有个固定的命运:先是备用机,然后变成闹钟,最后躺在抽屉里,每隔半年被拿出来充一次电。
它并没有坏——没有碎屏,没有进水,电池可能至少还有 80% 健康度,至少8 核处理器、6~16GB 内存、128~1024GB 存储,比很多人在跑的云服务器还宽敞。它唯一的问题只是"不够新",于是被市场判了死刑。
后来我想明白一件事:我不需要它跑得快,我需要它一直开着。
于是它从抽屉里被捞了出来,目标是改造成一台 7×24 在线的 Linux 小服务器。
二、旧手机当服务器,硬件上其实很占便宜
先说为什么是手机,而不是去买树莓派或者开一台云主机:
| 优势 | 说明 |
|---|---|
| 自带电池 = 天然 UPS | 这是最被低估的一点。家里跳闸、插座松动、不小心踢掉线,树莓派直接关机,而手机只是把电源换成了电池继续跑。对"服务必须在线"这件事来说,这是白送的可靠性 |
| 功耗极低 | 屏幕熄灭、CPU 降频之后整机只有几瓦量级,24 小时开着一年也没多少电费 |
| 永远在线 | 它本来就是为了常驻网络而设计的:Wi-Fi 长连、休眠唤醒、甚至有厂商级的省电策略(虽然这些策略后来成了我的主要敌人) |
| 性能够用 | 8 核 + 7.5GB 内存,跑几个单进程服务(网盘、下载器、SSH、AI 控制台)绰绰有余。实测我这套东西常驻内存合计约 487MB |
| 存储可观 | 225GB,比我大部分的云盘配额都大,而且插在手机上就是本地盘 |
| 零边际成本 | 已经买了,闲着也是闲着 |
当然,Android 也给我准备了一堵墙:没有 root、没有 systemd、没有 Docker、应用之间互相隔离、/sdcard 上不允许执行文件、后台进程随时可能被杀。
这套方案本质上是在墙内凿出三个洞,然后让 AI 住进去干活。
三、做完之后,你会得到三样东西
1. 一个贴身的 AI 操作台(这是核心)
用手机浏览器打开 http://127.0.0.1:3080,就是一个完整的 AI 工作台:能读写文件、执行命令、跑子任务、记住上下文。
它的价值不在于"能聊天",而在于它同时有三条手臂:
① 容器内 bash → 能跑 glibc 程序、Ubuntu 工具链
② ssh -p 8022 → 原生 Termux(真实内核、真实负载、原生速度)
③ adb shell → 整机(uid 2000:改系统设置、读日志、碰别的应用)
这意味着它可以:自己改配置、自己重启服务、自己看日志、自己验证结果。你要做的只是说清楚目标。
平时它可以干什么?举几个我已经在用的:
- 装新服务、调参数、写开机自启脚本
- 排查"为什么服务没起来"(它是真去读日志,不是猜)
- 用 adb 抓整机资源报告,告诉你哪个应用在偷偷吃电
- 临时当个"运维助手":清理重复文件、对比哈希、迁移数据
它是一台随叫随到、住在手机里的运维搭子。
2. 一个网盘(OpenList / AList 的继任者)
OpenList 挂在 /sdcard 上,于是手机里那 225GB 变成了:
- 网页版文件管理器(局域网内任何设备都能开)
- WebDAV 服务(能让电脑把手机挂成网络驱动器)
- 分享链接(给朋友发个临时下载地址)
我用它挂出了相册、下载目录和整个共享存储。
3. 一个离线下载器(aria2)
aria2 带 RPC 接口,被 OpenList 托管成"离线下载":磁力链接、HTTP 直链、多镜像加速断点续传,丢进去就行,进度在网页上看着。
实测它能吃满宽带(约 5MB/s),下完的文件自动落进 /sdcard/Download。
合起来的效果是:一个局域网里随时可访问的私人网盘 + 下载机,背后还坐着一个能自己干活的 AI。

四、用到的东西,以及每一件为什么必须在
这套东西看起来层数不少,但每一层都在解决一个具体问题:
| 软件 | 角色 | 为什么不能省 |
|---|---|---|
| Termux | 原生 Linux 用户态(bionic) | 这是唯一的入口。它不需要 root,却能提供 pkg 包管理和完整的命令行环境 |
| adb(android-tools) | 提权通道(uid 2000 shell) | 越过应用沙箱:改全局设置、读 logcat、读别的应用数据。而且 Android 12 有个"子进程超过 32 个就杀"的限制,只有它解得开 |
| proot-distro + Ubuntu | glibc 兼容层 | 很多程序(AList/OpenList 的官方二进制、AI 控制台的 Node 原生模块)是链接 glibc 的,Android 的 bionic 加载不了。这一层让它们能跑 |
| Node.js + DSH | AI 操作台 | 让"AI 帮你干活"变成"AI 在手机里干活" |
| Termux:Boot | 开机自启 | Android 没有 systemd,服务要活着就得靠它 |
| OpenList / aria2 | 网盘 / 下载器 | 服务本体 |
顺便说一句你可能关心的代价:proot 这层不是容器,是"系统调用翻译层"。它的实测副作用是——
- 身份是"假 root":
id显示 root,但内核眼里这个进程仍然是 Termux 应用(/proc/self/status里写着Uid: 10191) - 没有 capability:绑不了 80/443,
mount、setgid全是假的 - 没有命名空间:Docker 免谈,
unshare返回成功但没有隔离 - 一些系统信息是伪造的:
uname -r会显示一个不存在内核版本,/proc/loadavg永远显示0.12 0.07 0.02(静态快照) - 性能要交"过路费":翻译层自己会持续消耗 CPU——我这台机器上它累计烧了 27 分钟 CPU,比它服务的应用还多
/sdcard是 FUSE 文件系统:不能执行文件、不能建软链、chmod无效
所以最后的架构原则是:重 I/O 放原生侧,重依赖放容器侧,整机操作走 adb。
五、如果全手工做,是什么体验
前面那些听起来还挺顺利,对吧?让我说说以前的真实体验——这才是这篇博客真正想聊的部分。
在手机上手工把这套东西搭起来,难的不是技术,是每一个动作都很别扭:
第一,输入本身是折磨。 用软键盘敲 proot-distro login ubuntu -- bash -lc 'apt update && apt install -y curl' 这种命令——引号容易被输入法换成中文标点,长命令在窄屏上折成三行看不清,没有 Tab 补全所以路径打错一个字符就要重来,Ctrl+C 要找半天,复制粘贴要在浏览器和终端之间来回切窗口。
第二,排查错误是纯粹的体力活。 服务没起来,你要在四五个文件之间来回翻:~/boot.log 有没有记录、~/openlist.log 报了什么、~/dsh.log 里的地址变没变、dumpsys 里那个进程还在不在。屏幕只有六寸,一次看十几行,grep 打错一个字符又得重敲。
第三,最要命的是"碎"。 举一个我真实踩过的坑:
aria2 每次重启之后,都会重新下载一批我早就下完的文件。查下去才发现是配置文件里一个
force-save=true:它会把已完成的任务也留在会话文件里;而网盘程序在下载完成后会把文件从临时目录移动到目标存储——于是重启后下载器按会话文件重新加载,发现临时目录空了,就老老实实又下一遍。
这个坑的完整确认过程是:对比会话文件与磁盘上的实际文件 → 计算 1.4GB 文件的 sha256 确认两份拷贝一致 → 改配置 → 清会话 → 等 70 秒跨过定时保存点后再复查一次,确认它不会把任务写回去。
在人手上,这至少是一两个小时的来回折腾;而且每一步都要"改一下、试一下、看一眼"。
类似的事情还有一箩筐:开机自启被手机厂商的后台管理拦掉(但脚本日志里一条记录都没有,所以你得先证明"是广播没送到"而不是"脚本写错了");下载器进程被 pkill 静默杀失败了,导致我基于旧进程的数据做了半天错误判断;容器里读到的负载永远是 0.12,让人误以为系统很闲……
这些活的共同点是:不难,但很碎,而且碎得让人烦躁。 而"碎"恰好是最该被自动化的东西。
六、转折:把执行交给 AI
于是流程被重新设计了一遍。
关键认知是:这套改造里真正需要"人"的部分,其实只有三件事——
- 装应用、点系统弹窗(AI 没有手)
- 改手机厂商的私有设置(启动管理、省电策略,
adb也碰不到) - 重启(AI 自己执行重启会把宿主一起杀掉)
剩下的全是"读完日志决定下一步"的碎活——而这正是 AI 最擅长的:它不会累、不会烦、可以一次读五个日志文件、可以精确复制粘贴、可以在改完之后自己验证一遍再回来汇报。
所以现在整个方案被拆成了两半:
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ 人:装基础软件 + 配保活 │ → │ AI:其余全部 │
│ (约 15 分钟,一次性) │ 提示词 │ (装服务 / 配自启 / 排错 / │
│ │ │ 验证 / 出报告,持续可用) │
└─────────────────────────────┘ └──────────────────────────────┘
七、人需要做的事:四步软件 + 一件硬件
我把人工部分压缩到了四步(大约十五分钟),另外还有一件硬件上的事最好一起做掉——尤其是你打算让它常年插着电:
① 装两个应用
Termux(用 GitHub 的 debug 版本)和 Termux:Boot。两个都打开一次。
(为什么要 GitHub 版:插件必须和 Termux 同签名才能工作。)
② 打开一把"高权限钥匙"
开发者选项 → USB 调试 → 无线调试;adb connect 的时候手机上会弹一次"允许 USB 调试吗",勾上"一律允许"。
顺手解开 Android 12 的进程限制:
adb shell device_config put activity_manager max_phantom_processes 2147483647
③ 在 Termux 里粘一段引导命令
一条命令装好 Termux 侧基础件、Ubuntu、Node 和 AI 控制台,最后打印一个网址:
pkg update -y && pkg install -y proot-distro openssh android-tools python3 curl git
termux-setup-storage # 弹窗点"允许"
ssh-keygen -A && sshd
proot-distro install ubuntu
proot-distro login ubuntu -- bash -lc '
apt update && apt install -y curl ca-certificates &&
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - &&
apt install -y nodejs && npm i -g @deepseek-ai/dsh'
proot-distro login ubuntu -- /usr/bin/dsh web --no-open # 打开它打印的网址
④ 配两个"保活"开关(这步千万别省)
设置 → 应用启动管理:把 Termux 和 Termux:Boot 改成手动管理,三个开关(自启动 / 关联启动 / 后台活动)全开;
设置 → 电池:Termux 设为不受限制。
这一步不做会怎样?我第一次重启后,四个服务一个都没起来,而且自启脚本自己的日志里连一行记录都没有——不是脚本错,是系统的开机广播压根没送到应用。改完这两个开关,重启后一分钟内四个服务全部到位。
⑤(硬件,但别跳过)常年插电,先把电池这件事解决掉
手机当服务器有个前提:它得一直插着电。而锂电池长期满电 + 温热,正是鼓包的两大诱因——旧手机往往散热更差、电池更老,长年这么用风险不小。所以下面两条路,至少要选一条:
路线 A:用系统自带的充电上限(最省事)
设置 → 电池 → 「电池健康 / 更多电池设置」→ 找 充电上限 / 智能充电 / 电池保护,设到 80%(或系统允许的最低值)。
各家叫法不同:三星叫 Protect battery(85%)、索尼叫 Battery care,小米 / OPPO / 一加 / 荣耀基本都有类似开关,部分华为机型叫"智能充电模式"。如果手机没有这个开关、又不想 root,那就用一个定时插座:每天只通电 1~2 小时,让它在中段电量循环,而不是 24 小时顶在 100%。
路线 B:直供电电池小板(一劳永逸)
买一块"直供电 / 假电池小板",把电池替换掉,直接用适配器给手机供电。这样就从根上消除了鼓包和高温老化——很多把手机当固定终端长期跑的人都是这么干的。
买之前注意三件事:
- 电压必须对:单芯电池一般是 3.7~4.4V,千万别拿 5V 直接怼到电池接口上。优先选带可调压的型号
- 要能骗过电池检测:有些机型检测不到电池会不开机,或者疯狂降频。选带 NTC / 识别电阻(BMS 模拟) 的小板,最好买对应机型的
- 代价是失去"手机自带的 UPS":电池拆掉后,一断电就立刻关机。如果你在意断电续命,就把它接在一个小 UPS 或充电宝上(本质上就是"外置电池")
取出来的原电池别乱放:已经鼓包的绝对不要再充、不要戳、不要挤压,按规定交给回收点。
顺手再补两条
- 散热:别把它压在路由器、机顶盒这类发热设备上,留出空气流通——高温会让上面所有努力打折
- 定期体检:让 AI 隔一段时间用
adb shell dumpsys battery记一下health / level / temperature(它本来就有这条通道),数值异常就提醒你;物理上偶尔看一眼后盖有没有被顶起、屏幕边缘有没有翘,那是鼓包最早的信号
然后,就没有然后了。 剩下的交给一句话。
八、它自己接上的第一条手臂:Termux 里的 SSH
在丢提示词之前,有一步很容易被跳过,但它决定 AI 能不能真正"伸出去":给 Termux 开一个 SSH 服务,然后让 AI 自己连进去。
为什么非要这一步?因为 AI 的 bash 工具默认住在容器里,而容器看到的世界是打过折的:
uname -r会显示一个不存在的内核版本(proot 伪造的)/proc/loadavg永远是0.12 0.07 0.02(一个静态快照文件,不是真实读数)- 装不了 Termux 的原生包(网盘、下载器都是原生包更好)
只有原生 Termux 才有真实的内核、真实的负载、和 pkg。
那人在手机上要做什么?其实只有一条命令——把 SSH 服务打开:
pkg install -y openssh
ssh-keygen -A # 生成 host key
sshd # 监听 8022
接下来是最妙的一步:公钥根本不用你复制。
因为 proot 把 Termux 的家目录绑进了容器(/data/data/com.termux/files/home),AI 可以直接读写它。所以剩下的事 AI 自己就能完成:
# 在容器里:生成自己的密钥
ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519
# 直接把公钥写进 Termux 的 authorized_keys(这条路在容器里看得见)
mkdir -p /data/data/com.termux/files/home/.ssh && chmod 700 /data/data/com.termux/files/home/.ssh
cat ~/.ssh/id_ed25519.pub >> /data/data/com.termux/files/home/.ssh/authorized_keys
chmod 600 /data/data/com.termux/files/home/.ssh/authorized_keys
# 然后自己连自己
ssh -p 8022 -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new u0_a191@127.0.0.1
(Termux 的 SSH 用户名其实随意——它的认证会把任何用户名都映射到同一个应用 uid。)
连上之后,AI 用三个指标自证"这次是真原生":
TracerPid = 0 ← 没有被 ptrace 跟踪(不是容器的子进程)
uname -r = 4.19.157-perf+ ← 真实内核(容器里看到的是伪造值)
uptime = up 5:29, load average: 14.27 ← 真实负载(容器里永远是 0.12)
有了这条腿,后面就顺了:AI 可以在原生侧 pkg install、拉起长驻服务、往 ~/.termux/boot/ 写开机脚本——这些路径它都能通过 SSH 直接操作。你不需要在手机上再敲任何一条安装命令。
九、丢一个提示词,剩下的事它自己干
浏览器打开deepseek harness地址,把提示词整段粘进去。完整提示词:old-phone-prompt.txt
提示词里写了五件事:
- 目标:把这台手机变成什么(四个服务 + 可验证的验收报告)
- 环境事实:把上面那些坑直接变成 AI 的"先验知识"——假 root 的双面身份、内核没有 Landlock、
/proc/loadavg是假的、Termux 的sh是 dash、pgrep -x不可靠、force-save会导致重复下载…… 它不用再踩一遍 - 交付清单:建立原生 SSH 通道 → 装 OpenList/aria2 → 接好 RPC → 写幂等的开机自启脚本 → 配网盘临时目录 → 写常用命令和登录提示 → 出验收报告
- 工作方式:先只读取证再动手;一次只改一件事;每一步给真实命令输出当证据;所有自动化脚本必须幂等、可回滚、有日志
- 安全红线 + 何时必须停下来找人:不碰密码、不开高风险开关、删数据先比对哈希、不自己执行重启
然后你就可以去泡茶了。它自己干活的几个真实片段:
- 它自己发现了那个
force-save的坑,改完之后还特意睡了 70 秒跨过定时保存点再复查一遍,确认任务不会写回会话文件 - 它写出了带自诊断的自启脚本:每次运行都记录"是谁触发的"和"距开机多久",于是"厂商拦截"和"脚本报错"一眼可分
- 它用
adb抓了一份整机资源报告,顺手指出:翻译层 proot 自己累计烧了 27 分钟 CPU,比它服务的应用还多 - 清理 1.7GB 重复文件之前,它先把两份拷贝 7 个文件逐个算了 sha256(1.4GB 的包也读了 11 秒),确认一致才删
- 它还会主动告诉你"这个我改不了,需要你点一下"——比如重启、比如厂商设置
整个过程中,我做的事基本就是:点两次"允许"、改两个系统开关、重启一次、然后看它汇报。
十、跑起来之后长什么样
四个服务(全部原生或容器内常驻,开机自动就位):
| 服务 | 端口 | 用途 |
|---|---|---|
| sshd | 8022 | 从电脑连进手机(密钥登录) |
| OpenList | 5244 | 网盘 / WebDAV / 分享 |
| aria2 | 6800 | 离线下载(仅本机 + 密钥鉴权) |
| DSH Web | 3080 | AI 操作台 |
资源占用(真机实测,按应用聚合的 PSS):
| 应用 | 内存 |
|---|---|
| 浏览器 | 817 MB |
| 代理软件 | 585 MB |
| AI 控制台(node) | 415 MB |
| 网盘(OpenList) | 51 MB |
| 下载器(aria2) | 5 MB |
| 整套服务合计 | 约 487 MB |
7.5GB 内存的机器,跑完这些还剩一大半空着。
性能上也有个有意思的对比(同一目录,原生 vs 容器):小目录遍历 0.33s 对 0.42s,差别不大;但把 302MB 的目录树全量扫一遍,容器里直接 60 秒超时。所以最后的部署是"重活放原生、重依赖放容器"。
边界也要说清楚:这台机器上跑不了 Docker(没有命名空间)、挂不了网盘为本地盘(FUSE 不可用)、绑不了 80/443 端口、也没有真正的沙箱隔离。它是"够用的小服务器",不是"完整的云主机"。
十一、最后:AI 的价值不是替你写代码
写到这里我想讲一点感想。
以前我们谈 AI 编程,画面通常是"你说需求,它吐代码"。但这件事里,它一行代码都没为我"创作"——它做的是运维:读日志、提出假设、做最小改动、验证、汇报。
它最有价值的地方是不烦。
在手机上搭服务,真正让人放弃的从来不是技术门槛,而是"又要改一个配置、又要等它重启、又要翻日志、又要再试一次"这个循环。人做三遍就想摔手机了,而它可以做三十遍,并且每一遍都记得上一次学到的东西。
当然它也会犯错。这一晚它就把我的管理员密码覆盖过一次(后来改成从文件读取,不再出现在命令行里)、改错过一个系统配置文件的位置(发现后自己还原了)、还用一个错误的 kill 命令把自己的进程组带走过。所以我现在对它只有三条要求,我把这三条也写进了提示词里:
幂等、可回滚、有日志。
boot.log 那种看着很土的东西,其实才是"信不信得过"的分界线——它让"服务到底起没起来"从玄学变成证据,也让 AI 的每一次失误都留下痕迹、可以复盘。
一台旧手机,几个开源软件,一段提示词。它重新开始工作了,而我也终于不用再在六寸屏幕上敲那些命令了。
本文所有命令与数字均来自真机实测;文中提及的 token、密钥、设备序列号与公网 IP 已脱敏。
完整的「人工清单 + 交接提示词」见同目录 old-phone-handoff.md 与 old-phone-prompt.txt(可整段粘贴给 AI)。


