在 ct8.pl 部署 Node.js 网站的两种姿势与原理解析

想在 ct8.pl (以及它的孪生兄弟 Serv00) 这种免费空间跑 Node.js?很多新手卡在“明明进程跑起来了,但网页打不开”这件事上。其实这背后就是两种截然不同的流量转发逻辑。

姿势一:独立进程 + 反向代理 (The Proxy Way)

这是最灵活的方案。你通过 SSH 连上去,用 npm install -g pm2 搞个进程守护,让你的 App 监听在某个高位端口(比如 3000)。

底层原理:在这种模式下,你的 Node.js App 是一个完全独立的 OS 进程。但因为 80/443 端口被系统级的 Web 服务器(Apache/Nginx)把持,你没权限直接监听。所以你需要配置反向代理外部流量端口 80Web 服务器内部转发端口 3000你的 Node App

适用场景:需要长期运行的 WebSocket 服务、需要精细控制进程的复杂应用。

姿势二:Phusion Passenger (The Integrated Way)

这是 ct8.pl 控制面板里直接把网站类型选为 Node.js 时启用的模式。很多人第一步就踩坑:用 SSH 上传了一个 Express 项目,app.listen(3000),结果网页死活打不开。

底层原理:ct8.pl 选了 Node.js 后,Phusion Passenger 自动接管。Passenger 是一个嵌入 Web 服务器的应用容器,它并不是通过反向代理转发流量,而是直接在你域名被访问时 spawn 一个 Node 进程。关键区别来了——Passenger 会动态分配一个端口并通过 PORT 环境变量告知你的应用。如果你在代码里硬编码 app.listen(3000),你的应用确实跑在了 3000 上,但 Passenger 在等另一个端口,两者对不上,页面就一直是空白。

正确写法——不要写死端口,读取环境变量:

// 错误 ❌
app.listen(3000, () => console.log('Server running on 3000'));

// 正确 ✅
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server running on port ${port}`));

PORT 是 Passenger 注入的环境变量,值可能是某个随机高位端口(比如 54321)。带上 || 3000 是为了本地开发也能直接跑。同理,package.jsonmain 字段(或 scripts.start)需要指向你的入口文件,Passenger 通过这个字段找到启动点。

Passenger 额外贴心功能: - 按需启动:第一个请求到达时 Passenger 才 spawn 进程,空闲一段时间后自动杀掉省内存 - 自动重启:修改代码后 Passenger 会自动检测并重启(不用手动 kill) - 错误诊断页:如果你的 JS 启动就报错,Passenger 会展示诊断页面而不是 500 空页

适用场景:简单的 API、静态生成网站的后端、对内存占用敏感的小项目。适合”set and forget”的轻量服务。

怎么选?

  • 想要稳定性 → PM2 + 反向代理(进程一直活着,响应最快)。
  • 想要省心 → Passenger(面板点点就行,不用管 SSH 进程)。

总结:一个是“租个房间自己管”,一个是“住酒店由管家管”。

本文由 BOSH 的博客助手 HerMes 整理 🚀
原文链接:用户提供知识点科普