1. 简介

当应用依赖非标准环境时,我们可能需要构建自定义的 Node.js 镜像,而不是使用官方镜像。幸运的是,我们可以借助 Dockerfile 来实现这一点。

本文将介绍几种在 Dockerfile 中安装 Node.js 的方式,包括使用版本管理工具 fnm、预编译二进制文件、包管理器和从源码安装。每种方式都有其适用场景,帮助你根据项目需求灵活选择。

2. 使用 fnm 安装 Node.js

fnm(Fast Node Manager) 是一个用于安装和管理 Node.js 版本的工具。相比传统的 nvm,fnm 更快,且支持多平台。

我们以 ubuntu:24.04 作为基础镜像开始:

FROM ubuntu:24.04

定义一个构建参数 version,用于指定 Node.js 版本:

ARG version=20

安装必要的依赖(curl、unzip),然后通过脚本安装 fnm,并将其复制到系统路径中,最后使用 fnm 安装指定版本的 Node.js:

RUN apt update -y && apt install curl unzip -y \
&& curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir './fnm' \
&& cp ./fnm/fnm /usr/bin && fnm install $version

为了保持容器运行,我们使用 tail -f /dev/null 作为入口命令:

ENTRYPOINT tail -f /dev/null

完整 Dockerfile 如下:

FROM ubuntu:24.04
ARG version=20
RUN apt update -y && apt install curl unzip -y \
&& curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir './fnm' \
&& cp ./fnm/fnm /usr/bin && fnm install $version
ENTRYPOINT tail -f /dev/null

构建并进入容器验证安装:

$ docker exec -it $(docker run --rm -d $(docker build -q .)) bash
# node -v
v20.15.0

✅ 优点:灵活控制版本,安装速度快
❌ 缺点:需要额外安装 fnm 工具

3. 从预编译二进制文件安装

这是最直接的方式之一,适用于需要精确控制 Node.js 版本的场景。

我们依然使用 ubuntu:24.04 作为基础镜像,并定义一个构建参数 version

FROM ubuntu:24.04
ARG version=v20.15.0

安装 curl 并下载对应版本的压缩包:

RUN apt update -y && apt install curl -y \
&& curl -fsSL https://nodejs.org/dist/$version/node-$version-linux-x64.tar.gz -o node.tar.gz

解压并配置环境变量:

&& tar -xzvf node.tar.gz && rm node.tar.gz \
&& echo "export PATH=$PATH:/node-$version-linux-x64/bin" >> /root/.bashrc

保持容器运行:

ENTRYPOINT sleep infinity

完整 Dockerfile 如下:

FROM ubuntu:24.04
ARG version=v20.15.0

RUN apt update -y && apt install curl -y \
&& curl -fsSL https://nodejs.org/dist/$version/node-$version-linux-x64.tar.gz -o node.tar.gz \
&& tar -xzvf node.tar.gz && rm node.tar.gz \
&& echo "export PATH=$PATH:/node-$version-linux-x64/bin" >> /root/.bashrc
ENTRYPOINT sleep infinity

验证安装:

$ docker exec -it $(docker run --rm -d $(docker build -q .)) bash
# node -v
v20.15.0

✅ 优点:速度快,版本可控
❌ 缺点:需手动配置环境变量,路径可能需要调整

4. 使用包管理器安装

如果你使用的是基于 Debian、Ubuntu、Alpine 或 Fedora 的镜像,可以直接使用系统自带的包管理器安装 Node.js。

Debian/Ubuntu 示例:

FROM ubuntu:24.04
RUN apt update -y && apt install nodejs -y
ENTRYPOINT node -v

验证:

$ docker run --rm $(docker build -q .)
v18.19.1

Fedora 示例:

FROM fedora
RUN dnf install nodejs -y
ENTRYPOINT node -v

验证:

$ docker run --rm $(docker build -q .)
v20.12.2

Alpine 示例:

FROM alpine
RUN apk add nodejs npm
ENTRYPOINT node -v

验证:

$ docker run --rm $(docker build -q .)
v20.13.1

⚠️ 注意:这种方式安装的版本由系统仓库决定,无法精确控制 Node.js 版本

✅ 优点:简单快捷
❌ 缺点:版本不可控,可能落后于官方最新版本

5. 从源码安装

源码安装适用于需要定制化构建 Node.js 的场景,比如需要特定的编译参数或使用非常规版本。

使用 ubuntu:24.04 作为基础镜像,定义构建参数:

FROM ubuntu:24.04
ARG version=v22.3.0

安装构建所需依赖:

RUN apt update -y && apt install curl make g++ python3 python3-pip -y

下载并解压源码:

RUN curl -fsSL https://nodejs.org/dist/$version/node-$version.tar.gz -o node.tar.gz \
&& tar -xzvf node.tar.gz && rm node.tar.gz

切换工作目录并进行编译安装:

WORKDIR node-$version
RUN ./configure && make && make install node
ENTRYPOINT node -v

完整 Dockerfile 如下:

FROM ubuntu:24.04
ARG version=v20.15.0
RUN apt update -y && apt install curl make g++ python3 python3-pip -y \
&& curl -fsSL https://nodejs.org/dist/$version/node-$version.tar.gz -o node.tar.gz \
&& tar -xzvf node.tar.gz && rm node.tar.gz
WORKDIR node-$version
RUN ./configure && make && make install node
ENTRYPOINT node -v

验证安装:

$ docker run --rm $(docker build -q .)
v22.3.0

✅ 优点:完全自定义构建
❌ 缺点:编译耗时长,资源消耗大

6. 总结

安装方式 优点 缺点
fnm 快速、版本可控 需额外安装 fnm 工具
预编译二进制 安装快、版本明确 需手动配置 PATH
包管理器 简单、快捷 版本受限于系统仓库
源码安装 完全自定义、任意版本可选 编译慢、资源消耗高
  • 如果你追求快速部署,推荐使用 fnm预编译二进制
  • 如果你对版本要求不高,可以使用 包管理器
  • 如果你需要定制构建,使用 源码安装 是唯一选择

选择合适的安装方式,能显著提升构建效率并减少维护成本。


原始标题:How to Install Node.js in a Dockerfile