Astro Node 端口被占用却退出 0:核对启动失败处理
standalone 服务没有监听,也没有 EADDRINUSE 日志,进程却成功退出。检查适配器版本,分别验证端口冲突和正常启动。
运行 Astro 的 Node standalone 产物后,进程立即以 0 退出,既没有监听提示,也没有 EADDRINUSE;实际端口却正被其他进程占用。进程管理器可能把它视为正常结束,需要同时核对适配器的启动失败处理和真实监听状态。
这条明确场景包含 @astrojs/node 11.1.6、Astro 7.3.5;11.1.7 也有相同路径。当前正式适配器 11.1.9 已在自动启动处捕获 done 拒绝、输出错误并以非零结束。采用更早版本时,需核对其自动启动分支是否同样捕获 done 失败。
监听失败的 Promise 没有被正确接住
旧 standalone 把 HTTP server 的 error 事件转成 closed Promise 的拒绝,并作为 done 返回;自动启动入口却没有处理这个结果。进程里另有 unhandledRejection 监听器,启动时又没有请求上下文,便可能直接略过错误,失去 Node 默认的未处理拒绝行为。
服务器没有成功建立监听句柄,事件循环耗尽后就会自然结束。给入口再加一个空的 rejection 日志监听器,或套一层永不结束的 Promise,都不会让端口变得可用,反而可能继续改变退出语义。
先确认配置是 standalone,并核对 HOST、PORT 及实际执行的构建产物。middleware 模式由宿主服务器负责监听,不能套用这条自动启动路径。也不要看到端口占用就自动结束占用者,它可能是仍需保留的正常服务。
更新适配器后重新构建
按 Astro 与项目支持范围采用包含修正的适配器,例如已核对的正式 11.1.9,重新生成服务端产物。只更新开发依赖而继续启动旧 dist,并不会改变已打包的启动代码。
项目若显式设置 ASTRO_NODE_AUTOSTART=disabled、自己调用导出的 startServer(),应由自己的入口处理它返回的 done,而不能期待自动启动分支代劳。应按原进程管理规则记录失败并保留非零状态,不能把它接成只打印后成功退出。
端口确实需要调整时,在已批准的部署配置中统一修改监听端口和反向代理或健康检查目标。不要为了启动成功临时随机换端口,却仍让流量指向旧位置。
验收在隔离环境准备一组可控端口:空闲时服务应持续监听并可接受请求;被测试占用者占用时,新进程应报告错误并非零退出。随后释放测试占用者,再确认正常启动。检查实际监听者的身份,避免请求恰好命中了占用端口的旧进程,从而把新进程失败误判成部署成功。


