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

明明配置端口5001,PM2却强制Node.js使用5000端口

问题:PM2强制绑定5000端口而非指定的5001端口?

我正在使用PM2运行一个基于Express和MongoDB的Node.js应用,已将应用配置为使用5001端口,但即便明确设置端口为5001,PM2仍将应用绑定到5000端口。

应用代码

const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');

// Initialize app
const app = express();

// Middleware to parse JSON
app.use(express.json());

// Environment variables
dotenv.config();

// MongoDB Connection
mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/devtrust', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
.then(() => console.log('Connected to MongoDB'))
.catch((err) => console.error('MongoDB connection error:', err));

// User model
const User = mongoose.model('User', new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true }
}));

// Signup route (create user)
app.post('/api/signup', async (req, res) => {
  try {
    const { email, password } = req.body;
    // Input validation
    if (!email || !password) {
      return res.status(400).json({ error: 'Email and password are required' });
    }

    // Check if user already exists
    const existingUser = await User.findOne({ email });
    if (existingUser) return res.status(400).json({ error: 'User already exists' });

    // Hash the password
    const hashedPassword = await bcrypt.hash(password, 10);

    // Save the user
    const user = new User({ email, password: hashedPassword });
    await user.save();
    res.status(201).json({ message: 'User created successfully' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Error creating user', error: err.message });
  }
});

// Login route (authenticate user)
app.post('/api/login', async (req, res) => {
  try {
    const { email, password } = req.body;

    // Input validation
    if (!email || !password) {
      return res.status(400).json({ error: 'Email and password are required' });
    }

    const user = await User.findOne({ email });
    if (!user) return res.status(400).json({ error: 'Invalid credentials' });

    // Compare passwords
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) return res.status(400).json({ error: 'Invalid credentials' });

    // Generate JWT token
    const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
    res.json({ token });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Error logging in', error: err.message });
  }
});

// Test route to verify the server is running
app.get('/test', (req, res) => {
  res.json({ message: 'Server is working' });
});

// Start server
const PORT = process.env.PORT || 5001;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

已执行的操作

  • 在.env文件和server.js中明确设置PORT环境变量为5001;
  • 使用命令PORT=5001 pm2 start server.js --name devtrust-backend -f启动服务;
  • 确认服务器仍监听5000端口而非5001。

已尝试的解决方法

  • 执行pm2 stop all和pm2 delete all停止并删除PM2进程后,重新用PORT=5001 pm2 start server.js启动;
  • 检查是否有其他进程占用5000端口并通过lsof -i :5000和kill -9 <PID>杀死该进程;
  • 通过pm2 logs devtrust-backend查看日志,仍显示服务器运行在5000端口;
  • 在server.js中打印端口以验证实际使用的端口。

原因分析

  1. PM2环境变量缓存:PM2会缓存进程启动时的环境变量,即便命令行传入新的PORT值,旧的缓存值(如之前使用的5000)仍可能生效。
  2. .env文件加载问题:若.env文件路径不正确,或PM2启动时的环境变量优先级高于.env,会导致代码读取到错误的PORT值。
  3. PM2配置文件冲突:如果之前创建过ecosystem.config.js配置文件,其中若指定了PORT=5000,会覆盖命令行传入的参数。

解决方案

方法1:彻底清除PM2缓存并重启

pm2 delete all
pm2 flush  # 清空日志及缓存
PORT=5001 pm2 start server.js --name devtrust-backend

方法2:确保代码正确读取环境变量

修改代码,明确指定.env文件路径,并打印PORT值验证:

// 明确指定.env文件路径,避免加载失败
dotenv.config({ path: './.env' });

// 优先使用命令行传入的PORT,其次是.env,最后 fallback 到5001
const PORT = process.env.PORT || 5001;
console.log('实际使用端口:', PORT); // 打印确认
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

方法3:使用PM2配置文件(推荐)

创建ecosystem.config.js,统一管理环境变量:

module.exports = {
  apps : [{
    name: 'devtrust-backend',
    script: 'server.js',
    env: {
      NODE_ENV: 'development',
      PORT: 5001
    },
    env_production: {
      NODE_ENV: 'production',
      PORT: 5001
    }
  }]
};

启动命令:

pm2 start ecosystem.config.js

方法4:验证环境变量是否正确传入

先在终端测试环境变量是否生效:

PORT=5001 node -e "console.log(process.env.PORT)"

若输出5001,说明环境变量没问题,问题出在PM2缓存;若输出异常,检查.env文件内容或是否有其他地方覆盖了PORT。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:22:05