打开网易新闻 查看精彩图片

200MB的安装包,实际用到的功能不到10%。这是每个在Windows上搭过本地开发环境的程序员,都咽下去过的哑巴亏。

印尼开发者Taqin三个月前算了笔账:XAMPP下载包200MB,装完更大,但他只用到Apache+MariaDB+PHP+phpMyAdmin。PHP 8.5.0发布四个月后,XAMPP才跟进。Apache崩溃时控制面板直接卡死,因为pid文件没清理。

他决定自己写一个。周末开工,纯Go语言,最终成品7MB。

「我要的是包管理器,不是安装器」

「我要的是包管理器,不是安装器」

Taqin的设计哲学很直白:控制面板本身要极小,服务按需下载、本地缓存,从不捆绑用不到的东西。GoAMPP的核心是一个单二进制文件,编译时加上-ldflags="-H windowsgui -s -w",去掉控制台窗口,剥离调试符号,压到7MB。

GUI没选Electron,没用Webview,甚至没碰CGO。他用了windigo——一个纯Go的Win32控件绑定库。按钮、进度条、日志框,全是原生Windows组件。

二进制内部嵌着一个DownloadCatalog,按服务名索引。每个条目包含下载URL、安装目录、可选的StripTop字段(用于处理顶层套娃的压缩包),以及PostInstall钩子。Apache的条目长这样:

版本号精确到编译器版本,URL指向ApacheLounge的VS18构建,PostInstall负责改SRVROOT、ServerName、开mod_cgi。

点击Start时,如果二进制文件不存在,流程自动触发:查目录→开goroutine保UI响应→流式下载到.part文件→原子重命名→解压到bin/目录。zip-slip防护是硬编码的:任何解析后逃出目标路径的条目,直接拒绝。

进度条30Hz刷新,日志1Hz。因为多行Edit控件的WM_SETTEXT每写一行都是完整往返,写太频繁会卡。

那个吃掉一整晚的Apache bug

那个吃掉一整晚的Apache bug

Taqin在复盘帖里专门留了一节讲这个。Apache httpd的Windows版本有个历史包袱:默认配置里SRVROOT写死成解压时的绝对路径,ServerName没设,mod_cgi默认关闭。他的PostInstall钩子得逐行扫描httpd.conf,正则替换这三处。

更隐蔽的是pid文件问题。Apache崩溃时.pid文件残留,下次启动会报"already running"。XAMPP控制面板在这里会挂死,因为没做超时处理。Taqin的解法:启动前强制删.pid,启动后轮询检测端口而不是解析pid文件。

「Win32的CreateProcess和Unix的fork+exec完全是两种生物。」他在帖子里写。Go的os/exec包在Windows下会隐式创建控制台窗口,即使父进程是windowsgui。得显式设置SysProcAttr.HideWindow,或者直接用syscall.CreateProcess。

MariaDB的坑在初始化。mariadb-install-db.exe第一次运行要弹控制台窗口,即使主程序是GUI。Taqin最后用了条件编译:Windows下单独一个包处理这类需要短暂暴露控制台的子进程。

 seventeen个脚手架,四个运行时

seventeen个脚手架,四个运行时

GoAMPP的服务清单比XAMPP长得多。Apache/Nginx二选一,MariaDB/PostgreSQL二选一,Redis、PHP、phpMyAdmin、Adminer。语言运行时四个:Node.js、Python、Go、Java。

脚手架是Taqin后来加的。十七个框架的初始化模板:Express、Django、Flask、Laravel、Spring Boot……选完技术栈,点Scaffold,自动下运行时、配虚拟主机、写环境变量。

缓存机制是懒加载+永久保留。第一次下载的PHP压缩包存在downloads/,下次切版本时直接解压。Taqin的版本切换设计:bin/php/8.3.6/和bin/php/8.4.0/并存,改个软链接就能切,但Windows软链接需要管理员权限,最后用了junction点。

体积对比很刺眼。GoAMPP本体7MB,首次启动后按需下载,典型配置(Apache+MariaDB+PHP+phpMyAdmin)全部缓存完约150MB。XAMPP安装包200MB起步,且每次大版本得全量重装。

「没有Docker,没有WSL」

「没有Docker,没有WSL」

这个副标题是Taqin刻意强调的。他的目标用户很明确:公司电脑锁了Hyper-V、Docker Desktop装不上、WSL2需要BIOS开虚拟化但IT部门不给权限的Windows开发者。

纯原生Win32的二进制,意味着不需要任何容器层。Apache跑在Windows服务管理器里,PHP是原生DLL,MariaDB用Windows命名管道通信。性能损耗为零,调试时用Process Monitor能看到完整的系统调用链。

代价也有。windigo的文档稀少,Taqin翻了不少Win32 API原始文档。ProgressBar的平滑动画要自己算增量,因为原生控件不支持中间值。右键菜单、托盘图标、单实例限制(用mutex实现),这些Electron里一行配置的事,这里要调几十个API。

但启动速度是真实的。Taqin录了对比视频:GoAMPP冷启动到控制面板可用,0.3秒。XAMPP控制面板需要加载Perl运行时,2秒以上。Laragon更慢,因为它要先初始化Cmder和Telegram通知器。

GitHub仓库开源后,一周收了400星。Issues里最常见的请求是加MySQL 8.0支持、加Caddy替代Nginx、加Ruby运行时。Taqin的回复很克制:「MySQL 8.0的zip包结构变了,得改StripTop逻辑。Caddy是单二进制,可能直接内置。Ruby在考虑,但体积太大。」

有个用户反馈让他改了设计。最初版本所有服务共享一个日志框,Apache和MariaDB的输出混在一起。后来改成每个服务独立标签页,但底层还是单goroutine轮询,因为windigo的Edit控件线程不安全,得串行更新。

项目README的最后一段,Taqin写了用途声明:「不是生产环境工具,是开发机上的沙盒。别用它托管正式站点,SSL证书管理、日志轮转、自动备份这些都没做。」

但已经有用户在Issue里贴图:用GoAMPP跑起来的本地WordPress,配合Tailscale内网穿透,给甲方做预览。Taqin没阻止,只是回了句:「记得关debug模式,phpMyAdmin默认没密码。」

下一个周末他打算加什么功能?