15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用
08.10.2024

如何在 Ubuntu 上安装 NVM for Node.js:完整技术指南

NVM (Node Version Manager) 是一个符合 POSIX 标准的 shell 脚本,可在单台机器上安装和管理多个独立的 Node.js 运行环境,无需 root 权限或修改系统级路径。每个 Node.js 版本都存放在 `~/.nvm/versions/node/` 下的独立目录中,为各项目提供完全无冲突的隔离环境。

本指南介绍如何在 Ubuntu(20.04、22.04 和 24.04)上进行生产级 NVM 安装,不仅涵盖基本命令,还包括 shell 配置文件的边缘情况、`.nvmrc` 工作流自动化、全局包迁移以及大多数教程所忽略的服务器特定问题。

为何选择 NVM 而非系统包管理器

通过 `apt` 安装 Node.js 会在 `/usr/bin/node` 放置一个系统级的单一二进制文件。升级它会同时影响主机上的每个应用程序。在共享开发机器或运行多个 Node.js 项目的 VPS 上,这会造成脆弱且难以复现的环境。

NVM 通过将每个 Node.js 版本安装到用户空间目录并在 shell 级别操控 `PATH` 来解决这一问题。其结果是实现按用户、按项目的版本控制,对操作系统的包状态零影响。

NVM 与其他 Node.js 版本管理器的对比

功能NVMfnmVoltan
语言Shell (Bash/Zsh)RustRustShell
速度中等非常快非常快
`.nvmrc` 支持部分支持
按项目锁定版本
Windows 支持否(仅 WSL)
全局包隔离
Shell 启动开销~70ms~5ms~5ms极小
成熟度 / 生态系统最高中等

NVM 仍然是文档最完善、生态系统支持最广泛的选项,对于可复现性比原始启动速度更重要的团队和服务器环境而言,是最安全的默认选择。

前提条件

  • Ubuntu 20.04、22.04 或 24.04(桌面版或服务器版)
  • 具有 `sudo` 权限的非 root 用户账户
  • 已安装 `curl` 或 `wget`(大多数 Ubuntu 镜像默认已包含)
  • 具备 Bash 或 Zsh 的基本使用知识

在开始之前,确认您的 shell 和 Ubuntu 版本:

“`bash

echo $SHELL

lsb_release -a

“`

步骤 1:更新系统包索引

刷新 APT 包列表,确保本次会话中解析的所有依赖项均为最新版本:

“`bash

sudo apt-get update && sudo apt-get upgrade -y

“`

同时确认 `curl` 可用:

“`bash

curl –version || sudo apt-get install -y curl

“`

步骤 2:下载并运行 NVM 安装脚本

官方 NVM 安装程序托管在 GitHub 上。它会将 NVM 仓库克隆到 `~/.nvm`,并将必要的 shell 初始化块追加到您的配置文件中。

选项 A — 使用 curl(推荐):

“`bash

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

“`

选项 B — 使用 wget:

“`bash

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

“`

运行前请务必在 NVM GitHub 发布页面上核实最新的发布标签。如果已发布更新的稳定版本,请将 `v0.40.1` 替换为当前稳定标签。

安装程序实际执行的操作:

  1. 将 NVM 仓库克隆到 `~/.nvm`
  2. 检测您当前使用的 shell(`bash`、`zsh`、`ksh` 或 `fish`)
  3. 将以下初始化块追加到相应的配置文件中(`~/.bashrc`、`~/.zshrc`、`~/.profile` 或 `~/.bash_profile`)

“`bash

export NVM_DIR="$HOME/.nvm"

[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"

“`

安全提示:将远程脚本直接通过管道传输到 `bash` 是一种常见做法,但存在固有风险。对于生产服务器或独立服务器环境,建议先下载脚本,检查内容后再执行:

“`bash

curl -o install_nvm.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh

cat install_nvm.sh # review before running

bash install_nvm.sh

“`

步骤 3:在当前 Shell 会话中激活 NVM

安装程序会修改您的配置文件,但这些更改仅在新的 shell 会话中生效。若要立即激活 NVM 而无需打开新终端:

对于 Bash:

“`bash

source ~/.bashrc

“`

对于 Zsh:

“`bash

source ~/.zshrc

“`

手动加载(适用于任何 shell):

“`bash

export NVM_DIR="$HOME/.nvm"

[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

“`

常见问题:非交互式 Shell 中配置文件未被加载

在 Ubuntu 上,`~/.bashrc` 仅在交互式非登录 shell 中被加载。如果您通过 SSH 连接(登录 shell),Bash 会读取 `~/.bash_profile` 或 `~/.profile`。如果 SSH 登录后找不到 NVM,请将加载块添加到 `~/.bash_profile`:

“`bash

echo 'source ~/.bashrc' >> ~/.bash_profile

source ~/.bash_profile

“`

这是在远程服务器上配置 NVM 时最常遇到的问题之一。

步骤 4:验证 NVM 安装

“`bash

nvm –version

“`

预期输出(版本号可能有所不同):

“`

0.40.1

“`

如果命令返回 `nvm: command not found`,说明 shell 配置文件未正确加载。重新执行步骤 3 中的加载命令,并验证初始化块是否存在于您的配置文件中:

“`bash

grep -n 'NVM_DIR' ~/.bashrc

“`

步骤 5:使用 NVM 安装 Node.js

安装最新 LTS 版本(生产环境推荐)

“`bash

nvm install –lts

“`

`–lts` 标志用于安装最新的长期支持版本,该版本可获得 30 个月的安全补丁。对于在带 cPanel 的 VPS 或任何服务器环境上运行的生产工作负载,强烈建议使用 LTS 版本而非当前版本。

安装最新版本

“`bash

nvm install node

“`

安装特定版本

“`bash

nvm install 20.14.0

“`

列出所有可用的远程版本

“`bash

nvm ls-remote

“`

仅筛选 LTS 版本:

“`bash

nvm ls-remote –lts

“`

步骤 6:验证当前 Node.js 和 npm 版本

“`bash

node -v

npm -v

“`

同时确认二进制文件路径,以确保您没有意外使用系统级 Node.js 安装:

“`bash

which node

Expected: /home/<username>/.nvm/versions/node/v20.14.0/bin/node

“`

步骤 7:管理多个 Node.js 版本

列出所有本地已安装的版本

“`bash

nvm ls

“`

示例输出:

“`

-> v20.14.0

v18.20.3

v16.20.2

default -> lts/* (-> v20.14.0)

node -> stable (-> v20.14.0) (default)

lts/* -> lts/iron (-> v20.14.0)

“`

在版本之间切换

“`bash

nvm use 18.20.3

“`

此更改仅适用于当前终端会话。打开新终端将恢复为默认别名。

查看当前激活的版本

“`bash

nvm current

“`

步骤 8:设置持久默认 Node.js 版本

将特定版本设为所有新 shell 会话的默认版本:

“`bash

nvm alias default 20.14.0

“`

您也可以将别名设置为发布系列而非特定补丁版本,这样可以自动跟踪该系列内的更新:

“`bash

nvm alias default lts/*

“`

步骤 9:使用 `.nvmrc` 自动化版本切换

这是 NVM 最强大却最少被使用的功能之一。在项目根目录中放置一个包含所需 Node.js 版本的 `.nvmrc` 文件:

“`bash

echo "20.14.0" > /path/to/your/project/.nvmrc

“`

然后,当您 `cd` 进入该目录时:

“`bash

nvm use

Found '/path/to/your/project/.nvmrc' with version <20.14.0>

Now using node v20.14.0

“`

目录切换时自动切换版本

将以下内容添加到您的 `~/.bashrc`(或 `~/.zshrc`)中,以便在进入包含 `.nvmrc` 文件的目录时自动触发 `nvm use`:

对于 Bash:

“`bash

cdnvm() {

command cd "$@" || return $?

nvm_path="$(nvm_find_up .nvmrc | command tr -d 'n')"

if [[ ! $nvm_path = *[^[:space:]]* ]]; then

declare default_version

default_version="$(nvm version default)"

if [[ $default_version == "N/A" ]]; then

nvm use default

elif [[ $(nvm current) != "$default_version" ]]; then

nvm use default

fi

elif [[ -r "$nvm_path/.nvmrc" && -r "$nvm_path" ]]; then

declare nvm_version

nvm_version=$(<"$nvm_path/.nvmrc")

declare locally_resolved_nvm_version

locally_resolved_nvm_version="$(nvm ls –no-colors "$nvm_version" | command tail -1 | command tr -d '->*' | command tr -d '[:space:]')"

if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then

nvm install "$nvm_version"

elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then

nvm use "$nvm_version"

fi

fi

}

alias cd='cdnvm'

“`

这种模式在 CI/CD 流水线和团队环境中尤为有价值,特别是当多名开发者在具有不同运行时要求的项目上协作时。

步骤 10:跨版本管理全局 npm 包

NVM 安装的每个 Node.js 版本都有其独立的 `node_modules` 目录用于全局安装的包。这意味着在 `v18` 下全局安装的 `pm2`、`yarn` 或 `typescript` 等工具在 `v20` 下不可用。

为当前版本安装全局包

“`bash

npm install -g yarn

npm install -g pm2

npm install -g typescript

“`

安装新版本时迁移全局包

NVM 提供了一个内置标志,可将所有全局包从一个版本复制到新安装的版本:

“`bash

nvm install 20.14.0 –reinstall-packages-from=18.20.3

“`

在升级由 PM2 或类似工具管理持久进程的服务器上的 Node.js 版本时,这一点至关重要。

列出当前版本的全局已安装包

“`bash

npm list -g –depth=0

“`

步骤 11:卸载某个 Node.js 版本

卸载前,请先切换到其他版本:

“`bash

nvm use 20.14.0

nvm uninstall 16.20.2

“`

您无法卸载当前激活的版本,尝试这样做将返回错误。

进阶:在非交互式环境中使用 NVM(CI/CD、Cron、Systemd)

NVM 依赖于 shell 初始化文件,而这些文件在非交互式 shell 中不会被加载。这会导致在 cron 任务、systemd 单元文件以及某些 CI 环境中出现 `node: command not found` 错误。

解决方案 1:使用完整的二进制文件路径

“`bash

/home/username/.nvm/versions/node/v20.14.0/bin/node /path/to/app.js

“`

解决方案 2:在脚本中显式加载 NVM

“`bash

#!/bin/bash

export NVM_DIR="$HOME/.nvm"

[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

nvm use 20.14.0

node /path/to/app.js

“`

解决方案 3:创建符号链接以实现系统级访问(谨慎使用)

“`bash

sudo ln -s /home/username/.nvm/versions/node/v20.14.0/bin/node /usr/local/bin/node

“`

这种方法会牺牲按用户隔离,但有时对于以专用服务用户身份运行的 systemd 服务是必要的。

NVM 在共享主机、VPS 与独立服务器上的对比

环境NVM 适用性备注
共享主机不支持无 shell 访问权限;使用平台提供的 Node.js
[VPS 主机](https://alexhost.com/zh/vps/)极佳完整 shell 访问权限;按用户隔离完美运行
[独立服务器](https://alexhost.com/zh/dedicated-servers/)极佳适用于多项目环境和 CI 运行器
Docker 容器部分支持建议改用官方 Node.js Docker 镜像
共享虚拟主机不支持大多数配置下无 SSH 访问权限

对于在其他服务旁边运行 Node.js 应用程序的团队,VPS 可为您提供 NVM 所需的 shell 级控制,同时无需承担管理物理硬件的开销。

实用要点清单

将其作为部署和配置参考:

  • 安装前确认 shell 类型(`echo $SHELL`)—— Zsh 和 Bash 需要不同的配置文件
  • 生产环境 Node.js 安装始终使用 `–lts`;将 `node`(最新版)保留用于实验性工作
  • 将 `.nvmrc` 提交到版本控制,以便每位团队成员和 CI 运行器使用完全相同的运行时版本
  • 升级 Node.js 版本时使用 `–reinstall-packages-from`,避免手动重新安装全局工具
  • 在任何非交互式脚本中显式加载 NVM(cron、systemd、CI 流水线)—— 切勿假设 shell 配置文件已被加载
  • 切换版本后使用 `npm list -g –depth=0` 审查每个版本的全局包,以便尽早发现缺失的依赖项
  • 在 `.nvmrc` 中锁定精确版本(例如 `20.14.0`)而非使用别名(例如 `lts`),以在生产环境中实现最大可复现性
  • 切换版本后检查 `which node`,确认您没有意外使用系统安装的二进制文件

常见问题解答

NVM 安装 Node.js 是否需要 sudo 或 root 权限?

不需要。NVM 将所有内容安装在当前用户主目录下的 `~/.nvm` 中。安装或切换 Node.js 版本无需 root 权限。这是其相对于系统级包管理器的主要优势之一。

安装后为何出现 `nvm: command not found`?

NVM 初始化块已添加到您的 shell 配置文件中,但当前会话尚未重新加载该配置文件。请运行 `source ~/.bashrc`(Bash)或 `source ~/.zshrc`(Zsh)。如果打开新终端后错误仍然存在,请使用 `grep NVM_DIR ~/.bashrc` 检查初始化块是否确实已写入正确的文件。

同一服务器上的多个用户能否各自通过 NVM 使用不同的 Node.js 版本?

可以。由于 NVM 安装在每个用户的主目录中(`~/.nvm`),每个用户都维护一套完全独立的 Node.js 版本和全局包。这是多租户服务器的正确架构。

使用 NVM 切换 Node.js 版本后,全局安装的 npm 包会怎样?

每个 Node.js 版本都有其独立的全局包目录。在一个版本下全局安装的包对其他版本不可见。使用 `nvm install <new-version> –reinstall-packages-from=<old-version>` 可自动迁移这些包。

NVM 是否适合在服务器上的生产环境中运行 Node.js 应用程序?

NVM 非常适合管理所使用的 Node.js 版本,但在生产环境中进行进程管理时,您应将其与 PM2 等进程管理器配合使用,或使用 systemd 单元文件。请确保这些非交互式环境显式加载 NVM 或引用完整的二进制文件路径,如上文 CI/CD 部分所述。

15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用