宝塔面板中php与node.js不能共用同一端口混跑,但可通过反向代理协同:php处理传统逻辑,node.js独立运行并由nginx将/api/等路径代理至其服务,需用pm2守护、监听0.0.0.0:3000、避免端口冲突及权限问题。

宝塔面板的 PHP 环境和 Node.js 不能“共用同一个网站端口直接混跑”,但可以共存并协同工作——关键在于明确分工:PHP 处理传统后端逻辑(如 WordPress、ThinkPHP),Node.js 单独运行服务(如 WebSocket、实时接口、前端构建服务),再通过反向代理或 API 调用打通。
Node.js 服务必须独立启动,不能挂载在 PHP 进程里
宝塔的 PHP 管理器只管 php-fpm 和 nginx/apache 的 PHP 模块,对 Node.js 完全无感知。你写的 app.js 不会因为开了 PHP 就自动运行,必须手动启动并守护。
- 用
pm2 start app.js --name my-api启动(推荐,支持自动重启、日志查看) - 不要用
node app.js前台运行——关闭 SSH 就退出 - 确保 Node.js 已通过宝塔「软件商店」安装(v14+ 更稳妥),且
node -v和pm2 -v在终端能正常输出 - 检查应用监听地址:务必设为
0.0.0.0:3000或127.0.0.1:3000,不能是localhost:3000(部分环境解析异常)
让 Nginx 把特定路径反向代理给 Node.js
这是最常用也最安全的混合方式:PHP 网站照常访问,但 /api/ 或 /ws/ 这类路径由 Nginx 转发到本地 Node.js 服务,用户无感。
- 进宝塔 → 网站 → 对应站点 → 「配置文件」→ 在
server块内插入:
location ^~ /api/ {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
-
^~表示前缀匹配且优先级高于正则,避免被 PHP 的try_files拦截 - 结尾的
/很关键:proxy_pass http://127.0.0.1:3000/;会把/api/user映射为/user;漏掉斜杠就会变成/api/user→/api/user,大概率 404 - 改完点「保存」,再点「重载配置」,不要只重启 Nginx
PHP 调用 Node.js 接口时要注意跨域和超时
如果 PHP 代码里用 file_get_contents() 或 cURL 主动请求本地 Node.js(比如 http://127.0.0.1:3000/data),不是反向代理,那得自己处理细节:
立即学习“PHP免费学习笔记(深入)”;
- Node.js 服务需显式允许来源,例如 Express 中加:
app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); next(); }); - PHP cURL 请求要设超时,Node.js 启动慢或卡住时,
curl_setopt($ch, CURLOPT_TIMEOUT, 5)防止 PHP 页面假死 - 避免在 PHP 每次请求中都新建连接——可复用 cURL handler,或改用连接池(如 Swoole + HTTP client)
- 生产环境慎用
file_get_contents('http://...'),它不支持 POST body、Header 控制弱,出错难调试
真正容易被忽略的是端口冲突和权限隔离:Node.js 应用别监听 80/443(会被 Nginx 抢占),也别用 root 启动;pm2 要用网站运行用户(如 www)启动,否则可能读不到 PHP 写的缓存文件或写不了日志目录。











