前段时间,我陆续记录了几次 OneinStack 生产环境中的组件升级、兼容性处理和配置审计。
这些工作最初都来自实际服务器上的具体需求。
例如,将 PHP 升级到 8.5 以后,需要继续处理 Phar、GNU libiconv、Imagick 等兼容问题;升级 Nginx 时,又涉及 OpenSSL 版本、源码来源以及编译后的实际验证;再往后,还对 PHP-FPM、OPcache、Redis、RDS 等配置进行了一轮整体审计。
随着这些调整逐渐稳定,我后来又把同一套 OneinStack 定制基线应用到了另一台不运行 WordPress 的 Nginx 代理服务器上。
到了这一步,我觉得已经没有必要继续让这些修改只存在于自己的本地仓库和零散博客记录中了。
所以这一次,我把目前真正已经进入代码、并经过实际生产环境使用验证的部分重新整理了一遍,正式公开到了 GitHub:
GitHub:shuijingwan/oneinstack-custom
https://github.com/shuijingwan/oneinstack-custom
如果以后还有类似的 OneinStack 生产环境维护需求,我也准备继续在这个仓库中维护相关修改。

一、这个项目并不是重新写一套 OneinStack
在正式公开仓库之前,我首先需要重新回答一个问题:
这个项目究竟是什么?
如果只看之前的一系列服务器维护记录,很容易把它理解成一个服务器优化工具集。
如果只看最初出现问题的使用环境,又可能把它理解成 WordPress 运维项目。
但重新对照当前代码、Git 历史以及 OneinStack 上游以后,这两种说法都不够准确。
目前更准确的定位是:
面向长期运行生产服务器的 OneinStack 定制分支,在保留上游运维方式的基础上,补充 PHP 8.5 兼容构建与 Nginx/OpenSSL 更新。
也就是说,这个仓库首先仍然是建立在 OneinStack 上的。
它并不准备重新实现 OneinStack 已经做得很成熟的事情。
OneinStack 本身已经提供了很多完整能力,例如:
- Nginx、Tengine、OpenResty、PHP、数据库、Redis 等组件安装;
install.sh安装流程;upgrade.sh组件升级;vhost.sh;- HTTPS 与证书管理;
- 服务配置与管理;
- 备份;
- PHP 扩展;
- PHP-FPM;
- OPcache;
- PHP 8.5 基础支持。
因此,我没有必要脱离 OneinStack,再重新维护一套完全不同的服务器管理体系。
这个定制分支仍然尽量保持 OneinStack 原有的目录结构、脚本入口以及日常管理方式。
只有在长期生产环境中真正遇到具体问题以后,才对对应位置进行增量修改。

二、这些修改最初来自真实的生产环境问题
这个仓库不是先想好一堆“功能”,然后再寻找应用场景。
实际过程恰好相反。
很多修改都是在维护已经运行多年的生产服务器时,一点一点积累出来的。
此前已经记录过几次比较重要的过程。
第一部分,是 PHP 8.5 升级以及随后出现的一系列兼容问题:
OneinStack 生产环境升级 PHP 8.5 的相关记录
第二部分,是 Nginx 和 OpenSSL 的升级:
阿里云 OneinStack 环境中的 Nginx/OpenSSL 升级记录
第三部分,是 Redis 升级,以及围绕生产环境增加的备份、验证和回滚保护:
之后,我又对 PHP-FPM、OPcache、Redis、RDS 等实际运行配置做了一轮整体审计:
PHP-FPM、OPcache、Redis、RDS 等服务器配置全面审计
后来,这套 OneinStack 定制基线又被应用到了一台并不运行 WordPress 的 Nginx 代理节点上:
这一步也进一步说明了一件事:
WordPress 是很多问题最初暴露出来的生产负载,但不是这个仓库的边界。
真正被修改和维护的,是下面这些更加基础的环境:
OneinStack、Linux、PHP、PHP-FPM、Nginx、OpenSSL,以及长期生产服务器中的组件升级和兼容性问题。
三、OneinStack 原生方案与这个定制分支有什么区别
这一次整理公开仓库时,我专门重新对照了一遍 OneinStack 当前的官方实现。
这样做很有必要。
因为随着 OneinStack 自身继续发展,一些以前需要自己处理的问题,后来可能已经被上游支持。
如果不重新对照,很容易把 OneinStack 已经具备的能力误写成自己的功能。
最终 README 中也专门增加了一张对比表。

目前比较明确的关系是:
环境安装和日常管理
OneinStack 已经负责 Nginx、Tengine、OpenResty、PHP、数据库、Redis、虚拟主机、证书、备份以及常见组件升级。
这个分支没有重新实现这些能力。
主要还是继续使用已有的 OneinStack 运维方式。
PHP 8.5
OneinStack 当前已经有 PHP 8.5 基础支持。
所以这个仓库并不能简单描述成“让 OneinStack 支持 PHP 8.5”。
真正增加的是我在实际生产环境升级 PHP 8.5.9 时遇到的一些更具体的兼容处理和验证逻辑。
Imagick
OneinStack 已经针对 PHP 8.5 提供专门的 Imagick 版本选择。
当前定制分支进一步固定到了实际验证过的 Imagick 3.8.1。
PHP-FPM 与 OPcache
OneinStack 本身已经可以生成和管理相关配置。
这个分支进一步增加了已经验证过的配置基线,并且在安装完成以后明确检查 PHP-FPM 配置和服务状态。
Nginx/OpenSSL
OneinStack 本身支持使用配置好的 OpenSSL 源码构建 Nginx、Tengine 和 OpenResty。
当前分支则将相关构建链固定到 OpenSSL 3.5.7,并调整安装与升级路径,从 OpenSSL 官方来源获取源码。
所以这个项目真正要做的,并不是:
“OneinStack 没有这些功能,所以我重新实现。”
而更接近:
“OneinStack 已经解决了基础问题,我把长期生产环境中进一步遇到的具体问题继续固化到这个分支。”
四、PHP 8.5 的修改并不只是改一个版本号
这一点也是我认为有必要公开代码的原因之一。
如果只看博客,很容易觉得:
PHP 8.5.9、Imagick 3.8.1、OpenSSL 3.5.7,无非就是把几个版本号修改一下。
实际并不是这样。
在 PHP 8.5 的实际构建过程中,我遇到过 GNU libiconv 头文件冲突的问题。
最终进入仓库的处理方式,是在构建前识别:
/usr/local/include/iconv.h
如果存在冲突,则临时移动这个文件。
同时又不能只简单地 mv 一次就结束。
因为如果中途编译失败、脚本退出或者收到终止信号,原有文件仍然应该恢复。
因此现在脚本中增加了恢复函数,并通过 trap 处理:
EXITINTTERMHUP
这样即使构建过程异常结束,也尽量确保原来的 iconv.h 被恢复。

PHP-FPM 的处理也是类似。
脚本不会只执行启动操作,然后默认认为一切正常。
现在会继续检查:
- PHP-FPM 是否能够正常重启;
- 服务是否处于 active 状态;
- 出错时明确退出,而不是继续把整个安装流程报告为成功。
目前进入仓库并固定下来的几个关键版本包括:
- PHP 8.5.9;
- Imagick 3.8.1;
- OpenSSL 3.5.7。
这些都不是为了单纯追逐新版本,而是当前生产环境中实际使用和验证过的组合。
五、博客里做过的事情,不等于仓库已经全部自动化
这次公开仓库时,我觉得另一个很重要的原则,就是必须把这两件事情分开:
实际运维过程中做过什么;
以及:
GitHub 仓库当前真正实现了什么。
两者并不完全相同。
比如此前 Redis 升级过程中,我实际做过:
- 多层备份;
- 回滚准备;
- 内核参数调整;
- 临时端口测试;
- 升级后的状态确认。
但这些流程目前并没有完整自动化进入 oneinstack-custom。
类似的还有:
- Nginx 完整旁路构建和自动回滚;
- 独立的配置审计命令;
- PHP-FPM、Redis、RDS 的动态调参;
- WordPress、REST API、缓存等应用层验收;
- Go Playground 代理;
- CORS;
- 8443;
- 证书部署。
这些都是以前实际做过的工作,但不能因为博客中记录过,就直接把它们写成 GitHub 仓库已经提供的功能。
所以 README 中也专门保留了这个边界。
例如 Redis 一项明确写着:
当前没有增加回滚自动化或独立配置审计命令。
我觉得这种区分反而比较重要。
公开仓库以后,别人真正关心的是:
下载当前代码以后,它现在到底能够做什么。
而不是我过去曾经人工完成过多少事情。
六、配置优化并不是“参数越大越好”
前面的配置审计也对这个仓库后续的维护方向产生了影响。
服务器优化很容易变成一种“套参数”的过程。
网上经常能看到各种所谓:
- Nginx 最佳参数;
- PHP-FPM 最佳参数;
- Redis 最佳配置;
- OPcache 最佳配置;
- 数据库最佳配置。
但真实生产环境并不存在一套所有服务器都适用的固定参数。
机器内存不同、CPU 不同、访问量不同、应用类型不同、缓存结构不同,最终合适的参数自然也不同。
在前面的实际审计中,有些参数最后确实进行了调整。
但也有很多参数,在结合服务器资源、日志和真实运行状态以后,最终选择了:
保持不动。
所以如果以后继续扩展这个仓库,我更希望坚持这样的方向:
只有真实问题和实际证据能够支持的修改,才进入定制分支。
而不是单纯为了让 README 中看起来拥有更多“优化项目”,就增加大量未经验证的所谓最佳参数。
七、为什么继续保持 OneinStack 原有运维方式
既然已经做了自己的定制分支,还有一个问题:
为什么不干脆把各种流程都重新写一遍?
一个很现实的原因是,OneinStack 已经运行多年,本身积累了大量成熟的安装与管理逻辑。
在自己的生产环境中,我也已经长期习惯了它的目录和管理方式。
因此,目前的原则仍然是:
凡是 OneinStack 已经提供官方脚本或者原生管理流程的操作,优先继续使用原有方案。
只有原有流程确实无法完整覆盖实际需求时,才增加额外处理。
这也意味着后续同步 OneinStack 上游更新时,不能简单地直接覆盖。
当前仓库采用的上游基线是 OneinStack 提交:
42d59b3
这个仓库也不是一个自动追踪上游的镜像。
今后如果 OneinStack 有新的提交需要同步,仍然应该先阅读差异,再有意识地合并。
README 中也专门增加了一个比较重要的警告:
./upgrade.sh --oneinstack
会使用上游发布包覆盖当前定制分支,因此不能把它当成普通的组件升级命令随意执行。
对于一个存在本地定制的 OneinStack 环境来说,这一点还是比较重要的。
八、公开 GitHub 前又做了一轮完整检查
既然准备把仓库公开,就不能只是执行一次 git push。
这次在正式发布之前,又重新检查了:
- README;
- 中文 README;
- Git 历史;
- 当前工作树;
.gitignore;- License;
- 脚本语法;
- 外部链接;
- 认证凭据;
- 历史提交中的高风险信息。
这次检查没有发现真实密码、Token、API Key、私钥、Bearer Token 或其他认证 Secret。
同时也补充了 .gitignore,避免以后实际生产运行过程中生成的一些敏感文件被意外提交。
这里比较值得注意的是:
tools/iplist.txt
在远程备份流程中可能保存远端主机密码,所以已经明确加入忽略列表。
仓库仍然继续使用原有的 Apache License 2.0。
九、110 个 Shell 脚本和入口全部通过语法检查
这个仓库本身没有独立测试套件,也没有额外的 lint 配置。
所以这次公开前,至少对当前所有 Shell 脚本和入口重新执行了一轮 Bash 语法检查。
仓库当前包含:
- 109 个
.sh文件; - 1 个没有
.sh后缀、但实际属于 Shell 入口的init.d/Tomcat-init。
合计 110 个 Shell 脚本/入口。
最终全部通过:
bash -n
检查。

本轮公开整理最终包含两个提交:
55de35b
chore: 完成 OneinStack 定制分支公开整理
以及:
cb6f0dc
chore: 忽略备份流程运行时敏感文件
最终 HEAD:
cb6f0dc11881b15c76ef821be8303adef8c88ada
本地状态为:
## main...origin/main
也就是说,本地 main 与 GitHub origin/main 已经保持一致,工作树干净。
十、为什么现在把它公开出来
从我自己的角度来说,这个仓库以后首先还是服务于自己的生产服务器。
但是既然很多问题都是 OneinStack 用户在长期维护服务器以后可能碰到的问题,那么继续只保存在本地,价值就比较有限了。
尤其是 PHP、Nginx、OpenSSL 这类基础组件不断更新以后,一些原来没有问题的构建流程,几年以后可能就会出现新的兼容边界。
公开到 GitHub 以后,至少可以让这些修改:
- 有完整 Git 历史;
- 可以查看具体 diff;
- 可以和 OneinStack 上游持续比较;
- 可以通过 Issue 记录问题;
- 可以接受不同环境下的兼容性反馈;
- 可以逐步把真正稳定的人工运维过程继续固化进代码。
对于有类似 OneinStack 长期生产环境维护需求的读者,如果当前仓库中的处理方式有参考价值,可以在 GitHub 上 Star 收藏。
这样以后需要重新查找这些修改,或者关注后续更新时,也会更方便。
仓库地址:
https://github.com/shuijingwan/oneinstack-custom
十一、后续还会继续做什么
目前我并不准备为了让仓库“功能更多”,就马上把过去所有人工操作全部脚本化。
下一步更可能继续沿用现在的原则:
实际使用 → 发现问题 → 完成验证 → 确认方案稳定 → 再决定是否进入仓库。
例如 Redis 的升级、备份与回滚流程,以后如果真正形成足够稳定和通用的自动化方案,再考虑进入这个分支。
配置审计也是一样。
相比直接增加一大堆所谓优化参数,我更希望以后能够逐步沉淀出:
- 为什么检查;
- 根据什么判断;
- 什么情况下应该修改;
- 什么情况下反而不应该修改;
- 修改以后怎样验证;
- 出问题以后怎样恢复。
这样,这个仓库才不会慢慢变成另一套难以维护的“魔改版安装脚本”。
它更适合作为一个:
长期跟随真实生产需求演进的 OneinStack 定制分支。
这也是这次决定把 oneinstack-custom 正式公开到 GitHub 的主要原因。
需要长期技术维护或远程问题排查?
我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。
如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:
- ✅ PHP / Laravel / Yii2 老项目无人维护
- ✅ Go / Gin 后端接口需要排查或优化
- ✅ WordPress 网站访问慢、报错或插件冲突
- ✅ Nginx / MySQL / Redis / Linux 服务器异常
- ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
- ✅ 需要长期远程技术支持或兼职维护
更多介绍请查看:关于我 & 合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan


发表回复