You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一VPS中两个Node.js应用.env配置串用,数据库连接错误求助

问题排查与解决方案

一、先排查核心:.env文件加载异常(最可能的根源)

你的问题是prod应用连接到dev数据库,这和Apache反向代理的端口冲突无关(代理只处理外部请求转发,不影响应用内部的数据库连接),优先从环境变量加载环节入手:

1. 验证.env文件的加载路径与优先级

  • Node.js的dotenv默认加载当前工作目录下的.env文件,PM2启动时如果未指定工作目录,可能会使用PM2的默认工作目录(而非应用目录)。
    • 执行pm2 show <prod-app-name>,查看输出中的cwd字段,确认是否为prod应用的根目录;dev应用同理检查。
    • 如果工作目录不对,在PM2启动时指定--cwd参数,比如:pm2 start index.js --name prod --cwd /path/to/prod-app。
  • 检查PM2配置文件(如ecosystem.config.js),是否存在env字段覆盖了数据库凭证——PM2配置的环境变量优先级高于.env文件。

2. 确认代码中.env的加载时机

确保require('dotenv').config()在数据库连接初始化代码之前执行,否则会导致数据库连接读取不到正确的.env变量。可以在prod代码中添加日志验证:

require('dotenv').config();
console.log('Prod DB Name:', process.env.DB_NAME); // 启动后查看日志是否为prod的数据库名

3. 排除手动启动与PM2启动的差异

手动在prod目录下执行node index.js,观察是否仍连接到dev数据库:

  • 如果手动启动正常,说明是PM2的工作目录或配置问题;
  • 如果手动启动也异常,检查prod目录下的.env是否被误替换为dev的内容,或者代码中存在硬编码的数据库配置。

二、Apache反向代理与端口冲突的排查(次要但需确认)

如果两个Node应用监听同一端口,会导致后启动的应用无法绑定端口(报错EADDRINUSE),但你描述dev启动后prod仍能运行,说明端口大概率不冲突,但仍需验证:

1. 确认两个应用的监听端口

检查prod和dev的代码,确保监听端口不同:

// prod应用
app.listen(3000, () => console.log('Prod running on port 3000'));

// dev应用
app.listen(3001, () => console.log('Dev running on port 3001'));

执行netstat -tulpn | grep node,查看Node进程占用的端口,确认两个应用端口无重叠。

2. 修正Apache反向代理配置

复制prod配置后必须修改代理目标端口,确保子域名对应正确的Node应用:

# prod的虚拟主机配置
<VirtualHost *:80>
    ServerName your-domain.com
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

# dev的虚拟主机配置
<VirtualHost *:80>
    ServerName dev.your-domain.com
    ProxyPass / http://localhost:3001/
    ProxyPassReverse / http://localhost:3001/
</VirtualHost>

修改后重启Apache:systemctl restart apache2

三、数据库层面验证(兜底排查)

开启数据库的通用日志(如MySQL的general_log),查看prod应用进程对应的连接请求,确认是应用端传入了错误的数据库凭证,还是数据库配置本身有问题。


内容的提问来源于stack exchange,提问作者Tata Volador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:45:34