我把 wp-shell 重写了:现在它更像一个没有 Web 面板的 Cloudways
几个月前,我写过一篇文章:
《告别 Cloudways:用这个极简脚本,10 分钟在原生 VPS 上搭建高性能 WordPress》
当时我写 wp-shell 的目的其实非常简单:
我只是不想为了部署几个 WordPress 网站,再给服务器装一个沉重的 Web 面板。
Cloudways 确实方便,宝塔之类的面板也方便。
但如果本身会一点 Linux,会用 SSH,那么很多时候我真正需要的,无非就是:
- Nginx
- PHP-FPM
- MariaDB
- Redis
- SSL
- WordPress
- 一套合理的性能和安全配置
所以最初的想法就是:
把这些重复劳动写成 Shell 脚本,一条命令完成部署。
当时我甚至觉得,做到这里就差不多了。
结果几个月真正用下来,事情完全不是这么回事。
现在再回头看,最早的 wp-shell 更像是一个 WordPress Installer。
而现在的 wp-shell,我觉得更准确的定义应该是:
一个不需要 Web 控制面板的 WordPress VPS 管理工具。
或者说得更形象一点:
我似乎不知不觉做出了一个“没有 Web 面板的 Cloudways”。
一、后来我才发现:安装 WordPress 其实是最简单的事情
自己维护 VPS 一段时间以后,我越来越觉得:
安装 WordPress 根本不是服务器运维里最麻烦的事情。
安装可能只需要 10 分钟。
真正麻烦的是后面那几个月,甚至几年。
比如:
服务器内存还够不够?
PHP-FPM 应该给多少进程?
MariaDB 为什么突然被 Kill 了?
到底是哪个网站占用了最多资源?
Redis 有没有正常工作?
FastCGI Cache 到底有没有命中?
网站最近是不是突然出现大量 404 或 5xx?
SSL 证书还有多久过期?
昨天的备份到底有没有成功?
一台服务器跑几个 WordPress 比较合理?
如果一个网站突然流量暴涨,会不会把另外几个网站一起拖死?
这些问题,才是真正需要长期解决的问题。
我自己以前在 VPS 上同时跑多个 WordPress 时,就遇到过一个非常典型的问题:
内存不够,然后数据库进程直接被系统 OOM Killer 干掉。
网站看起来就是突然全部打不开。
SSH 上去一看:
MariaDB 没了。
重新启动数据库,网站恢复。
过一段时间又挂。
所以后来我越来越意识到一个问题:
“WordPress 能跑起来”和“WordPress 能长期稳定地跑”,根本是两回事。
这也是后来 wp-shell 越写越大的根本原因。
二、我不想做另一个宝塔
既然功能越来越多,很自然会冒出一个问题:
为什么不干脆做一个 Web 管理面板?
其实我认真想过这个问题。
最后还是放弃了。
因为一旦开始做 Web Panel,就意味着我要额外维护:
- Web 管理后台
- 登录系统
- 权限系统
- 面板自身数据库
- 后台常驻服务
- API
- Web Server
- 安全更新
- 面板漏洞
本来我是想让服务器更简单。
最后很可能为了“管理服务器”,又给服务器安装了一套需要被管理的软件。
这就有点绕回去了。
所以 wp-shell 到现在依然坚持一个原则:
不安装 Web 控制面板。
没有面板网页。
没有面板数据库。
没有远程监控端口。
也没有遥测数据上传。
日常管理仍然通过:
SSH + Shell + WP-CLI + systemd
来完成。
服务器上真正长期运行的,还是 WordPress 本身需要的那些服务。
这其实也是我现在对 wp-shell 定位最满意的地方:
不是为了替代 Linux,而是把日常最烦琐、最容易出错的 Linux 运维操作标准化。
三、现在的 wp-shell 已经和最初完全不是一个东西了
截至我写这篇文章时,wp-shell 已经更新到了 v9.4.7。
现在统一使用一个入口:
sudo wp-shell
以前的:
wp-vps-manager.sh
deploy-single-wordpress.sh
仍然保留兼容,但新安装已经不建议继续使用了。
目前支持:
Ubuntu 22.04 LTS
Ubuntu 24.04 LTS
x86_64
aarch64
也就是说,不管是常见的 Intel / AMD VPS,还是 ARM VPS,都可以使用。
但真正变化最大的,并不是这些。
而是整个架构已经从:
帮我安装一个 WordPress
变成了:
帮我管理一台运行 WordPress 的服务器。
四、单站点和多站点,现在终于统一了
我以前其实写过不同的部署逻辑。
一个是单网站。
一个是多网站。
用久了以后发现,这种设计很烦。
代码要维护两套。
以后增加新功能,也得考虑两套逻辑。
所以后来干脆重新整理。
现在全部统一到:
wp-shell
第一次安装环境时,会让你选择:
Single website
或者:
Multiple websites
这里的 Multiple websites 并不是 WordPress Multisite。
而是:
一台 VPS 上运行多个彼此独立的 WordPress 网站。
比如:
site-a.com
site-b.com
site-c.com
它们都是各自独立安装的 WordPress。
数据库独立。
PHP-FPM 独立。
Redis 独立。
缓存独立。
日志独立。
备份也独立。
这也是我现在比较推荐的部署方式。
五、我最在意的一件事:不要让一个网站拖死整台服务器
一台 VPS 跑多个 WordPress,最大的坑之一就是:
大家抢资源。
假设一台服务器上有三个网站。
其中一个网站装了几十个插件,或者突然来了一堆动态请求。
PHP-FPM 开始疯狂拉进程。
内存一路上涨。
最后最坏的结果不是这个网站自己挂。
而是:
MariaDB 被 OOM Kill,三个网站一起完蛋。
所以现在 wp-shell 给每个网站建立独立的 PHP-FPM Pool。
每个站都有自己的:
- PHP-FPM Pool
- Unix Socket
- Status Socket
- PHP 日志
- Process Limit
这样至少可以知道:
到底是谁在吃资源。
并且可以限制某一个站点的 PHP-FPM 进程数量,避免一个网站无限扩张,把整个服务器的内存吃光。
这个改变对我来说,比所谓“跑分提高多少”重要得多。
因为服务器最重要的不是 Benchmark。
而是:
半夜没人管的时候,它别死。
六、Redis 和 FastCGI Cache 也按网站隔离
多站点还有一个问题:
缓存不能乱。
所以现在每个网站都有自己的:
- Redis DB
- Redis Prefix
- FastCGI Cache 目录
- 数据库账号
- 日志目录
- 备份目录
这样多个网站虽然运行在同一台 VPS 上,但尽可能减少彼此之间的影响。
架构大致可以理解成:
VPS
│
├── Nginx
│
├── MariaDB
│
├── Redis
│
├── PHP-FPM
│
├── site-a.com
│ ├── PHP-FPM Pool
│ ├── FastCGI Cache
│ ├── Redis DB
│ ├── Database
│ ├── Logs
│ └── Backup
│
├── site-b.com
│ ├── PHP-FPM Pool
│ ├── FastCGI Cache
│ ├── Redis DB
│ ├── Database
│ ├── Logs
│ └── Backup
│
└── site-c.com
└── ...
当然,这并不是真正意义上的容器级隔离。
所有网站依然共享同一台服务器。
但对于我这种自己管理几个 WordPress 独立站的使用场景来说,我觉得已经比较合适了。
七、后来我甚至给它写了一个 SSH Dashboard
这是我自己现在比较喜欢的一个功能。
直接运行:
sudo wp-shell dashboard
会进入一个类似 htop 的终端 Dashboard。
不是 Web 页面。
直接就在 SSH 里。
它会显示整台服务器的:
- CPU
- Load
- 内存
- 磁盘
以及每个 WordPress 网站的运行状态。
可以切换查看:
Overview
Traffic
Resources
Operations
Alerts
包括:
- 请求量
- HTTP 状态码
- P95 响应延迟
- FastCGI Cache 命中率
- PHP 内存
- 网站磁盘占用
- TLS 状态
- 备份状态
- PHP-FPM 异常
- 服务器资源状态
这样日常 SSH 登录服务器之后,我不需要先打一堆:
free -h
df -h
top
systemctl status nginx
systemctl status mariadb
systemctl status redis-server
再慢慢去翻 Nginx 日志。
先执行:
sudo wp-shell dashboard
大概就知道这台服务器现在是不是正常。
八、为什么我还加了 SQLite?
刚开始我只想看服务器的“现在”。
后来发现不够。
比如你现在看到:
内存使用率:65%
这实际上说明不了太多东西。
65% 到底正常不正常?
昨天是多少?
过去七天一直是 65%,还是今天突然从 30% 涨到了 65%?
PHP-FPM 有没有经常打满?
Redis 有没有发生淘汰?
MariaDB 有没有慢查询?
哪个网站的 P95 响应时间正在逐渐上升?
所以后来 wp-shell 加了一套本地指标采集。
每分钟采集一次服务器和站点状态,并保存在本机 SQLite 中。
这里我还是坚持了之前的思路:
能在服务器本地解决,就没必要再搞一套远程 SaaS。
对于大型系统,Prometheus + Grafana 肯定强得多。
但为了管理两三个 WordPress 网站,再搭一套 Prometheus、Grafana、Exporter……
我觉得又开始有点本末倒置了。
SQLite 对这个场景刚刚好。
轻量。
本地。
不需要额外开放端口。
也不需要再维护一个监控平台。
九、监控的目的不是看漂亮图表,而是回答“我应该怎么调”
这是后来我觉得比较重要的一次变化。
很多服务器监控工具会告诉你:
CPU 38%
Memory 71%
Load 1.2
然后呢?
对于普通 WordPress 用户来说,真正想知道的是:
我要不要调整?
所以现在 wp-shell 可以根据一段时间的历史数据,对资源使用情况进行分析。
例如观察:
- PHP-FPM 是否频繁达到
pm.max_children - PHP 实际内存使用
- MariaDB 慢查询
- Redis Eviction
- 系统内存压力
- Swap
- CPU Load
- 网站请求量
然后给出相对保守的资源调整建议。
注意,我这里故意用了:
“保守”
两个字。
因为自动调优最危险的事情,就是:
看见服务器还有 2GB 内存,就敢把这 2GB 全分出去。
Linux 本身要内存。
Nginx 要。
MariaDB 要。
Redis 要。
PHP-FPM 要。
系统 Page Cache 也要。
还必须留出突发流量和系统操作的余量。
所以我的思路一直不是:
把服务器性能压榨到 100%。
而是:
尽量找到性能、容量和稳定性之间比较安全的平衡点。
十、站点数量也不能再靠“感觉”
以前很多人问:
2 核 4G 能跑几个 WordPress?
这个问题其实根本没有标准答案。
一个纯博客和一个 WooCommerce 商城完全不是一回事。
一个 GeneratePress 搭的轻量网站,和装了几十个插件再套页面构建器的网站,也完全不是一回事。
但脚本至少需要设置一个安全边界。
所以目前 wp-shell 会根据物理内存,对默认站点数量做限制:
| VPS 内存 | 默认最大站点数 |
|---|---|
| 1GB–2GB | 1 个 |
| 2GB–4GB | 2 个 |
| 4GB–8GB | 4 个 |
| 8GB 以上 | 8 个 |
这里一定要强调:
这是安全上限,不是性能承诺。
不是说一台 4GB VPS 放两个 WooCommerce,就一定跑得飞起。
如果网站动态请求很多、插件很重、缓存命中率又低,实际容量会小得多。
但至少比:
“我感觉还能再塞一个。”
靠谱一点。
十一、备份这件事,我现在不敢再靠“记得”
服务器还有一个非常典型的问题:
大家都知道应该备份。
但最危险的一句话就是:
“我等会儿手动备份一下。”
然后就没有然后了。
所以现在安装 wp-shell 时,会同时建立 systemd Timer,自动执行备份和指标采集。
在主菜单里也可以直接:
Back up one website
Back up all websites
Restore a website
命令行同样可以直接操作:
sudo wp-shell backup 1
或者:
sudo wp-shell backup-all
不过这里我还是要提醒一句:
服务器本机备份不等于真正的备份。
如果 VPS 整块磁盘挂了,本机备份会跟网站一起消失。
所以真正重要的生产网站,我依然建议:
再把备份同步到对象存储、NAS 或另一台服务器。
这一点不能偷懒。
十二、我后来越来越重视“修复”,而不仅是“安装”
早期部署脚本有个很典型的思维:
Install
安装成功,任务结束。
但真正运行几个月之后,你就会发现:
服务器最常见的需求其实是:
Repair
Check
Restore
Migrate
Upgrade
所以现在主菜单里已经有:
Dashboard
Add a new website
Website list
Website status
Deploy or repair a website
Back up one website
Back up all websites
Restore a website
Import existing websites
Traffic and resource report
Analyze resource usage
Apply safe tuning recommendations
Reapply service resource budget
Security scan
Repair backup and metrics timers
这也是为什么我现在不太愿意把 wp-shell 叫做:
“WordPress 一键安装脚本”
因为安装已经只是它的一部分。
十三、安全方面,我现在反而比最初保守得多
脚本写得越多,我越觉得:
自动化最大的风险不是失败,而是“自动地做错”。
尤其涉及:
- Nginx 配置
- 数据库
- Redis 密码
- WordPress 配置
- 防火墙
- SSL
- 文件权限
任何一个地方处理不好,都可能不是某个功能坏掉,而是网站直接打不开。
所以现在很多操作都会先检查,再应用。
比如 Nginx 配置修改后必须经过:
nginx -t
验证。
验证失败就不能直接继续启用。
敏感配置文件使用 root 权限保护。
Redis 只监听本机 loopback,并启用认证。
脚本也增加了:
sudo wp-shell security-scan
来检查常见安全问题。
我甚至在开发过程中遇到过 Redis 密钥可能出现在 WP-CLI 输出日志里的问题。
发现之后,我专门增加了密钥轮换和日志脱敏逻辑。
这件事也让我越来越确定一个原则:
做服务器管理工具,功能多并不是最重要的,可恢复性和失败时不把服务器搞死才重要。
所以现在每增加一个功能,我首先考虑的已经不是:
“能不能实现?”
而是:
“如果执行到一半失败怎么办?”
十四、现在新建一台 WordPress VPS,其实还是很简单
虽然背后的东西已经比以前复杂了很多,但是使用方式反而应该越来越简单。
目前建议使用一台全新的:
Ubuntu 22.04 LTS
或者:
Ubuntu 24.04 LTS
VPS。
最低建议:
1GB RAM
8GB 可用磁盘
不过如果是真的生产网站,我个人还是更倾向从:
2 CPU
4GB RAM
这一档开始。
尤其一台 VPS 准备运行两个左右 WordPress 时,会舒服很多。
下载脚本:
wget https://raw.githubusercontent.com/hwc0212/wp-shell/main/wp-shell.sh
chmod +x wp-shell.sh
然后运行:
sudo ./wp-shell.sh
或者直接:
sudo ./wp-shell.sh install
脚本会先让你选择:
Single website
Multiple websites
然后选择 PHP 版本,并询问是否配置 UFW。
环境安装完成后,再运行:
sudo wp-shell
添加网站。
需要添加新站时也可以直接:
sudo wp-shell site add
后面 Nginx、PHP-FPM、MariaDB、Redis、Certbot、WP-CLI、Fail2ban、SQLite,以及备份和指标采集 Timer,都会由脚本统一管理。
十五、它和 Cloudways 到底有什么区别?
写到这里,我觉得反而可以重新回答几个月前那篇文章里的问题:
wp-shell 能不能替代 Cloudways?
我的答案现在比以前谨慎了一些。
对于所有人:
不能。
对于特定的一类人:
可以,而且我自己更喜欢这种方式。
如果你完全不想碰:
SSH
Linux
Nginx
PHP
MariaDB
那 Cloudways 这种托管平台明显更适合。
出了问题有人帮你处理。
所有操作都有漂亮的 Web UI。
你付的钱里面,本来就包含这些服务。
但如果你:
- 本来就会 SSH
- 能看懂一点 Linux 日志
- 自己管理 VPS
- 手里有多个 WordPress
- 不想安装宝塔
- 不想让管理面板长期占用服务器资源
- 希望自己控制 Nginx、PHP、数据库和缓存
那 wp-shell 的思路可能更适合。
Cloudways 是:
把 Linux 封装起来,让你尽量看不到服务器。
而 wp-shell 是:
服务器依然是你的 Linux,只是把重复运维工作自动化。
这是两个完全不同的方向。
十六、为什么我觉得它现在更像“没有 Web 面板的 Cloudways”
回过头看,现在 wp-shell 已经可以处理:
- VPS 环境部署
- WordPress 新建
- 已有网站导入
- 多网站管理
- PHP-FPM 隔离
- Redis 隔离
- FastCGI Cache
- HTTPS
- 自动备份
- 网站恢复
- SSH Dashboard
- 历史性能指标
- 流量报告
- P95 延迟
- 缓存命中率
- 资源分析
- PHP-FPM 调优
- 安全扫描
- 服务资源预算
- 旧版本迁移
这些事情,本来正是 Cloudways、SpinupWP 或各种服务器管理面板解决的问题。
区别只是:
wp-shell 没有 Web UI。
我反而越来越喜欢这种方式。
需要管理的时候:
ssh server
sudo wp-shell
管理完:
exit
结束。
服务器上没有一个专门为了“等我哪天登录看看”而一直运行的管理后台。
这大概就是我最开始写这个项目时想要的东西。
只是当时我自己也没完全想明白。
十七、从“10 分钟安装”,到“几年不用操心”
几个月前我写那篇 Cloudways 文章时,关注的是:
如何在 10 分钟里部署一个 WordPress。
现在继续写 wp-shell,我更关注的是另外一个问题:
这个 WordPress 能不能安安稳稳地跑几年?
这两者的难度完全不在一个级别。
安装环境,本质上就是:
apt install
+
写配置
+
启动服务
真正难的是:
随着流量变化,资源怎么调整?
多个网站怎么互相隔离?
服务器出现异常怎么发现?
备份坏了怎么知道?
配置修改失败怎么回滚?
旧版本怎么迁移?
代码更新后怎么保证以前的网站不会被搞坏?
密码有没有意外写进日志?
某个脚本执行一半失败,服务器会处于什么状态?
这些问题才是我现在花时间最多的地方。
所以 wp-shell 到今天已经完全不是我几个月前写文章时的那个脚本了。
十八、但我依然不准备把它做成“大而全”
虽然现在功能越来越多,但我还是给这个项目划了一条线。
我不准备给它加入:
- Web 后台
- 邮件服务器
- DNS 托管
- 文件管理器
- phpMyAdmin
- 在线代码编辑器
- 一堆和 WordPress 无关的服务器功能
因为这些东西一旦全部塞进去,最后又会变成另一个传统面板。
而我想保留的,还是最开始那个思路:
只解决 WordPress VPS 真正需要解决的问题。
简单不等于功能少。
我现在对“简单”的理解反而变成了:
用户需要做的事情简单,但脚本内部应该把复杂性处理掉。
如果为了让脚本代码看起来简单,最后把所有风险都扔给使用者,那不叫简单。
那叫没做完。
十九、谁适合用 wp-shell?
如果你只是第一次接触 WordPress,甚至不知道 SSH 是什么,我不建议从 wp-shell 开始。
直接买一台托管 WordPress 主机,可能省心得多。
但如果你和我一样:
自己有几个 WordPress 网站;
以前用过 Cloudways、宝塔或者其他面板;
会一点 Linux;
又不想花大量时间每天手工维护服务器;
那这个项目可能比较适合你。
尤其是:
外贸独立站。
这是我自己最主要的使用场景。
很多外贸网站的访问量并没有大到需要 Kubernetes,也不值得为了两个 WordPress 搭一整套复杂 DevOps 系统。
一台配置合理的 VPS:
Nginx
PHP-FPM
MariaDB
Redis
FastCGI Cache
Cloudflare
其实已经可以跑得非常好。
关键是:
配置合理,并且长期有人管。
如果“有人管”这件事情,可以交给脚本完成大部分重复工作,那就够了。
二十、写在最后:又一次重复造轮子
我的博客副标题一直是:
重复造轮子的魅力。。。
wp-shell 大概就是一个非常典型的例子。
这个世界当然不缺 WordPress 面板。
也不缺 VPS 管理工具。
更不缺 Cloudways 的替代品。
理论上讲,我完全没有必要再写一个。
但很多工具最后真正好不好用,并不取决于:
“市场上有没有同类产品。”
而是取决于:
它是不是刚好解决了自己的问题。
wp-shell 最开始只是因为我懒得每次重新配置一遍 WordPress 环境。
然后因为服务器内存爆过,我开始管 PHP-FPM。
因为多个网站放在一起,我开始做资源隔离。
因为不知道服务器过去发生了什么,我开始记录指标。
因为不想再搭监控平台,我用了 SQLite。
因为懒得每天检查,我写了 Dashboard。
因为担心备份忘掉,我加了 systemd Timer。
因为自动化越来越多,我又开始考虑失败回滚、安全检查和升级迁移。
结果一圈下来:
一个“一键安装 WordPress”的 Shell 脚本,就这么被我写成了现在这个样子。
以后应该还会继续改。
但方向已经比较明确:
不做 Web 面板。
不把 Linux 藏起来。
不追求什么都能管。
只把 WordPress VPS 上那些重复、容易出错、又不得不做的事情自动化。
如果你也喜欢自己折腾 VPS,可以试试看。
GitHub:
https://github.com/hwc0212/wp-shell
觉得有用的话,可以顺手点个 Star。
至于它以后会变成什么样……
我自己也挺好奇。
毕竟,重复造轮子这件事,一旦开始,好像就很难停下来。
