在 Ubuntu VPS 上安装 Node.js 和 PM2

Node.js 是一个 JavaScript 运行时环境,让你能够在服务器端运行 JavaScript 代码,非常适合构建 API、Web 应用、实时应用程序和微服务。PM2 是一款生产级进程管理器,能让你的 Node.js 应用以后台守护进程方式持续运行,在程序崩溃时自动重启,并在每次服务器重启后自动启动。本指南将从一台全新的 Ubuntu VPS 开始,带你完成整个配置流程,直至应用上线并完成安全加固。

系统要求

第一步:通过 NVM 安装 Node.js

强烈推荐使用 NVM(Node 版本管理器),而不是直接运行 apt install nodejs。NVM 让你可以同时管理多个 Node.js 版本、随时切换,并且无需 sudo 即可全局安装软件包。

安装 NVM

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

重新加载 Shell 以使 nvm 命令生效:

source ~/.bashrc

验证安装是否成功:

nvm --version

安装 Node.js LTS 版本

nvm install --lts nvm use --lts nvm alias default node

确认已安装的版本:

node -v npm -v

为什么选择 LTS? LTS(长期支持)版本会在超过 30 个月内持续获得安全补丁和错误修复,是生产服务器的最佳选择。Current(最新)版本适合体验新特性,不建议用于正式环境。

第二步:创建一个测试 Node.js 应用

创建项目文件夹并搭建一个最简单的 Express 应用:

mkdir -p ~/myapp && cd ~/myapp npm init -y npm install express

创建入口文件 app.js:

cat > app.js << 'EOF' const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.json({ message: 'Hello from AsiaGB VPS!', status: 'ok' }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); EOF

在添加 PM2 之前,先直接测试一下:

node app.js

打开另一个终端窗口并运行:curl http://localhost:3000 — 你应该能看到 JSON 响应。按 Ctrl+C 停止。

第三步:安装并配置 PM2

PM2 作为生产级进程管理器运行——它让你的应用以后台服务方式持续运行,崩溃时自动重启,并在服务器重启后自动恢复。

npm install -g pm2

使用 PM2 启动应用

cd ~/myapp pm2 start app.js --name "myapp"

查看进程状态和实时日志:

pm2 status pm2 logs myapp

开机自动启动

pm2 startup # 复制 PM2 输出的命令并执行,例如: # sudo env PATH=$PATH:/home/user/.nvm/versions/node/v20.x.x/bin pm2 startup systemd -u user --hp /home/user pm2 save

常用 PM2 命令: pm2 restart myapp — 重启 · pm2 stop myapp — 停止 · pm2 delete myapp — 从 PM2 中删除 · pm2 monit — 实时 CPU/内存监控面板

第四步:配置 Nginx 反向代理

Node.js 在内部使用 3000 端口运行,但访客通过 80 端口(HTTP)或 443 端口(HTTPS)连接。Nginx 负责桥接两者——接收公网流量并转发给 Node.js。

安装 Nginx

apt update && apt install nginx -y ufw allow 'Nginx Full'

创建服务器配置块

nano /etc/nginx/sites-available/myapp

添加以下配置(将 yourdomain.com 替换为你的实际域名):

server { listen 80; server_name yourdomain.com www.yourdomain.com; location / { proxy_pass http://localhost: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_cache_bypass $http_upgrade; } }

启用网站配置并重载 Nginx:

ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx

访问 http://yourdomain.com — 你应该能看到 Node.js 应用返回的 JSON 内容。

第五步:使用 Certbot 安装 SSL(推荐)

添加 Let's Encrypt SSL,让你的应用支持 HTTPS 流量:

apt install certbot python3-certbot-nginx -y certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot 会自动更新 Nginx 配置以支持 HTTPS,并设置自动续期——无需手动操作。

通过 NodeSource 安装 Node.js(NVM 的替代方案)

如果你的 VPS 是多用户环境,或者有多个服务需要共用同一个系统级 Node.js 版本,从 NodeSource 仓库安装通常比 NVM 更简单。Node.js 二进制文件会进入全局路径,所有用户都能直接使用,并且与 systemd 原生兼容,无需额外配置 PATH。对于追求简洁的生产服务器来说,这是一个更稳定可预期的选择。

添加 Node.js 20 LTS 的 NodeSource 仓库并安装:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs node -v npm -v

如果你需要从源码编译原生模块(如 bcrypt 或 sharp),还需要安装构建工具链:

sudo apt install -y build-essential

NVM 还是 NodeSource? 如果你经常需要切换版本或在单台机器上开发,选择 NVM。如果你希望生产环境有一个统一的系统级 Node.js,方便 systemd 和 PM2 找到二进制文件,选择 NodeSource。对于典型的 AsiaGB VPS(每台服务器运行一个应用),NodeSource 通常是维护成本更低的选择。

使用 PM2 集群模式运行应用

默认情况下,Node.js 只运行在单个 CPU 核心上,造成 VPS 其他核心资源浪费。PM2 的集群模式利用 Node.js 内置的 cluster 模块,将请求分发给多个工作进程——每个核心对应一个进程,从而获得更高吞吐量和零停机重载能力。

将实例数设置为 max(等于 CPU 核心数)启动集群:

pm2 start app.js --name "myapp" -i max

或者固定工作进程数量,例如 2 个进程(适合双核 VPS):

pm2 start app.js --name "myapp" -i 2

为了避免每次都手动输入参数,可以创建一个 ecosystem.config.js 文件,将所有配置集中管理——包括环境变量、实例数量和内存限制:

cat > ecosystem.config.js << 'EOF' module.exports = { apps: [{ name: 'myapp', script: './app.js', instances: 'max', exec_mode: 'cluster', max_memory_restart: '300M', env: { NODE_ENV: 'production', PORT: 3000 } }] }; EOF

然后用一个命令启动所有进程:

pm2 start ecosystem.config.js pm2 save

max_memory_restart 选项会在工作进程超过内存阈值时自动重启,是防止内存泄漏导致应用在内存受限 VPS 上崩溃的简单保障。

集群模式注意事项: 如果你的应用将状态保存在内存中(例如内存会话),每个工作进程都有独立的副本,彼此之间不共享数据。请改用 Redis 或数据库等外部存储来管理会话。

监控、日志与零停机重载

应用上线后,关键在于监控进程健康状态,以及在不中断用户服务的情况下部署新代码。PM2 为此提供了完整的工具支持。

实时查看资源与日志

pm2 monit # 每个进程的实时 CPU/内存监控面板 pm2 logs myapp # 流式输出实时日志(stdout + stderr) pm2 logs myapp --lines 200 # 显示最近 200 行日志 pm2 show myapp # 进程详情(运行时间、重启次数、路径)

日志轮转防止磁盘空间耗尽

PM2 日志会无限增长,最终可能占满 VPS 磁盘空间。安装 pm2-logrotate 模块可以自动轮转并压缩日志:

pm2 install pm2-logrotate pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 7

上述配置将每个日志文件上限设为 10 MB,并保留最近 7 个文件。

代码更新后零停机重载

restart 命令会同时停止所有进程,造成短暂中断。在集群模式下,请改用 reload——PM2 会逐个替换工作进程,其他进程在此期间继续提供服务,用户不会感知到任何错误:

git pull npm install --production pm2 reload myapp

配合 pm2 startup 和 pm2 save,你的应用在每次 VPS 重启后都会自动恢复运行,有助于达到 AsiaGB VPS 所承诺的 99% 可用率标准。

建议: 在应用中暴露一个健康检查端点(如 /healthz),并使用外部监控工具(如 Uptime Kuma)每分钟检测一次。这样在用户反映问题之前,你就能第一时间收到告警。

常见问题解答

PM2 和 systemd 有什么区别?应该用哪个?

systemd 是 Ubuntu 的初始化系统,负责管理操作系统级别的服务;而 PM2 是专为 Node.js 设计的进程管理器,集成了集群模式、日志管理和零停机重载功能。实际使用中两者可以配合:pm2 startup 会生成一个 systemd 单元文件,在系统启动时自动拉起 PM2,再由 PM2 监管你的 Node.js 进程。

运行 Node.js + PM2 需要多少 VPS 内存?

一个小型 Express 应用在 512 MB 内存的 VPS 上可以正常运行,但如果启用了多个工作进程的集群模式或需要承载高流量,建议至少 1 GB 内存。AsiaGB Linux VPS 起步价为 500 泰铢/月,提供 Ubuntu 系统和完整 root 权限,随着应用增长可随时升级内存和 CPU。

应用用 node app.js 能跑,但通过 Nginx 访问返回 502 Bad Gateway,为什么?

通常有两个原因:PM2 实际上并没有运行该应用(用 pm2 status 检查是否显示 online),或者 Nginx 的 proxy_pass 中的端口与应用监听的端口不一致。确认两边都是 3000,然后运行 nginx -t 和 systemctl reload nginx。

部署了新代码,但 PM2 仍在运行旧版本,怎么办?

PM2 不会在 git pull 之后自动重载文件。请运行 pm2 reload myapp(集群模式)或 pm2 restart myapp 来加载新代码。如果修改了 ecosystem.config.js 中的配置,请使用 pm2 reload ecosystem.config.js --update-env,确保新的环境变量生效。

总结

需要一台运行 Node.js 的 VPS?

AsiaGB Linux VPS 起步价 500 泰铢/月 · 完整 Root 权限 · SSD 存储 · 不限流量 · 自由选择 Ubuntu 版本

查看 VPS 方案

查看泰国VPS主机全部套餐 →