第一个nodejs项目上线的经验


码海无涯系列,写给自己的注释

第一部分

首先在服务器上安装nodejs。

建立一个 Node.js 服务端:
在网站文件夹下 上传server.js文件
server.js例子:

const express = require("express");
const { exec } = require("child_process");

const app = express();
const port = 9999; // 可以改

// 一个API,当用户点击时访问
app.get("/run", (req, res) => {
  exec("node w.js", (error, stdout, stderr) => {
    if (error) {
      console.error(`执行出错: ${error}`);
      return res.status(500).send("执行出错");
    }
    res.send(`<pre>${stdout}</pre>`); // 把执行结果返回网页
  });
});

app.listen(port, () => {
  console.log(`服务运行在 http://localhost:${port}`);
});

在nginx中,设置反向代理到node

location /run {
    proxy_pass http://127.0.0.1:9999; # 转发到 Node 服务
}
出现问题
cannot found module:

权限错误:途中使用了 sudo 导致文件夹的用户全部变为 root 而不是 aaa
sudo 直装 node,导致 node 只为 root 所有,依赖库也只能为 root 所用,使用 aaa,或 www 用户无法调用依赖库
使用pm2守护进程时,调用依赖库直接报找不到模块
多次安装依赖库后仍然徒劳

解决办法:

卸载干净 nodejs

按照nodejs官网文档,使用 nvm with npm,安装了 node 22版本

下面是一些途中可能用到的命令:

pm2 命令

启动服务:
pm2 start 你的文件名.js(该命令要在“你的文件名.js”所在目录运行)

保存当前 pm2 的进程列表,确保重启服务器后还能恢复:
pm2 save

让 pm2 在开机时自动启动:
pm2 startup

查看 pm2 守护的服务的进程状态:
pm2 status

列出最后50行报错日志:
pm2 logs SB(这个是你设置的名字) --lines 50


tail -n 50 ~/.pm2/logs/SB-error.log

启动服务并给该服务命名为SB(该命令要在“你的文件名.js”所在目录运行):
pm2 start 你的文件名.js --name SB

卸载pm2:
sudo npm uninstall -g pm2

安装pm2:
npm install -g pm2

node,npm命令

卸载 node,npm(如果是用 apt 安装的):
sudo apt remove --purge nodejs npm -y

再次清查 node npm:

which node
which npm

如果输出还有 /usr/bin/node/usr/local/bin/node,就删掉:

sudo rm -f /usr/bin/node
sudo rm -f /usr/bin/npm
sudo rm -f /usr/local/bin/node
sudo rm -f /usr/local/bin/npm

同时清理旧全局模块:

sudo rm -rf /usr/lib/node_modules
sudo rm -rf /usr/local/lib/node_modules

按照官网文档,我使用 nvm with npm,安装了 node,则新程序会安装在当前用户下,避免权限问题

由于之前执行过 sudo,需要把网页文件全部改为当前用户:
sudo chown -R aaa:aaa /www/wwwroot/1.com/src

再把1.com/src/node_modules删除(用宝塔面板删也可以):

sudo rm -rf /www/wwwroot/1.com/src/node_modules
sudo rm -f /www/wwwroot/1.com/src/package-lock.json

重新安装依赖:
npm install

但是运行pm2 server.js 仍然报错,打开pm2日志看,错误为找不到模块。推测pm2仍然是旧的:
Cannot find module '/usr/lib/node_modules/pm2/lib/ProcessContainerFork.js'

因为我用 nvm 重新安装了 node,所以 pm2 位置应该在:
~/.nvm/versions/node/v22.18.0/lib/node_modules/pm2

则再删除 pm2:

sudo rm -f /usr/bin/pm2
sudo rm -rf /usr/lib/node_modules/pm2

重新全局安装:
npm install -g pm2

刷新 shell 的环境变量,确保 ~/.nvm/versions/node/22.18.0/bin 在 PATH 里:
export PATH="$HOME/.nvm/versions/node/v22.18.0/bin:$PATH"

更新 Shell 环境:
source ~/.bashrc

WSL 重新开机后 pm2 没启动:
由于使用的是WSL 2,WSL 默认不会像 Ubuntu 那样运行 systemd 服务
所以使用 PM2 来守护 nodejs 进程,但是 pm2 在 WSL 里设置了 pm2 startup 也不会开机自启,第一次使用该功能,以为哪里又出错

解决:
第①种方法:
打开wsl.conf:
sudo nano /etc/wsl.conf

添加:

[boot]
systemd=true

重启:
wsl --shutdown

开机后检查:
systemctl list-units --type=service | grep pm2

配置 PM2 自启:

pm2 startup systemd
pm2 save

第②种方法
在windows系统的powershell里直接打开:
wsl -d Ubuntu pm2 resurrect


文章作者: Alan Work
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alan Work !
  目录