手机跑CentOS 7搭建LNMP环境,Termux+proot实战指南
手机装CentOS 7再把LNMP整套跑起来这事听起来确实有点“折腾自己”但真把它弄通之后你会发现它反倒是个特别适合练手的环境。我自己是在一台淘汰下来的旧安卓机上试的装了Termux用proot-distro把CentOS 7的rootfs拉进来然后Nginx、MariaDB、PHP一个个装最后这台手机就变成了一台能通过局域网访问的Web服务器。整个过程不需要root不会破坏手机原本的系统玩坏了直接把proot的目录删掉重来就行。写这篇东西主要给两类人看一类是刚开始学Linux、手上暂时没有电脑的学生党想找个零成本环境练命令另一类是出差只带了手机、临时想验证一个Web环境或者跑个小项目的运维同行。手机端跑LNMP肯定代替不了云服务器但作为学习环境、演示环境、临时调试环境它比你在脑子里面空想Linux命令要直观得多。1. 手机跑CentOS 7先把思路理清楚1.1 为什么是Termux proot而不是完整虚拟机手机上跑Linux常用方案其实就三种QEMU虚拟机、chroot类方案、还有Termux自带的Proot环境。我先说结论我最终选了Termux proot-distro原因不复杂。QEMU虚拟机方案听起来最“正宗”因为它真的模拟了一台完整机器可以安装CentOS 7官方镜像内核也是真的跑起来。但代价非常大手机上的CPU、内存和存储都经不起QEMU的折腾特别是aarch64架构的CentOS 7本身就不是主流镜像启动一次要等很久装LNMP更是噩梦。我在旧手机上试过一次光启动到登录界面就将近十分钟进去之后操作延迟明显后面直接弃了。chroot方案需要手机已经root而且要求内核能匹配你要跑的系统环境布置复杂。现在大多数人手机不root这条路直接pass。Proot是目前比较务实的方案。它不是虚拟机核心思路是拦截open、read、write这类系统调用把进程对“根目录”的访问重新映射到你指定的rootfs目录里相当于给普通用户造了一个“假的根目录”。好处很明确不需要root不污染手机系统性能损失比QEMU小一个数量级。缺点也有一些最典型的就是systemd在proot里起不来因为systemd需要cgroup、namespace这些内核能力的配合proot给不了。不过LNMP这套东西还真不太依赖systemdCentOS 7本身的service命令基于SysVinit脚本照样能把Nginx、MariaDB、PHP-FPM拉起来。这就是手机跑LNMP能成立的关键。方案是否需要root启动速度systemd支持跑LNMP体验推荐度QEMU虚拟机不需要很慢支持卡顿基本没法用不推荐chroot需要快支持依赖内核匹配不适合大众proot-distro不需要很快不支持流畅service可替代推荐1.2 手机端跑LNMP的边界能做什么别指望什么先把丑话说在前面。手机跑LNMP最大的价值是“学习”和“验证”不是“生产”。学习Linux目录结构、理解Nginx配置、搞懂PHP-FPM和MySQL之间的协作流程这些完全没问题。出差或者在外面临时起一个环境给同事演示一下页面效果也没问题。但你要是在这台手机上挂公网服务或者跑一个数据量稍大的应用那肯定扛不住。手机CPU功耗墙很低跑满几分钟就开始降频proot本身也会增加系统调用开销同样的PHP页面在普通云服务器上能跑几千QPS在手机上可能就剩下几百。存储方面也别抱太大期望旧手机的eMMC随机读写性能摆在那里数据库频繁写入的时候延迟会很明显。定位清楚这些边界后面折腾起来心态才会稳。2. 准备工作与CentOS 7镜像选择2.1 Termux安装与换源这一步别偷懒Termux是Android平台上一个很成熟的终端模拟器自带了包管理器和Linux用户态环境。安装渠道一定要用F-Droid不要用Google Play商店里的版本Play版更新滞后还有一堆限制会让你少踩很多坑。装好之后第一件事不是装proot而是先换源。Termux默认的软件源在国外网络状况不好的时候pkg update能卡到你怀疑人生。Termux提供了一条换源命令termux-change-repo运行之后会弹出图形化选择界面挑一个国内镜像就行实测下来清华、中科大都可以。换完源执行pkg update -y pkg upgrade -y然后装proot-distropkg install proot-distro -yproot-distro算是Termux社区管理Linux发行版的标准工具它负责下载、解压、配置rootfs以及提供一条login命令让我们进入CentOS 7环境。顺便执行一下termux-setup-storage授予Termux读取手机存储的权限因为后面下载的镜像文件可能需要借助手机存储中转。2.2 拉CentOS 7的正确姿势以及arm64镜像的大坑很多教程会直接告诉你proot-distro install centos proot-distro login centos但这里有个隐蔽的坑不同版本的proot-distro内置的CentOS镜像版本不一样新版里默认给的可能是CentOS 8/9甚至Stream版本并不是我们要的CentOS 7。CentOS 7在2024年已经停止维护官方仓库的数据都挪到了vault目录默认源如果不处理装完系统第一步yum就会404。我实际用的方法是手动下载CentOS 7的rootfs压缩包再让proot-distro导入。CentOS 7官方对aarch64架构的镜像放在altarch目录下文件名大致是CentOS-7-aarch64-rootfs-7.9-2009.tar.xz拿到这个包的下载地址之后在Termux里直接wget下载到手机存储里。如果网络不稳定也可以先在电脑上下好再用数据线拷贝到手机。下载完以后导入proot-distro install --rootfs centos7 /sdcard/Download/CentOS-7-aarch64-rootfs-7.9-2009.tar.xz不同版本的proot-distro参数会略有差异如果提示不支持--rootfs也可以手动用proot-distro安装任意发行版再加自定义rootfs或者直接解压到指定目录再写一份配置文件。核心思路是一样的让proot-distro知道我们有一个自定义的CentOS 7 rootfs它负责帮你登录进去。进入环境验证一下proot-distro login centos7 cat /etc/redhat-release看到CentOS Linux release 7.9.2009就算成功了。这里还要强调一下手机CPU是aarch64所有软件包都得走aarch64仓库别手滑下成x86_64的。CentOS 7的arm64软件仓库支持度其实还可以nginx、mariadb、php这些核心包都有足够LNMP使用。3. 环境初始化换源、关SELinux、处理systemd3.1 CentOS 7源失效怎么办一键切换vault源刚进入CentOS 7环境我建议别急着装LNMP先把yum源搞定。CentOS 7停止维护之后原来的mirror.centos.org已经不再提供7系列的软件包直接yum install大概率会报404或者metadata错误。处理方法分两步备份原来的repo文件然后手写一个指向vault的repo。考虑到手机是aarch64架构需要走altarch vault路径。我直接用阿里云的镜像mkdir /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ cat /etc/yum.repos.d/centos7.repo EOF [base] nameCentOS-7 - Base baseurlhttp://mirrors.aliyun.com/centos-vault/7.9.2009/os/aarch64/ gpgcheck0 [updates] nameCentOS-7 - Updates baseurlhttp://mirrors.aliyun.com/centos-vault/7.9.2009/updates/aarch64/ gpgcheck0 [extras] nameCentOS-7 - Extras baseurlhttp://mirrors.aliyun.com/centos-vault/7.9.2009/extras/aarch64/ gpgcheck0 EOF yum clean all yum makecache写repo时有几个细节gpgcheck0是图省事生产环境不建议这么做但手机上的实验环境问题不大baseurl一定要用aarch64路径别照抄网上x86_64的例子。如果官方vault被墙或者特别慢也可以换成清华的mirrors.tuna.tsinghua.edu.cn/centos-altarch-vault/方法一样只改baseurl前半段就行。试一下yum repolist能看到三个仓库都正常拉取元数据接下来的安装才会顺利。3.2 systemd起不来不要慌service命令能接盘进入proot的CentOS 7后很多人第一件事就是敲systemctl start nginx然后收获一条报错Failed to connect to bus: No such file or directory别慌这是正常的。systemd要作为PID 1运行需要挂载cgroup文件系统需要特权能力proot给不了这些。但这个限制对LNMP影响其实很小因为CentOS 7的服务脚本都兼容SysVinit路径你可以直接使用service nginx start service mariadb start service php-fpm start这条命令本质上会去执行/etc/init.d/下的脚本由脚本负责拉起进程。很多运维老手这么多年都是用service管理服务的所以手机里没有systemd并不影响LNMP的启动和停止。SELinux在proot里也基本是负优化建议直接关掉不然后面PHP写文件、Nginx读目录都可能被权限卡住setenforce 0这个命令在proot环境里偶尔会提示不支持没关系再编辑一下/etc/selinux/config把SELINUXenforcing改成SELINUXdisabled下次重新登录这个rootfs时系统会走一遍初始化SELinux会变成permissive甚至直接关闭省掉后续一堆莫名其妙的permission denied。基础工具顺手装一批yum install -y vim net-tools curl wgetnet-tools提供ifconfig和netstat虽然CentOS 7默认装的是iproute2但用惯了ifconfig的话还是装上省心。4. LNMP环境搭建实操4.1 Nginx安装与配置worker数别贪多CentOS 7的yum仓库里有Nginx版本不算新但胜在稳定直接安装yum install -y nginx安装完成后先别急着启动改一下nginx.conf。手机CPU核心数一般不超过8个跑LNMP实验环境完全没必要把worker_processes调大反而会让手机更卡。我配置的是worker_processes 1;events块里的worker_connections也没必要给到默认的1024以上手机实验场景512足够了。gzip压缩可以开对节省带宽有帮助手机上测试页面体积小感知不明显。启动前先用nginx -t检查配置语法没问题再service nginx start验证方式很简单在Termux里执行curl -I http://127.0.0.1能看到HTTP/1.1 200 OK就是起好了。如果你想用手机浏览器看直接访问http://127.0.0.1会看到CentOS 7默认Nginx欢迎页。这个页面路径是/usr/share/nginx/html/index.html后面PHP测试页也放在这个目录下。4.2 MariaDB安装与初始化老版本也有它的稳CentOS 7仓库里的数据库组件是MariaDB没有MySQL。这是历史原因CentOS 7发布时MariaDB已经取代MySQL成为默认关系型数据库而且兼容MySQL协议和SQL语法。对学习LNMP环境来说你完全可以把MariaDB当成MySQL用。安装yum install -y mariadb-server启动service mariadb startCentOS 7仓库里的MariaDB版本是5.5不需要额外的初始化步骤启动后直接就能用。第一次进去执行安全初始化mysql_secure_installation这个脚本会让你设置root密码、删除匿名用户、删除test库、禁用root远程登录一路按提示走就行。然后创建一个测试库和专用账号避免后面PHP始终用root连库CREATE DATABASE testdb DEFAULT CHARACTER SET utf8mb4; CREATE USER phpuserlocalhost IDENTIFIED BY 123456; GRANT ALL PRIVILEGES ON testdb.* TO phpuserlocalhost; FLUSH PRIVILEGES;用utf8mb4而不是老的utf8是因为utf8mb4才是完整的Unicode支持哪怕在测试环境里都建议养成新习惯。phpuserlocalhost这个授权范围够用了proot环境里PHP和数据库都在同一个rootfs里用localhost连接即可。4.3 PHP安装选型别硬用默认的PHP 5.4CentOS 7官方源里的PHP是5.4版这个版本在当年是主力但现在看实在太老很多现代框架和Composer包直接不支持。既然手机都折腾到这一步了PHP版本也别太委屈自己。我用的方案是装Remi仓库然后启用PHP 7.2的模块。先装EPEL和Remi的release包yum install -y epel-release rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum install -y yum-utils yum-config-manager --enable remi-php72如果希望PHP版本更高可以把后面换成remi-php73、remi-php74。原则上别直接开remi默认仓库那个默认是PHP 5.4的补充包用户最好明确指定启用哪个PHP系列。启用之后安装组件yum install -y php php-fpm php-mysqlnd php-gd php-mbstring注意php-mysqlnd必须装否则PHP代码里连MySQL会报Call to undefined function mysqli_connect()。安装完成后启动php-fpmservice php-fpm start如果报错提示/run/php-fpm目录不存在手动创建一下mkdir -p /run/php-fpm chown apache:apache /run/php-fpmphp-fpm的默认监听地址是127.0.0.1:9000这个保持默认就行Nginx会通过这个端口把PHP请求转发过来。查看进程确认ps aux | grep php-fpm能看到master进程和几个worker进程在跑就OK。5. 联调与验证让Nginx把请求交给PHP5.1 Nginx配置server块PHP解析跑通LNMP三个组件分别装上只是第一步真正让它们协作起来需要Nginx配置好PHP解析规则。在/etc/nginx/conf.d/下新建一个测试配置server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.php index.html index.htm; location / { try_files $uri $uri/ 404; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; } }这个配置的核心在location ~ \.php$块里。正则匹配所有.php结尾的请求然后通过fastcgi_pass把请求交给9000端口的php-fpm处理。SCRIPT_FILENAME告诉PHP-FPM要执行的文件路径在什么地方这个参数经常漏配漏了就会返回空白页或者404。写完配置后检查语法并重载nginx -t service nginx reload然后写一个测试页面验证PHP解析是否成功。在/usr/share/nginx/html/index.php写入?php phpinfo();手机浏览器访问http://127.0.0.1/index.php能看到PHP 7.2的配置信息就说明Nginx到PHP-FPM的链路是通的。5.2 测试数据库连通性一次串起来PHP环境通了之后再把MariaDB拉进来验证联动。写一个带数据库连接测试的PHP脚本?php $conn new mysqli(127.0.0.1, phpuser, 123456, testdb); if ($conn-connect_error) { die(数据库连接失败 . $conn-connect_error); } echo 数据库连接成功MariaDB版本 . $conn-server_info; $conn-close();浏览器访问这个页面看到数据库连接成功就说明LNMP整套环境彻底跑通了。到这里手机就是一台五脏俱全的Web服务器Nginx负责接收HTTP请求PHP-FPM负责执行PHP代码MariaDB负责存数据。如果这一步报错优先级最高的排查点是php-mysqlnd扩展是否存在php -m | grep mysqlnd没输出就说明扩展没装回去补装php-mysqlnd。另外注意mysqli和pdo_mysql都可以通过php -m查看缺失的话同样从php-mysqlnd里补。6. 常见问题与排查技巧实录6.1 问题速查表手机上折腾这套环境几乎每一步都有坑。我把实际踩过的问题整理成一个表格遇到类似的可以直接对着排查。现象可能原因处理方式yum makecache报404CentOS 7源失效没有切换vault按3.1的写法重建repo文件service nginx start失败配置语法错误或80端口被占用nginx -t检查lsof -i:80看占用访问PHP页面变成下载或空白Nginx没有配置PHP解析确认conf.d里的location ~ .php$Nginx访问PHP返回502php-fpm没启动或端口不对service php-fpm status查看/var/log/php-fpmPHP连数据库报connect errorphp-mysqlnd缺失或账号授权不对装php-mysqlndGRANT授权启动php-fpm报/run/php-fpm不存在目录未创建mkdir -p /run/php-fpmproot里执行systemctl失败proot不支持systemd改用service命令setenforce 0提示不支持proot环境限制忽略改配置文件禁用6.2 手机端资源限制与保活技巧手机跑Linux环境最大的敌人不是性能而是系统杀后台。如果你锁屏一段时间再回来发现Termux进程被Android系统回收了proot环境也随之消失。解决方法是Termux内置的wakelocktermux-wake-lock这个命令会请求Android系统保持CPU唤醒状态让Termux进程在后台不被冻结。实验做完记得执行termux-wake-lock的对应关闭命令termux-wake-unlock不然手机耗电会明显增加。内存方面Nginx、MariaDB、PHP-FPM三件套加一起在空载状态下大约占用200MB到300MB内存手机总内存低于3GB的话会有点紧张。我建议调整一下PHP-FPM的进程配置在/etc/php-fpm.d/www.conf里pm dynamic pm.max_children 2 pm.start_servers 1 pm.min_spare_servers 1 pm.max_spare_servers 2减少PHP-FPM的worker进程数能让手机在跑其他应用时不至于卡死。存储方面也要注意rootfs默认放在Termux的应用数据目录里如果你的手机存储空间紧张装完LNMP之后记得清理yum缓存yum clean all6.3 局域网访问把手机变成一台真正能被访问的服务器如果你不想只在手机上自娱自乐想用电脑或者平板浏览器访问这台手机服务器先查一下手机在局域网里的IPip addr show找到wlan0接口下的IPv4地址比如192.168.1.100。同一WiFi下的设备直接访问http://192.168.1.100就能看到Nginx欢迎页并进一步访问PHP脚本。proot环境监听端口默认绑定在手机网络接口上不需要额外转发。局域网访问不了的时候优先检查手机系统自带的网络权限是否允许Termux后台联网其次看看Nginx是否真的在监听所有接口netstat -lnt第二列出现0.0.0.0:80说明监听正常。另外有些手机系统有“休息时断开网络”的省电策略记得把Termux加入电池优化白名单。7. 实测表现与个人建议7.1 性能参考我自己实测的机器是一台骁龙845、6GB内存的旧手机系统是Android 10跑这个proot CentOS 7环境。启动CentOS 7环境从登录到可用大约5秒Nginx、MariaDB、PHP-FPM三件套全部启动也就十几秒。用ab简单压了一下一个纯PHP输出页面ab -n 1000 -c 10 http://127.0.0.1/index.php结果在900到1100 QPS之间浮动CPU占用率大概60%。这个数字和云服务器肯定没得比但作为学习环境完全够用。手机如果开启省电模式性能会再打折扣建议测试时关闭省电模式。7.2 什么人适合用手机跑LNMP个人体验下来有几种人特别适合这种环境。一是Linux入门者手机随时随地能看命令、试配置比看视频课直观太多。二是短期需要演示环境的从业者比如在外面临时要给客户展示一个小Demo手机服务器反而方便。三是对系统原理感兴趣的人在proot里跑CentOS 7能直观感受到虚拟机、容器、系统调用之间的区别这些东西光看文档真的很难体会。如果你期望的是高性能、生产级Web环境手机这套方案肯定不合适趁早买个云服务器或者在家里放一台小主机才是正道。手机跑LNMP的正确心态是把它当实验室而不是机房。7.3 我的几点体会折腾完这个项目有几个经验我觉得值得留给你。第一手机端装LNMP尽量用包管理器安装组件不要自己编译源码。proot环境里编译PHP或者Nginx都会非常折磨光configure就可能跑十几分钟而yum装二进制包几秒钟就搞定。第二注意备份rootfs。手机环境说白了说没就没系统升级、应用清理都可能导致整个CentOS 7消失。备份方式很简单直接用tar打包整个rootfs目录tar -czf centos7-lnmp-backup.tar.gz /data/data/com.termux/files/usr/var/lib/proot-distro/installed-rootfs/centos7以后想恢复解压回去重新login就行。第三如果你手头有更好的手机或者平板这套方案的可玩性会更高大屏配合键盘操作起来的体验接近一台小电脑。手机跑Linux这件事情说到底不是为了替代任何正经服务器而是让你在碎片时间里也能有一个折腾环境。搞通了LNMP后面想在这个基础上加Redis、加Node、加Python服务思路都会顺很多。